Bug 1288187 - Allow synthesizing widget touch events on OS X. r?mstange
MozReview-Commit-ID: 3xL8Ttm2bR6
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -415,16 +415,22 @@ public:
virtual nsresult SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint,
uint32_t aNativeMessage,
double aDeltaX,
double aDeltaY,
double aDeltaZ,
uint32_t aModifierFlags,
uint32_t aAdditionalFlags,
nsIObserver* aObserver) override;
+ virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
+ TouchPointerState aPointerState,
+ LayoutDeviceIntPoint aPoint,
+ double aPointerPressure,
+ uint32_t aPointerOrientation,
+ nsIObserver* aObserver) override;
// Mac specific methods
virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent& event);
void WillPaintWindow();
bool PaintWindow(LayoutDeviceIntRegion aRegion);
bool PaintWindowInContext(CGContextRef aContext, const LayoutDeviceIntRegion& aRegion,
@@ -642,11 +648,15 @@ protected:
// flag tells us that we shouldn't allow the remaining events to cause
// scrolling. It is reset to false once a new gesture starts (as indicated by
// a PANGESTURE_(MAY)START event).
bool mCurrentPanGestureBelongsToSwipe;
static uint32_t sLastInputEventCount;
void ReleaseTitlebarCGContext();
+
+ // This is used by SynthesizeNativeTouchPoint to maintain state between
+ // multiple synthesized points
+ mozilla::UniquePtr<mozilla::MultiTouchInput> mSynthesizedTouchInput;
};
#endif // nsChildView_h_
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1179,16 +1179,64 @@ nsresult nsChildView::SynthesizeNativeMo
CGEventPost(kCGHIDEventTap, cgEvent);
CFRelease(cgEvent);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
+nsresult nsChildView::SynthesizeNativeTouchPoint(uint32_t aPointerId,
+ TouchPointerState aPointerState,
+ mozilla::LayoutDeviceIntPoint aPoint,
+ double aPointerPressure,
+ uint32_t aPointerOrientation,
+ nsIObserver* aObserver)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ AutoObserverNotifier notifier(aObserver, "touchpoint");
+
+ MOZ_ASSERT(NS_IsMainThread());
+ if (aPointerState == TOUCH_HOVER) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (!mSynthesizedTouchInput) {
+ mSynthesizedTouchInput = MakeUnique<MultiTouchInput>();
+ }
+
+ LayoutDeviceIntPoint pointInWindow = aPoint - WidgetToScreenOffset();
+ MultiTouchInput inputToDispatch = UpdateSynthesizedTouchState(
+ mSynthesizedTouchInput.get(), aPointerId, aPointerState,
+ pointInWindow, aPointerPressure, aPointerOrientation);
+
+ if (mAPZC) {
+ uint64_t inputBlockId = 0;
+ ScrollableLayerGuid guid;
+
+ nsEventStatus result = mAPZC->ReceiveInputEvent(inputToDispatch, &guid, &inputBlockId);
+ if (result == nsEventStatus_eConsumeNoDefault) {
+ return NS_OK;
+ }
+
+ WidgetTouchEvent event = inputToDispatch.ToWidgetTouchEvent(this);
+ ProcessUntransformedAPZEvent(&event, guid, inputBlockId, result);
+ } else {
+ WidgetTouchEvent event = inputToDispatch.ToWidgetTouchEvent(this);
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ }
+
+ return NS_OK;;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
// First argument has to be an NSMenu representing the application's top-level
// menu bar. The returned item is *not* retained.
static NSMenuItem* NativeMenuItemWithLocation(NSMenu* menubar, NSString* locationString)
{
NSArray* indexes = [locationString componentsSeparatedByString:@"|"];
unsigned int indexCount = [indexes count];
if (indexCount == 0)
return nil;