Add magnify and rotate gesture event support for Mac
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / mac / WKView.mm
index 68ec374..e857aaf 100644 (file)
 #import "EditorState.h"
 #import "LayerTreeContext.h"
 #import "Logging.h"
+#import "NativeWebGestureEvent.h"
 #import "NativeWebKeyboardEvent.h"
 #import "NativeWebMouseEvent.h"
 #import "NativeWebWheelEvent.h"
 #import "PageClientImpl.h"
 #import "PasteboardTypes.h"
 #import "RemoteLayerTreeDrawingAreaProxy.h"
+#import "RemoteObjectRegistry.h"
+#import "RemoteObjectRegistryMessages.h"
 #import "StringUtilities.h"
 #import "TextChecker.h"
 #import "TextCheckerState.h"
@@ -68,7 +71,7 @@
 #import "WKWebView.h"
 #import "WebBackForwardList.h"
 #import "WebEventFactory.h"
-#import "WebHitTestResult.h"
+#import "WebHitTestResultData.h"
 #import "WebInspectorProxy.h"
 #import "WebKit2Initialize.h"
 #import "WebPage.h"
@@ -78,6 +81,7 @@
 #import "WebProcessPool.h"
 #import "WebProcessProxy.h"
 #import "WebSystemInterface.h"
+#import "_WKRemoteObjectRegistryInternal.h"
 #import "_WKThumbnailViewInternal.h"
 #import <QuartzCore/QuartzCore.h>
 #import <WebCore/AXObjectCache.h>
@@ -181,6 +185,8 @@ struct WKViewInterpretKeyEventsParameters {
 #if WK_API_ENABLED
     RetainPtr<WKBrowsingContextController> _browsingContextController;
     RetainPtr<NSView> _inspectorAttachmentView;
+
+    RetainPtr<_WKRemoteObjectRegistry> _remoteObjectRegistry;
 #endif
 
     RetainPtr<NSTrackingArea> _primaryTrackingArea;
@@ -386,6 +392,13 @@ struct WKViewInterpretKeyEventsParameters {
 #endif
     [_data->_layoutStrategy willDestroyView:self];
 
+#if WK_API_ENABLED
+    if (_data->_remoteObjectRegistry) {
+        _data->_page->process().processPool().removeMessageReceiver(Messages::RemoteObjectRegistry::messageReceiverName(), _data->_page->pageID());
+        [_data->_remoteObjectRegistry _invalidate];
+    }
+#endif
+
     _data->_page->close();
 
 #if WK_API_ENABLED
@@ -3343,6 +3356,24 @@ static void* keyValueObservingContext = &keyValueObservingContext;
     return _data->_rootLayer.get();
 }
 
+static RetainPtr<CGImageRef> takeWindowSnapshot(CGSWindowID windowID, bool captureAtNominalResolution)
+{
+    CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
+    if (captureAtNominalResolution)
+        options |= kCGSWindowCaptureNominalResolution;
+    RetainPtr<CFArrayRef> windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
+
+    if (windowSnapshotImages && CFArrayGetCount(windowSnapshotImages.get()))
+        return (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
+
+    // Fall back to the non-hardware capture path if we didn't get a snapshot
+    // (which usually happens if the window is fully off-screen).
+    CGWindowImageOption imageOptions = kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque;
+    if (captureAtNominalResolution)
+        imageOptions |= kCGWindowImageNominalResolution;
+    return adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, imageOptions));
+}
+
 - (PassRefPtr<ViewSnapshot>)_takeViewSnapshot
 {
     NSWindow *window = self.window;
@@ -3351,22 +3382,17 @@ static void* keyValueObservingContext = &keyValueObservingContext;
     if (!windowID || ![window isVisible])
         return nullptr;
 
-    CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
-    RetainPtr<CFArrayRef> windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
-    if (!windowSnapshotImages || !CFArrayGetCount(windowSnapshotImages.get()))
+    RetainPtr<CGImageRef> windowSnapshotImage = takeWindowSnapshot(windowID, false);
+    if (!windowSnapshotImage)
         return nullptr;
 
-    RetainPtr<CGImageRef> windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
-
     // Work around <rdar://problem/17084993>; re-request the snapshot at kCGWindowImageNominalResolution if it was captured at the wrong scale.
     CGFloat desiredSnapshotWidth = window.frame.size.width * window.screen.backingScaleFactor;
-    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth) {
-        options |= kCGSWindowCaptureNominalResolution;
-        windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
-        if (!windowSnapshotImages || !CFArrayGetCount(windowSnapshotImages.get()))
-            return nullptr;
-        windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
-    }
+    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth)
+        windowSnapshotImage = takeWindowSnapshot(windowID, true);
+
+    if (!windowSnapshotImage)
+        return nullptr;
 
     [self _ensureGestureController];
 
