Commit be0b14cb authored by ccameron's avatar ccameron Committed by Commit bot

Add GesturePinchBegin/End events on Mac

Because a single gesture (in NSEvent-speak) can contain multiple types
of sub-gestures (e.g, pinch and rotate), we do not get a begin/end
of the magnify-only part of the gesture. Work around this by saving
the NSEvent-gesture's beginning event, sending it (with the right type)
when the magnification begins, and sending an end event when the
gesture ends (only if a magnification event was sent).

BUG=451559

Review URL: https://codereview.chromium.org/886893002

Cr-Commit-Position: refs/heads/master@{#314594}
parent 253dde8e
# Mac files
per-file *.mm=avi@chromium.org
per-file *.mm=ccameron@chromium.org
per-file *.mm=erikchen@chromium.org
per-file *.mm=mark@chromium.org
per-file *.mm=rsesek@chromium.org
per-file *.mm=thakis@chromium.org
per-file *_mac.h=avi@chromium.org
per-file *_mac.h=ccameron@chromium.org
per-file *_mac.h=erikchen@chromium.org
per-file *_mac.h=mark@chromium.org
per-file *_mac.h=rsesek@chromium.org
per-file *_mac.h=thakis@chromium.org
...@@ -124,6 +124,26 @@ class ChromeRenderWidgetHostViewMacHistorySwiperTest ...@@ -124,6 +124,26 @@ class ChromeRenderWidgetHostViewMacHistorySwiperTest
// Create mock events -------------------------------------------------------- // Create mock events --------------------------------------------------------
// Create a gesture event with no useful data. Used to create Begin and End
// events.
id MockGestureEvent(NSEventType type) {
id event = [OCMockObject mockForClass:[NSEvent class]];
NSPoint locationInWindow = NSMakePoint(0, 0);
CGFloat deltaX = 0;
CGFloat deltaY = 0;
NSTimeInterval timestamp = 0;
NSUInteger modifierFlags = 0;
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
[(NSEvent*)[[event stub]
andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow];
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX];
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY];
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp];
[(NSEvent*)[[event stub]
andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags];
return event;
}
// Creates a mock scroll wheel event that is backed by a real CGEvent. // Creates a mock scroll wheel event that is backed by a real CGEvent.
id MockScrollWheelEvent(NSPoint delta, NSEventType type) { id MockScrollWheelEvent(NSPoint delta, NSEventType type) {
CGEventRef cg_event = CGEventRef cg_event =
...@@ -189,18 +209,14 @@ class ChromeRenderWidgetHostViewMacHistorySwiperTest ...@@ -189,18 +209,14 @@ class ChromeRenderWidgetHostViewMacHistorySwiperTest
// Queues a gesture begin event (e.g. [NSView gestureDidBegin:]) // Queues a gesture begin event (e.g. [NSView gestureDidBegin:])
void QueueGestureBegin() { void QueueGestureBegin() {
id event = [OCMockObject mockForClass:[NSEvent class]]; QueueEvent(MockGestureEvent(NSEventTypeBeginGesture),
NSEventType type = NSEventTypeBeginGesture; DEPLOYMENT_GESTURE_BEGIN, NO);
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
QueueEvent(event, DEPLOYMENT_GESTURE_BEGIN, NO);
} }
// Queues a gesture end event (e.g. [NSView gestureDidEnd:]) // Queues a gesture end event (e.g. [NSView gestureDidEnd:])
void QueueGestureEnd() { void QueueGestureEnd() {
id event = [OCMockObject mockForClass:[NSEvent class]]; QueueEvent(MockGestureEvent(NSEventTypeEndGesture),
NSEventType type = NSEventTypeEndGesture; DEPLOYMENT_GESTURE_BEGIN, NO);
[(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
QueueEvent(event, DEPLOYMENT_GESTURE_END, NO);
} }
// Queues a touch event with absolute coordinates |x| and |y|. // Queues a touch event with absolute coordinates |x| and |y|.
......
...@@ -148,6 +148,18 @@ class Layer; ...@@ -148,6 +148,18 @@ class Layer;
// Event monitor for scroll wheel end event. // Event monitor for scroll wheel end event.
id endWheelMonitor_; id endWheelMonitor_;
// When a gesture starts, the system does not inform the view of which type
// of gesture is happening (magnify, rotate, etc), rather, it just informs
// the view that some as-yet-undefined gesture is starting. Capture the
// information about the gesture's beginning event here. It will be used to
// create a specific gesture begin event later.
scoped_ptr<blink::WebGestureEvent> gestureBeginEvent_;
// This is set if a GesturePinchBegin event has been sent in the lifetime of
// |gestureBeginEvent_|. If set, a GesturePinchEnd will be sent when the
// gesture ends.
BOOL gestureBeginPinchSent_;
// If true then escape key down events are suppressed until the first escape // If true then escape key down events are suppressed until the first escape
// key up event. (The up event is suppressed as well). This is used by the // key up event. (The up event is suppressed as well). This is used by the
// flash fullscreen code to avoid sending a key up event without a matching // flash fullscreen code to avoid sending a key up event without a matching
......
...@@ -2239,19 +2239,37 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( ...@@ -2239,19 +2239,37 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
- (void)beginGestureWithEvent:(NSEvent*)event { - (void)beginGestureWithEvent:(NSEvent*)event {
[responderDelegate_ beginGestureWithEvent:event]; [responderDelegate_ beginGestureWithEvent:event];
gestureBeginEvent_.reset(
new WebGestureEvent(WebInputEventFactory::gestureEvent(event, self)));
} }
- (void)endGestureWithEvent:(NSEvent*)event { - (void)endGestureWithEvent:(NSEvent*)event {
[responderDelegate_ endGestureWithEvent:event]; [responderDelegate_ endGestureWithEvent:event];
gestureBeginEvent_.reset();
if (!renderWidgetHostView_->render_widget_host_)
return;
if (gestureBeginPinchSent_) {
WebGestureEvent endEvent(WebInputEventFactory::gestureEvent(event, self));
endEvent.type = WebInputEvent::GesturePinchEnd;
renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(endEvent);
gestureBeginPinchSent_ = NO;
}
} }
- (void)touchesMovedWithEvent:(NSEvent*)event { - (void)touchesMovedWithEvent:(NSEvent*)event {
[responderDelegate_ touchesMovedWithEvent:event]; [responderDelegate_ touchesMovedWithEvent:event];
} }
- (void)touchesBeganWithEvent:(NSEvent*)event { - (void)touchesBeganWithEvent:(NSEvent*)event {
[responderDelegate_ touchesBeganWithEvent:event]; [responderDelegate_ touchesBeganWithEvent:event];
} }
- (void)touchesCancelledWithEvent:(NSEvent*)event { - (void)touchesCancelledWithEvent:(NSEvent*)event {
[responderDelegate_ touchesCancelledWithEvent:event]; [responderDelegate_ touchesCancelledWithEvent:event];
} }
- (void)touchesEndedWithEvent:(NSEvent*)event { - (void)touchesEndedWithEvent:(NSEvent*)event {
[responderDelegate_ touchesEndedWithEvent:event]; [responderDelegate_ touchesEndedWithEvent:event];
} }
...@@ -2330,16 +2348,27 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( ...@@ -2330,16 +2348,27 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
// Called repeatedly during a pinch gesture, with incremental change values. // Called repeatedly during a pinch gesture, with incremental change values.
- (void)magnifyWithEvent:(NSEvent*)event { - (void)magnifyWithEvent:(NSEvent*)event {
if (renderWidgetHostView_->render_widget_host_) { if (!renderWidgetHostView_->render_widget_host_)
// Send a GesturePinchUpdate event. return;
// Note that we don't attempt to bracket these by GesturePinchBegin/End (or
// GestureSrollBegin/End) as is done for touchscreen. Keeping track of when // If, due to nesting of multiple gestures (e.g, from multiple touch
// a pinch is active would take a little more work here, and we don't need // devices), the beginning of the gesture has been lost, skip the remainder
// it for anything yet. // of the gesture.
const WebGestureEvent& webEvent = if (!gestureBeginEvent_)
WebInputEventFactory::gestureEvent(event, self); return;
renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent);
// Send a GesturePinchBegin event if none has been sent yet.
if (!gestureBeginPinchSent_) {
WebGestureEvent beginEvent(*gestureBeginEvent_);
beginEvent.type = WebInputEvent::GesturePinchBegin;
renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(beginEvent);
gestureBeginPinchSent_ = YES;
} }
// Send a GesturePinchUpdate event.
const WebGestureEvent& updateEvent =
WebInputEventFactory::gestureEvent(event, self);
renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(updateEvent);
} }
- (void)viewWillMoveToWindow:(NSWindow*)newWindow { - (void)viewWillMoveToWindow:(NSWindow*)newWindow {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment