[GTK] Implement support for Pointer Lock API
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Nov 2019 08:06:32 +0000 (08:06 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Nov 2019 08:06:32 +0000 (08:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202956

Reviewed by Carlos Alberto Lopez Perez.

.:

Enable Pointer Lock for GTK port.

* Source/cmake/OptionsGTK.cmake:

Source/WebKit:

Add platform specific implementation of Pointer Lock for the GTK port.

* PlatformGTK.cmake: Generate code for pointer-constraints and relative-pointer Wayland protocols.
* Shared/NativeWebMouseEvent.h: Add optional mouse movement delta.
* Shared/gtk/NativeWebMouseEventGtk.cpp:
(WebKit::NativeWebMouseEvent::NativeWebMouseEvent): Pass movement delta to WebEventFactory::createWebMouseEvent().
* Shared/gtk/WebEventFactory.cpp:
(WebKit::WebEventFactory::createWebMouseEvent): Initialize deltaX and deltaY for motion events using the received delta.
* Shared/gtk/WebEventFactory.h: Add optional mouse movement delta.
* SourcesGTK.txt: Add new files to compilation.
* UIProcess/API/glib/WebKitUIClient.cpp: Add implementation for requestPointerLock and didLosePointerLock.
* UIProcess/API/glib/WebKitWebView.cpp:
(webkitWebViewRequestPointerLock): Call webkitWebViewBaseRequestPointerLock().
(webkitWebViewDidLosePointerLock): Call webkitWebViewBaseDidLosePointerLock().
* UIProcess/API/glib/WebKitWebViewPrivate.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseDispose): Unlock the pointer and release the PointerLockManager.
(webkitWebViewBaseHandleMouseEvent): Initialize the mouse movement delta for motion events and save the current event.
(webkitWebViewBaseMotionNotifyEvent): Let PointerLockManager handle motion events while pointer is locked.
(webkitWebViewBaseRequestPointerLock): Create a PointerLockManager and request it to lock the pointer.
(webkitWebViewBaseDidLosePointerLock): Request PointerLockManager to unlock the pointer.
* UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
* UIProcess/gtk/PointerLockManager.cpp: Added.
(WebKit::PointerLockManager::create):
(WebKit::PointerLockManager::PointerLockManager):
(WebKit::PointerLockManager::~PointerLockManager):
(WebKit::PointerLockManager::lock):
(WebKit::PointerLockManager::unlock):
(WebKit::PointerLockManager::handleMotion):
* UIProcess/gtk/PointerLockManager.h: Added.
(WebKit::PointerLockManager::didReceiveMotionEvent):
* UIProcess/gtk/PointerLockManagerWayland.cpp: Added.
(WebKit::PointerLockManagerWayland::PointerLockManagerWayland):
(WebKit::PointerLockManagerWayland::~PointerLockManagerWayland):
(WebKit::PointerLockManagerWayland::lock):
(WebKit::PointerLockManagerWayland::unlock):
* UIProcess/gtk/PointerLockManagerWayland.h: Added.
* UIProcess/gtk/PointerLockManagerX11.cpp: Added.
(WebKit::PointerLockManagerX11::PointerLockManagerX11):
(WebKit::PointerLockManagerX11::didReceiveMotionEvent):
* UIProcess/gtk/PointerLockManagerX11.h: Added.

Tools:

* WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
(WTR::getGDKKeySymForKeyRef): Handle escape key.

LayoutTests:

Unskip Pointer Lock tests and update expectations for tests still failing.

* platform/gtk/TestExpectations:
* platform/gtk/pointer-lock/mouse-event-delivery-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/gtk/pointer-lock/mouse-event-delivery-expected.txt [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/PlatformGTK.cmake
Source/WebKit/Shared/NativeWebMouseEvent.h
Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
Source/WebKit/Shared/gtk/WebEventFactory.cpp
Source/WebKit/Shared/gtk/WebEventFactory.h
Source/WebKit/SourcesGTK.txt
Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
Source/WebKit/UIProcess/gtk/PointerLockManager.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/gtk/PointerLockManager.h [new file with mode: 0644]
Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.h [new file with mode: 0644]
Source/WebKit/UIProcess/gtk/PointerLockManagerX11.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/gtk/PointerLockManagerX11.h [new file with mode: 0644]
Source/cmake/OptionsGTK.cmake
Tools/ChangeLog
Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp

index cbc3ff8..5c0fa57 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2019-11-06  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Implement support for Pointer Lock API
+        https://bugs.webkit.org/show_bug.cgi?id=202956
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        Enable Pointer Lock for GTK port.
+
+        * Source/cmake/OptionsGTK.cmake:
+
 2019-11-05  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [Win][CMake] Build WebCore as an OBJECT library for WinCairo port
index 94898a9..ee2a8b1 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-06  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Implement support for Pointer Lock API
+        https://bugs.webkit.org/show_bug.cgi?id=202956
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        Unskip Pointer Lock tests and update expectations for tests still failing.
+
+        * platform/gtk/TestExpectations:
+        * platform/gtk/pointer-lock/mouse-event-delivery-expected.txt: Added.
+
 2019-11-05  Kate Cheney  <katherine_cheney@apple.com>
 
         Layout test website-data-removal-for-site-navigated-to-with-link-decoration.html is a flaky failure
index 2fb1537..c65e357 100644 (file)
@@ -530,14 +530,6 @@ Bug(GTK) fast/text/font-weights-zh.html [ WontFix ]
 Bug(GTK) compositing/visible-rect [ Skip ]
 Bug(GTK) legacy-animation-engine/compositing/visible-rect [ Skip ]
 
-# Pointer Lock is not implemented.
-webkit.org/b/99036 pointer-lock [ Skip ]
-# As well as testing fullscreen functionality, these tests also utilize the pointer lock feature.
-webkit.org/b/99036 http/tests/fullscreen [ Skip ]
-webkit.org/b/99036 http/tests/pointer-lock [ Skip ]
-webkit.org/b/99036 fast/shadow-dom/pointerlockelement-in-shadow-tree.html [ Skip ]
-webkit.org/b/99036 fast/shadow-dom/pointerlockelement-in-slot.html [ Skip ]
-
 # IETC flexbox failures
 webkit.org/b/85211 ietestcenter/css3/flexbox/flexbox-align-stretch-001.htm [ ImageOnlyFailure ]
 webkit.org/b/85212 ietestcenter/css3/flexbox/flexbox-layout-002.htm [ ImageOnlyFailure ]
@@ -2532,6 +2524,9 @@ webkit.org/b/202245 http/tests/workers/service/Client-properties-subframe.html [
 webkit.org/b/202245 http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html [ Timeout ]
 webkit.org/b/202245 http/tests/workers/service/registration-clear-redundant-worker.html [ Timeout ]
 
+webkit.org/b/99036 pointer-lock/pointerlockchange-event-on-lock-lost.html [ Timeout ]
+webkit.org/b/99036 pointer-lock/pointerlockelement-null-when-pending.html [ Timeout ]
+
 #////////////////////////////////////////////////////////////////////////////////////////
 # End of Tests timing out
 #////////////////////////////////////////////////////////////////////////////////////////
@@ -3877,6 +3872,9 @@ webkit.org/b/203677 imported/w3c/web-platform-tests/svg/import/painting-fill-05-
 webkit.org/b/203677 imported/w3c/web-platform-tests/svg/import/painting-stroke-08-t-manual.svg [ Failure ]
 webkit.org/b/203677 svg/W3C-SVG-1.1/painting-fill-05-b.svg [ Failure ]
 
+webkit.org/b/99036 pointer-lock/locked-element-iframe-removed-from-dom.html [ Failure ]
+webkit.org/b/99036 pointer-lock/pointerlockchange-pointerlockerror-events.html [ Failure ]
+
 #////////////////////////////////////////////////////////////////////////////////////////
 # End of non-crashing, non-flaky tests failing
 #////////////////////////////////////////////////////////////////////////////////////////
diff --git a/LayoutTests/platform/gtk/pointer-lock/mouse-event-delivery-expected.txt b/LayoutTests/platform/gtk/pointer-lock/mouse-event-delivery-expected.txt
new file mode 100644 (file)
index 0000000..bc5cac1
--- /dev/null
@@ -0,0 +1,43 @@
+Test mouse events are routed to lock target.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.onpointerlockchange event received.
+PASS document.pointerLockElement is targetdiv1
+     With a lock in place send a wheel event.
+PASS event type: wheel, target: target1, received on: target1
+PASS event type: wheel, target: target1, received on: body
+     With a lock in place move the mouse.
+PASS event type: mousemove, movementX: 25, movementY: 30, target: target1, received on: target1
+PASS event type: mousemove, movementX: 25, movementY: 30, target: target1, received on: body
+     With a lock in place send a click.
+PASS event type: mousedown, target: target1, received on: target1
+PASS event type: mousedown, target: target1, received on: body
+PASS document.onpointerlockchange event received.
+PASS document.pointerLockElement is targetdiv2
+     With a lock in place send a wheel event.
+PASS event type: wheel, target: target2, received on: target2
+PASS event type: wheel, target: target2, received on: body
+     With a lock in place send a click.
+PASS event type: mousedown, target: target2, received on: target2
+PASS event type: mousedown, target: target2, received on: body
+     Ensure double clicks work as expected, sending 4 clicks.
+     Creating a click and dblclick.
+PASS event type: mousedown, target: target2, received on: target2
+PASS event type: mouseup, target: target2, received on: target2
+PASS event type: click, target: target2, received on: target2
+PASS event type: mousedown, target: target2, received on: target2
+PASS event type: mouseup, target: target2, received on: target2
+PASS event type: click, target: target2, received on: target2
+     Ensuring no false dblclicks if we continue.
+PASS event type: mousedown, target: target2, received on: target2
+PASS event type: mouseup, target: target2, received on: target2
+PASS event type: click, target: target2, received on: target2
+PASS event type: mousedown, target: target2, received on: target2
+PASS event type: mouseup, target: target2, received on: target2
+PASS event type: click, target: target2, received on: target2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index f4c3c8a..23ae4da 100644 (file)
@@ -1,3 +1,52 @@
+2019-11-06  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Implement support for Pointer Lock API
+        https://bugs.webkit.org/show_bug.cgi?id=202956
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        Add platform specific implementation of Pointer Lock for the GTK port.
+
+        * PlatformGTK.cmake: Generate code for pointer-constraints and relative-pointer Wayland protocols.
+        * Shared/NativeWebMouseEvent.h: Add optional mouse movement delta.
+        * Shared/gtk/NativeWebMouseEventGtk.cpp:
+        (WebKit::NativeWebMouseEvent::NativeWebMouseEvent): Pass movement delta to WebEventFactory::createWebMouseEvent().
+        * Shared/gtk/WebEventFactory.cpp:
+        (WebKit::WebEventFactory::createWebMouseEvent): Initialize deltaX and deltaY for motion events using the received delta.
+        * Shared/gtk/WebEventFactory.h: Add optional mouse movement delta.
+        * SourcesGTK.txt: Add new files to compilation.
+        * UIProcess/API/glib/WebKitUIClient.cpp: Add implementation for requestPointerLock and didLosePointerLock.
+        * UIProcess/API/glib/WebKitWebView.cpp:
+        (webkitWebViewRequestPointerLock): Call webkitWebViewBaseRequestPointerLock().
+        (webkitWebViewDidLosePointerLock): Call webkitWebViewBaseDidLosePointerLock().
+        * UIProcess/API/glib/WebKitWebViewPrivate.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseDispose): Unlock the pointer and release the PointerLockManager.
+        (webkitWebViewBaseHandleMouseEvent): Initialize the mouse movement delta for motion events and save the current event.
+        (webkitWebViewBaseMotionNotifyEvent): Let PointerLockManager handle motion events while pointer is locked.
+        (webkitWebViewBaseRequestPointerLock): Create a PointerLockManager and request it to lock the pointer.
+        (webkitWebViewBaseDidLosePointerLock): Request PointerLockManager to unlock the pointer.
+        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+        * UIProcess/gtk/PointerLockManager.cpp: Added.
+        (WebKit::PointerLockManager::create):
+        (WebKit::PointerLockManager::PointerLockManager):
+        (WebKit::PointerLockManager::~PointerLockManager):
+        (WebKit::PointerLockManager::lock):
+        (WebKit::PointerLockManager::unlock):
+        (WebKit::PointerLockManager::handleMotion):
+        * UIProcess/gtk/PointerLockManager.h: Added.
+        (WebKit::PointerLockManager::didReceiveMotionEvent):
+        * UIProcess/gtk/PointerLockManagerWayland.cpp: Added.
+        (WebKit::PointerLockManagerWayland::PointerLockManagerWayland):
+        (WebKit::PointerLockManagerWayland::~PointerLockManagerWayland):
+        (WebKit::PointerLockManagerWayland::lock):
+        (WebKit::PointerLockManagerWayland::unlock):
+        * UIProcess/gtk/PointerLockManagerWayland.h: Added.
+        * UIProcess/gtk/PointerLockManagerX11.cpp: Added.
+        (WebKit::PointerLockManagerX11::PointerLockManagerX11):
+        (WebKit::PointerLockManagerX11::didReceiveMotionEvent):
+        * UIProcess/gtk/PointerLockManagerX11.h: Added.
+
 2019-11-05  Chris Dumez  <cdumez@apple.com>
 
         [iOS] Scroll position does not get restored when doing a history navigation while the reader view is shown
index dfe1c52..aec87ae 100644 (file)
@@ -49,6 +49,8 @@ list(APPEND WebKit_DERIVED_SOURCES
 if (ENABLE_WAYLAND_TARGET)
     list(APPEND WebKit_DERIVED_SOURCES
         ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.c
+        ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/pointer-constraints-unstable-v1-protocol.c
+        ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/relative-pointer-unstable-v1-protocol.c
     )
 endif ()
 
@@ -547,9 +549,26 @@ if (ENABLE_WAYLAND_TARGET)
     add_custom_command(
         OUTPUT ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.c
         DEPENDS ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml
-        COMMAND wayland-scanner server-header < ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml > ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandServerProtocol.h
-        COMMAND wayland-scanner client-header < ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml > ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.h
-        COMMAND wayland-scanner code < ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml > ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.c
+        COMMAND ${WAYLAND_SCANNER} server-header ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandServerProtocol.h
+        COMMAND ${WAYLAND_SCANNER} client-header ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.h
+        COMMAND ${WAYLAND_SCANNER} code ${WEBKIT_DIR}/Shared/gtk/WebKitWaylandProtocol.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/WebKitWaylandClientProtocol.c
+        VERBATIM
+    )
+
+    add_custom_command(
+        OUTPUT ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/pointer-constraints-unstable-v1-protocol.c
+        DEPENDS ${WAYLAND_PROTOCOLS_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
+        COMMAND ${WAYLAND_SCANNER} code ${WAYLAND_PROTOCOLS_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/pointer-constraints-unstable-v1-protocol.c
+        COMMAND ${WAYLAND_SCANNER} client-header ${WAYLAND_PROTOCOLS_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/pointer-constraints-unstable-v1-client-protocol.h
+        VERBATIM
+    )
+
+    add_custom_command(
+        OUTPUT ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/relative-pointer-unstable-v1-protocol.c
+        DEPENDS ${WAYLAND_PROTOCOLS_DATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml
+        COMMAND ${WAYLAND_SCANNER} code ${WAYLAND_PROTOCOLS_DATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/relative-pointer-unstable-v1-protocol.c
+        COMMAND ${WAYLAND_SCANNER} client-header ${WAYLAND_PROTOCOLS_DATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml ${DERIVED_SOURCES_WEBKIT2GTK_DIR}/relative-pointer-unstable-v1-client-protocol.h
+        VERBATIM
     )
 endif ()
 
index ba7f93c..0fa557e 100644 (file)
@@ -60,7 +60,7 @@ public:
     NativeWebMouseEvent(NSEvent *, NSEvent *lastPressureEvent, NSView *);
 #elif PLATFORM(GTK)
     NativeWebMouseEvent(const NativeWebMouseEvent&);
-    NativeWebMouseEvent(GdkEvent*, int);
+    NativeWebMouseEvent(GdkEvent*, int, Optional<WebCore::IntPoint>);
 #elif PLATFORM(IOS_FAMILY)
     NativeWebMouseEvent(::WebEvent *);
     NativeWebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force);
index 28d00f0..58e37fe 100644 (file)
 
 namespace WebKit {
 
-NativeWebMouseEvent::NativeWebMouseEvent(GdkEvent* event, int eventClickCount)
-    : WebMouseEvent(WebEventFactory::createWebMouseEvent(event, eventClickCount))
+NativeWebMouseEvent::NativeWebMouseEvent(GdkEvent* event, int eventClickCount, Optional<WebCore::IntPoint> delta)
+    : WebMouseEvent(WebEventFactory::createWebMouseEvent(event, eventClickCount, delta))
     , m_nativeEvent(gdk_event_copy(event))
 {
 }
 
 NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& event)
-    : WebMouseEvent(WebEventFactory::createWebMouseEvent(event.nativeEvent(), event.clickCount()))
+    : WebMouseEvent(WebEventFactory::createWebMouseEvent(event.nativeEvent(), event.clickCount(), WebCore::IntPoint(event.deltaX(), event.deltaY())))
     , m_nativeEvent(gdk_event_copy(event.nativeEvent()))
 {
 }
index 04048ce..68ae468 100644 (file)
@@ -135,7 +135,7 @@ static inline short pressedMouseButtons(GdkModifierType state)
     return buttons;
 }
 
-WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int currentClickCount)
+WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int currentClickCount, Optional<IntPoint> delta)
 {
     double x, y, xRoot, yRoot;
     gdk_event_get_coords(event, &x, &y);
@@ -148,6 +148,7 @@ WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int cu
     gdk_event_get_button(event, &eventButton);
 
     WebEvent::Type type = static_cast<WebEvent::Type>(0);
+    IntPoint movementDelta;
 
     GdkEventType eventType = gdk_event_get_event_type(event);
     switch (eventType) {
@@ -155,6 +156,8 @@ WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int cu
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
         type = WebEvent::MouseMove;
+        if (delta)
+            movementDelta = delta.value();
         break;
     case GDK_BUTTON_PRESS:
     case GDK_2BUTTON_PRESS:
@@ -179,8 +182,8 @@ WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int cu
         pressedMouseButtons(state),
         IntPoint(x, y),
         IntPoint(xRoot, yRoot),
-        0 /* deltaX */,
-        0 /* deltaY */,
+        movementDelta.x(),
+        movementDelta.y(),
         0 /* deltaZ */,
         currentClickCount,
         modifiersForEvent(event),
index 8008ff2..596b729 100644 (file)
@@ -34,7 +34,7 @@ namespace WebKit {
 
 class WebEventFactory {
 public:
-    static WebMouseEvent createWebMouseEvent(const GdkEvent*, int);
+    static WebMouseEvent createWebMouseEvent(const GdkEvent*, int, Optional<WebCore::IntPoint>);
     static WebWheelEvent createWebWheelEvent(const GdkEvent*);
     static WebWheelEvent createWebWheelEvent(const GdkEvent*, WebWheelEvent::Phase, WebWheelEvent::Phase momentumPhase);
     static WebKeyboardEvent createWebKeyboardEvent(const GdkEvent*, const String&, bool handledByInputMethod, Vector<String>&& commands);
index c9e153d..e765066 100644 (file)
@@ -240,6 +240,9 @@ UIProcess/gtk/GestureController.cpp
 UIProcess/gtk/HardwareAccelerationManager.cpp
 UIProcess/gtk/InputMethodFilter.cpp
 UIProcess/gtk/KeyBindingTranslator.cpp
+UIProcess/gtk/PointerLockManager.cpp @no-unify
+UIProcess/gtk/PointerLockManagerWayland.cpp @no-unify
+UIProcess/gtk/PointerLockManagerX11.cpp @no-unify
 UIProcess/gtk/RemoteWebInspectorProxyGtk.cpp
 UIProcess/gtk/TextCheckerGtk.cpp @no-unify
 UIProcess/gtk/ViewGestureControllerGtk.cpp @no-unify
index cd4cfd6..b24321f 100644 (file)
@@ -250,6 +250,19 @@ private:
         webkitWebViewIsPlayingAudioChanged(m_webView);
     }
 
+#if ENABLE(POINTER_LOCK)
+    void requestPointerLock(WebPageProxy* page) final
+    {
+        webkitWebViewRequestPointerLock(m_webView);
+    }
+
+    void didLosePointerLock(WebPageProxy*) final
+    {
+        webkitWebViewDidLosePointerLock(m_webView);
+    }
+#endif
+
+
     WebKitWebView* m_webView;
 };
 
index 6ca1387..3e37613 100644 (file)
@@ -2627,6 +2627,22 @@ void webkitWebViewDidReceiveUserMessage(WebKitWebView* webView, UserMessage&& me
     g_signal_emit(webView, signals[USER_MESSAGE_RECEIVED], 0, userMessage.get(), &returnValue);
 }
 
+#if ENABLE(POINTER_LOCK)
+void webkitWebViewRequestPointerLock(WebKitWebView* webView)
+{
+#if PLATFORM(GTK)
+    webkitWebViewBaseRequestPointerLock(WEBKIT_WEB_VIEW_BASE(webView));
+#endif
+}
+
+void webkitWebViewDidLosePointerLock(WebKitWebView* webView)
+{
+#if PLATFORM(GTK)
+    webkitWebViewBaseDidLosePointerLock(WEBKIT_WEB_VIEW_BASE(webView));
+#endif
+}
+#endif
+
 #if PLATFORM(WPE)
 /**
  * webkit_web_view_get_backend:
index 3326414..13801c3 100644 (file)
@@ -103,3 +103,8 @@ gboolean webkitWebViewScriptDialog(WebKitWebView*, WebKitScriptDialog*);
 gboolean webkitWebViewRunFileChooser(WebKitWebView*, WebKitFileChooserRequest*);
 void webkitWebViewDidChangePageID(WebKitWebView*);
 void webkitWebViewDidReceiveUserMessage(WebKitWebView*, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&);
+
+#if ENABLE(POINTER_LOCK)
+void webkitWebViewRequestPointerLock(WebKitWebView*);
+void webkitWebViewDidLosePointerLock(WebKitWebView*);
+#endif
index a9d49d5..de29ac4 100644 (file)
@@ -38,6 +38,7 @@
 #include "NativeWebMouseEvent.h"
 #include "NativeWebWheelEvent.h"
 #include "PageClientImpl.h"
+#include "PointerLockManager.h"
 #include "ViewGestureController.h"
 #include "WebEventFactory.h"
 #include "WebInspectorProxy.h"
@@ -195,6 +196,7 @@ struct _WebKitWebViewBasePrivate {
     KeyBindingTranslator keyBindingTranslator;
     TouchEventsMap touchEvents;
     IntSize contentsSize;
+    GUniquePtr<GdkEvent> lastMotionEvent;
 
     GtkWindow* toplevelOnScreenWindow { nullptr };
     unsigned long toplevelFocusInEventID { 0 };
@@ -229,6 +231,8 @@ struct _WebKitWebViewBasePrivate {
     CompletionHandler<void(String)> emojiChooserCompletionHandler;
     RunLoop::Timer<WebKitWebViewBasePrivate> releaseEmojiChooserTimer;
 #endif
+
+    std::unique_ptr<PointerLockManager> pointerLockManager;
 };
 
 WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
@@ -555,6 +559,10 @@ static void webkitWebViewBaseDispose(GObject* gobject)
 #if GTK_CHECK_VERSION(3, 24, 0)
     webkitWebViewBaseCompleteEmojiChooserRequest(webView, emptyString());
 #endif
+    if (webView->priv->pointerLockManager) {
+        webView->priv->pointerLockManager->unlock();
+        webView->priv->pointerLockManager = nullptr;
+    }
     webView->priv->pageProxy->close();
     webView->priv->acceleratedBackingStore = nullptr;
     webView->priv->sleepDisabler = nullptr;
@@ -821,6 +829,7 @@ static void webkitWebViewBaseHandleMouseEvent(WebKitWebViewBase* webViewBase, Gd
     ASSERT(!priv->dialog);
 
     int clickCount = 0;
+    Optional<IntPoint> movementDelta;
     GdkEventType eventType = gdk_event_get_event_type(event);
     switch (eventType) {
     case GDK_BUTTON_PRESS:
@@ -850,6 +859,16 @@ static void webkitWebViewBaseHandleMouseEvent(WebKitWebViewBase* webViewBase, Gd
         gtk_widget_grab_focus(GTK_WIDGET(webViewBase));
         break;
     case GDK_MOTION_NOTIFY:
+        // Pointer Lock. 7.1 Attributes: movementX/Y must be updated regardless of pointer lock state.
+        if (priv->lastMotionEvent) {
+            double currentX, currentY;
+            gdk_event_get_root_coords(event, &currentX, &currentY);
+            double previousX, previousY;
+            gdk_event_get_root_coords(priv->lastMotionEvent.get(), &previousX, &previousY);
+            movementDelta = IntPoint(currentX - previousX, currentY - previousY);
+        }
+        priv->lastMotionEvent.reset(gdk_event_copy(event));
+        break;
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
         break;
@@ -857,7 +876,7 @@ static void webkitWebViewBaseHandleMouseEvent(WebKitWebViewBase* webViewBase, Gd
         ASSERT_NOT_REACHED();
     }
 
-    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, clickCount));
+    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, clickCount, movementDelta));
 }
 
 static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventButton* event)
@@ -961,6 +980,11 @@ static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMo
         return widgetClass->motion_notify_event ? widgetClass->motion_notify_event(widget, event) : GDK_EVENT_PROPAGATE;
     }
 
+    if (priv->pointerLockManager) {
+        priv->pointerLockManager->didReceiveMotionEvent(reinterpret_cast<GdkEvent*>(event));
+        return GDK_EVENT_STOP;
+    }
+
     webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
 
     return GDK_EVENT_PROPAGATE;
@@ -1837,3 +1861,42 @@ int webkitWebViewBaseRenderHostFileDescriptor(WebKitWebViewBase* webkitWebViewBa
     return webkitWebViewBase->priv->acceleratedBackingStore->renderHostFileDescriptor();
 }
 #endif
+
+void webkitWebViewBaseRequestPointerLock(WebKitWebViewBase* webViewBase)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    RELEASE_ASSERT(!priv->pointerLockManager);
+    if (!priv->lastMotionEvent) {
+        GtkWidget* viewWidget = GTK_WIDGET(webViewBase);
+        auto* device = gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(viewWidget)));
+        int x, y;
+        GdkModifierType state;
+        gdk_window_get_device_position(gtk_widget_get_window(viewWidget), device, &x, &y, &state);
+        priv->lastMotionEvent.reset(gdk_event_new(GDK_MOTION_NOTIFY));
+        priv->lastMotionEvent->motion.x = x;
+        priv->lastMotionEvent->motion.y = y;
+        int rootX, rootY;
+        gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &rootX, &rootY);
+        priv->lastMotionEvent->motion.x_root = rootX;
+        priv->lastMotionEvent->motion.y_root = rootY;
+        priv->lastMotionEvent->motion.state = state;
+    }
+    priv->pointerLockManager = PointerLockManager::create(*priv->pageProxy, priv->lastMotionEvent.get());
+    if (priv->pointerLockManager->lock()) {
+        priv->pageProxy->didAllowPointerLock();
+        return;
+    }
+
+    priv->pointerLockManager = nullptr;
+    priv->pageProxy->didDenyPointerLock();
+}
+
+void webkitWebViewBaseDidLosePointerLock(WebKitWebViewBase* webViewBase)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (!priv->pointerLockManager)
+        return;
+
+    priv->pointerLockManager->unlock();
+    priv->pointerLockManager = nullptr;
+}
index f84a3ab..8bc19b5 100644 (file)
@@ -101,3 +101,6 @@ void webkitWebViewBaseShowEmojiChooser(WebKitWebViewBase*, const WebCore::IntRec
 #if USE(WPE_RENDERER)
 int webkitWebViewBaseRenderHostFileDescriptor(WebKitWebViewBase*);
 #endif
+
+void webkitWebViewBaseRequestPointerLock(WebKitWebViewBase*);
+void webkitWebViewBaseDidLosePointerLock(WebKitWebViewBase*);
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManager.cpp b/Source/WebKit/UIProcess/gtk/PointerLockManager.cpp
new file mode 100644 (file)
index 0000000..6d23c39
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PointerLockManager.h"
+
+#include "NativeWebMouseEvent.h"
+#include "WebPageProxy.h"
+#include <WebCore/PlatformDisplay.h>
+#include <gtk/gtk.h>
+
+#if PLATFORM(WAYLAND)
+#include "PointerLockManagerWayland.h"
+#endif
+
+#if PLATFORM(X11)
+#include "PointerLockManagerX11.h"
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+std::unique_ptr<PointerLockManager> PointerLockManager::create(WebPageProxy& webPage, const GdkEvent* event)
+{
+#if PLATFORM(WAYLAND)
+    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
+        return makeUnique<PointerLockManagerWayland>(webPage, event);
+#endif
+#if PLATFORM(X11)
+    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11)
+        return makeUnique<PointerLockManagerX11>(webPage, event);
+#endif
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+PointerLockManager::PointerLockManager(WebPageProxy& webPage, const GdkEvent* event)
+    : m_webPage(webPage)
+    , m_event(event)
+{
+}
+
+PointerLockManager::~PointerLockManager()
+{
+    RELEASE_ASSERT(!m_device);
+}
+
+bool PointerLockManager::lock()
+{
+    RELEASE_ASSERT(!m_device);
+
+    auto* viewWidget = m_webPage.viewWidget();
+    m_device = gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(viewWidget)));
+    GRefPtr<GdkCursor> cursor = adoptGRef(gdk_cursor_new_from_name(gtk_widget_get_display(viewWidget), "none"));
+    auto grabResult = gdk_seat_grab(gdk_device_get_seat(m_device), gtk_widget_get_window(viewWidget), GDK_SEAT_CAPABILITY_ALL_POINTING, TRUE,
+        cursor.get(), nullptr, nullptr, nullptr);
+    if (grabResult != GDK_GRAB_SUCCESS) {
+        m_device = nullptr;
+        return false;
+    }
+
+    return true;
+}
+
+bool PointerLockManager::unlock()
+{
+    if (!m_device)
+        return false;
+
+    gdk_seat_ungrab(gdk_device_get_seat(m_device));
+    m_device = nullptr;
+    return true;
+}
+
+void PointerLockManager::handleMotion(IntPoint&& delta)
+{
+    m_webPage.handleMouseEvent(NativeWebMouseEvent(const_cast<GdkEvent*>(m_event), 0, delta));
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManager.h b/Source/WebKit/UIProcess/gtk/PointerLockManager.h
new file mode 100644 (file)
index 0000000..c70cf7e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Noncopyable.h>
+
+typedef struct _GdkDevice GdkDevice;
+typedef union _GdkEvent GdkEvent;
+
+namespace WebCore {
+class IntPoint;
+}
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class PointerLockManager {
+    WTF_MAKE_NONCOPYABLE(PointerLockManager); WTF_MAKE_FAST_ALLOCATED;
+public:
+    static std::unique_ptr<PointerLockManager> create(WebPageProxy&, const GdkEvent*);
+    PointerLockManager(WebPageProxy&, const GdkEvent*);
+    virtual ~PointerLockManager();
+
+    virtual bool lock();
+    virtual bool unlock();
+    virtual void didReceiveMotionEvent(const GdkEvent*) { };
+
+protected:
+    void handleMotion(WebCore::IntPoint&&);
+
+    WebPageProxy& m_webPage;
+    const GdkEvent* m_event;
+    GdkDevice* m_device { nullptr };
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.cpp b/Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.cpp
new file mode 100644 (file)
index 0000000..61bae57
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PointerLockManagerWayland.h"
+
+#if PLATFORM(WAYLAND)
+
+#include "WebPageProxy.h"
+#include "pointer-constraints-unstable-v1-client-protocol.h"
+#include <WebCore/WlUniquePtr.h>
+#include <gdk/gdkwayland.h>
+#include <gtk/gtk.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+PointerLockManagerWayland::PointerLockManagerWayland(WebPageProxy& webPage, const GdkEvent* event)
+    : PointerLockManager(webPage, event)
+{
+    auto* display = gdk_wayland_display_get_wl_display(gtk_widget_get_display(m_webPage.viewWidget()));
+    WlUniquePtr<struct wl_registry> registry(wl_display_get_registry(display));
+    wl_registry_add_listener(registry.get(), &s_registryListener, this);
+    wl_display_roundtrip(display);
+}
+
+PointerLockManagerWayland::~PointerLockManagerWayland()
+{
+    g_clear_pointer(&m_relativePointerManager, zwp_relative_pointer_manager_v1_destroy);
+    g_clear_pointer(&m_pointerConstraints, zwp_pointer_constraints_v1_destroy);
+}
+
+const struct wl_registry_listener PointerLockManagerWayland::s_registryListener = {
+    // global
+    [](void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t) {
+        if (!g_strcmp0(interface, "zwp_pointer_constraints_v1")) {
+            auto& manager = *reinterpret_cast<PointerLockManagerWayland*>(data);
+            manager.m_pointerConstraints = static_cast<struct zwp_pointer_constraints_v1*>(wl_registry_bind(registry, name, &zwp_pointer_constraints_v1_interface, 1));
+        } else if (!g_strcmp0(interface, "zwp_relative_pointer_manager_v1")) {
+            auto& manager = *reinterpret_cast<PointerLockManagerWayland*>(data);
+            manager.m_relativePointerManager = static_cast<struct zwp_relative_pointer_manager_v1*>(wl_registry_bind(registry, name, &zwp_relative_pointer_manager_v1_interface, 1));
+        }
+    },
+    // global_remove
+    [](void*, struct wl_registry*, uint32_t)
+    {
+    }
+};
+
+const struct zwp_relative_pointer_v1_listener PointerLockManagerWayland::s_relativePointerListener = {
+    // relative_motion
+    [](void* data, struct zwp_relative_pointer_v1*, uint32_t, uint32_t, wl_fixed_t, wl_fixed_t, wl_fixed_t deltaX, wl_fixed_t deltaY) {
+        auto& manager = *reinterpret_cast<PointerLockManagerWayland*>(data);
+        manager.handleMotion({ wl_fixed_to_int(deltaX), wl_fixed_to_int(deltaY) });
+    }
+};
+
+bool PointerLockManagerWayland::lock()
+{
+    if (!m_pointerConstraints || !m_relativePointerManager)
+        return false;
+
+    if (!PointerLockManager::lock())
+        return false;
+
+    auto* pointer = gdk_wayland_device_get_wl_pointer(m_device);
+
+    RELEASE_ASSERT(!m_relativePointer);
+    m_relativePointer = zwp_relative_pointer_manager_v1_get_relative_pointer(m_relativePointerManager, pointer);
+    zwp_relative_pointer_v1_add_listener(m_relativePointer, &s_relativePointerListener, this);
+
+    RELEASE_ASSERT(!m_lockedPointer);
+    auto* surface = gdk_wayland_window_get_wl_surface(gtk_widget_get_window(m_webPage.viewWidget()));
+    m_lockedPointer = zwp_pointer_constraints_v1_lock_pointer(m_pointerConstraints, surface, pointer, nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
+    return true;
+}
+
+bool PointerLockManagerWayland::unlock()
+{
+    g_clear_pointer(&m_relativePointer, zwp_relative_pointer_v1_destroy);
+    g_clear_pointer(&m_lockedPointer, zwp_locked_pointer_v1_destroy);
+
+    return PointerLockManager::unlock();
+}
+
+} // namespace WebKit
+
+#endif // PLATFORM(WAYLAND)
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.h b/Source/WebKit/UIProcess/gtk/PointerLockManagerWayland.h
new file mode 100644 (file)
index 0000000..ca7234e
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PointerLockManager.h"
+
+#if PLATFORM(WAYLAND)
+
+#include "relative-pointer-unstable-v1-client-protocol.h"
+#include <WebCore/WlUniquePtr.h>
+#include <wayland-client.h>
+
+struct zwp_locked_pointer_v1;
+struct zwp_pointer_constraints_v1;
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class PointerLockManagerWayland final : public PointerLockManager {
+    WTF_MAKE_NONCOPYABLE(PointerLockManagerWayland); WTF_MAKE_FAST_ALLOCATED;
+public:
+    PointerLockManagerWayland(WebPageProxy&, const GdkEvent*);
+    ~PointerLockManagerWayland();
+
+private:
+    static const struct wl_registry_listener s_registryListener;
+    static const struct zwp_relative_pointer_v1_listener s_relativePointerListener;
+
+    bool lock() override;
+    bool unlock() override;
+
+    WebCore::WlUniquePtr<struct wl_registry> m_registry;
+    struct zwp_pointer_constraints_v1* m_pointerConstraints { nullptr };
+    struct zwp_locked_pointer_v1* m_lockedPointer { nullptr };
+    struct zwp_relative_pointer_manager_v1* m_relativePointerManager { nullptr };
+    struct zwp_relative_pointer_v1* m_relativePointer { nullptr };
+};
+
+} // namespace WebKit
+
+#endif // PLATFORM(WAYLAND)
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManagerX11.cpp b/Source/WebKit/UIProcess/gtk/PointerLockManagerX11.cpp
new file mode 100644 (file)
index 0000000..03d8416
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PointerLockManagerX11.h"
+
+#if PLATFORM(X11)
+
+#include "WebPageProxy.h"
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+PointerLockManagerX11::PointerLockManagerX11(WebPageProxy& webPage, const GdkEvent* event)
+    : PointerLockManager(webPage, event)
+{
+}
+
+void PointerLockManagerX11::didReceiveMotionEvent(const GdkEvent* event)
+{
+    double currentX, currentY;
+    gdk_event_get_root_coords(event, &currentX, &currentY);
+    double initialX, initialY;
+    gdk_event_get_root_coords(m_event, &initialX, &initialY);
+    if (currentX == initialX && currentY == initialY)
+        return;
+
+    handleMotion(IntPoint(currentX - initialX, currentY - initialY));
+    gdk_device_warp(m_device, gtk_widget_get_screen(m_webPage.viewWidget()), initialX, initialY);
+}
+
+} // namespace WebKit
+
+#endif // PLATFORM(WAYLAND)
diff --git a/Source/WebKit/UIProcess/gtk/PointerLockManagerX11.h b/Source/WebKit/UIProcess/gtk/PointerLockManagerX11.h
new file mode 100644 (file)
index 0000000..1be15ff
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PointerLockManager.h"
+
+#if PLATFORM(X11)
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class PointerLockManagerX11 final : public PointerLockManager {
+    WTF_MAKE_NONCOPYABLE(PointerLockManagerX11); WTF_MAKE_FAST_ALLOCATED;
+public:
+    PointerLockManagerX11(WebPageProxy&, const GdkEvent*);
+    ~PointerLockManagerX11() = default;
+
+private:
+    void didReceiveMotionEvent(const GdkEvent*) override;
+};
+
+} // namespace WebKit
+
+#endif // PLATFORM(X11)
index 6b41305..cce10c0 100644 (file)
@@ -160,6 +160,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PUBLIC ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
@@ -343,6 +344,7 @@ if (ENABLE_WAYLAND_TARGET)
     endif ()
 
     find_package(Wayland REQUIRED)
+    find_package(WaylandProtocols 1.12 REQUIRED)
 endif ()
 
 if (USE_LIBNOTIFY)
index 3b8b0a2..e65395b 100644 (file)
@@ -1,3 +1,13 @@
+2019-11-06  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Implement support for Pointer Lock API
+        https://bugs.webkit.org/show_bug.cgi?id=202956
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        * WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
+        (WTR::getGDKKeySymForKeyRef): Handle escape key.
+
 2019-11-05  Chris Dumez  <cdumez@apple.com>
 
         [iOS] Scroll position does not get restored when doing a history navigation while the reader view is shown
index b17eca8..7e95b11 100644 (file)
@@ -270,6 +270,8 @@ int getGDKKeySymForKeyRef(WKStringRef keyRef, unsigned location, guint* modifier
         return GDK_KEY_F11;
     if (WKStringIsEqualToUTF8CString(keyRef, "F12"))
         return GDK_KEY_F12;
+    if (WKStringIsEqualToUTF8CString(keyRef, "escape"))
+        return GDK_KEY_Escape;
 
     size_t bufferSize = WKStringGetMaximumUTF8CStringSize(keyRef);
     auto buffer = makeUniqueArray<char>(bufferSize);