@@ -3936,6 +3962,20 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
     }
 }
 
+#if WK_API_ENABLED
+- (_WKRemoteObjectRegistry *)_remoteObjectRegistry
+{
+    if (!_data->_remoteObjectRegistry) {
+        _data->_remoteObjectRegistry = adoptNS([[_WKRemoteObjectRegistry alloc] _initWithMessageSender:*_data->_page]);
+        _data->_page->process().processPool().addMessageReceiver(Messages::RemoteObjectRegistry::messageReceiverName(), _data->_page->pageID(), [_data->_remoteObjectRegistry remoteObjectRegistry]);
+    }
+
+    return _data->_remoteObjectRegistry.get();
+}
+
+#endif
+
+
 - (void)_didCommitLoadForMainFrame
 {
     [self _updateSupportsArbitraryLayoutModes];
@@ -3967,7 +4007,7 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
 
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 
-- (void)_didPerformImmediateActionHitTest:(const WebHitTestResult::Data&)hitTestResult contentPreventsDefault:(BOOL)contentPreventsDefault userData:(API::Object*)userData
+- (void)_didPerformImmediateActionHitTest:(const WebHitTestResultData&)hitTestResult contentPreventsDefault:(BOOL)contentPreventsDefault userData:(API::Object*)userData
 {
     [_data->_immediateActionController didPerformImmediateActionHitTest:hitTestResult contentPreventsDefault:contentPreventsDefault userData:userData];
 }
@@ -4539,6 +4579,10 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
 - (void)magnifyWithEvent:(NSEvent *)event
 {
     if (!_data->_allowsMagnification) {
+#if ENABLE(MAC_GESTURE_EVENTS)
+        NativeWebGestureEvent webEvent = NativeWebGestureEvent(event, self);
+        _data->_page->handleGestureEvent(webEvent);
+#endif
         [super magnifyWithEvent:event];
         return;
     }
@@ -4547,10 +4591,33 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
 
     [self _ensureGestureController];
 
-    _data->_gestureController->handleMagnificationGesture(event.magnification, [self convertPoint:event.locationInWindow fromView:nil]);
+#if ENABLE(MAC_GESTURE_EVENTS)
+    if (_data->_gestureController->hasActiveMagnificationGesture()) {
+        _data->_gestureController->handleMagnificationGestureEvent(event, [self convertPoint:event.locationInWindow fromView:nil]);
+        return;
+    }
 
-    if (event.phase == NSEventPhaseEnded || event.phase == NSEventPhaseCancelled)
-        _data->_gestureController->endMagnificationGesture();
+    NativeWebGestureEvent webEvent = NativeWebGestureEvent(event, self);
+    _data->_page->handleGestureEvent(webEvent);
+#else
+    _data->_gestureController->handleMagnificationGestureEvent(event, [self convertPoint:event.locationInWindow fromView:nil]);
+#endif
+}
+
+#if ENABLE(MAC_GESTURE_EVENTS)
+- (void)rotateWithEvent:(NSEvent *)event
+{
+    NativeWebGestureEvent webEvent = NativeWebGestureEvent(event, self);
+    _data->_page->handleGestureEvent(webEvent);
+}
+#endif
+
+- (void)_gestureEventWasNotHandledByWebCore:(NSEvent *)event
+{
+#if ENABLE(MAC_GESTURE_EVENTS)
+    if (_data->_gestureController)
+        _data->_gestureController->gestureEventWasNotHandledByWebCore(event, [self convertPoint:event.locationInWindow fromView:nil]);
+#endif
 }
 
 - (void)smartMagnifyWithEvent:(NSEvent *)event
@@ -4642,7 +4709,7 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
     _data->_gestureController->setDidMoveSwipeSnapshotCallback(callback);
 }
 
-- (id)_immediateActionAnimationControllerForHitTestResult:(WKHitTestResultRef)hitTestResult withType:(_WKImmediateActionType)type userData:(WKTypeRef)userData
+- (id)_immediateActionAnimationControllerForHitTestResult:(WKHitTestResultRef)hitTestResult withType:(uint32_t)type userData:(WKTypeRef)userData
 {
     return nil;
 }