Chromium Code Reviews| Index: ui/views/cocoa/bridged_native_widget.mm |
| diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm |
| index ce3731d026165eb42ef39e0b00bafe6953e2fcf9..248e09de35d1fc9c52360eb8fc1e477a7684918b 100644 |
| --- a/ui/views/cocoa/bridged_native_widget.mm |
| +++ b/ui/views/cocoa/bridged_native_widget.mm |
| @@ -169,16 +169,20 @@ bool IsPointInResizeArea(NSPoint point, NSWindow* window) { |
| return false; |
| } |
| +// Routes the |ns_event| to the corresponding BridgedNativeWidget and queries |
| +// whether the event should be reposted. |
| BOOL WindowWantsMouseDownReposted(NSEvent* ns_event) { |
| - id delegate = [[ns_event window] delegate]; |
| - return |
| - [delegate |
| - respondsToSelector:@selector(shouldRepostPendingLeftMouseDown:)] && |
| - [delegate shouldRepostPendingLeftMouseDown:[ns_event locationInWindow]]; |
| + DCHECK(views::BridgedNativeWidget::ShouldUseDragEventMonitor()); |
| + |
| + views::BridgedNativeWidget* bridge = |
| + views::NativeWidgetMac::GetBridgeForNativeWindow([ns_event window]); |
| + return bridge && bridge->ShouldRepostPendingLeftMouseDown(ns_event); |
| } |
| // Check if a mouse-down event should drag the window. If so, repost the event. |
| NSEvent* RepostEventIfHandledByWindow(NSEvent* ns_event) { |
| + DCHECK(views::BridgedNativeWidget::ShouldUseDragEventMonitor()); |
| + |
| enum RepostState { |
| // Nothing reposted: hit-test new mouse-downs to see if they need to be |
| // ignored and reposted after changing draggability. |
| @@ -253,9 +257,12 @@ NSEvent* RepostEventIfHandledByWindow(NSEvent* ns_event) { |
| // To bridge the two models, we monitor mouse-downs with |
| // +[NSEvent addLocalMonitorForEventsMatchingMask:handler:]. This receives |
| // events after window dragging is handled, so for mouse-downs that land on a |
| -// draggable point, we cancel the event and repost it at the CGSessionEventTap |
| -// level so that window dragging will be handled again. |
| +// draggable point, we cancel the event, make the window draggable and repost it |
| +// at the CGSessionEventTap level so that window dragging will be handled again. |
| +// On Mac OS > 10.10, we don't use an event monitor. Instead, we use [NSWindow |
| +// performWindowDragWithEvent:]. See [NativeWidgetMacNSWindow sendEvent:]. |
| void SetupDragEventMonitor() { |
| + DCHECK(views::BridgedNativeWidget::ShouldUseDragEventMonitor()); |
| static id monitor = nil; |
| if (monitor) |
| return; |
| @@ -338,6 +345,14 @@ gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize( |
| return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect)); |
| } |
| +// static |
| +// TODO(karandeepb): Remove usage of drag event monitor once we stop supporting |
| +// Mac OS 10.10. |
| +bool BridgedNativeWidget::ShouldUseDragEventMonitor() { |
| + return ![NSWindow |
| + instancesRespondToSelector:@selector(performWindowDragWithEvent:)]; |
| +} |
| + |
| BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent) |
| : native_widget_mac_(parent), |
| focus_manager_(nullptr), |
| @@ -347,7 +362,9 @@ BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent) |
| in_fullscreen_transition_(false), |
| window_visible_(false), |
| wants_to_be_visible_(false) { |
| - SetupDragEventMonitor(); |
| + if (BridgedNativeWidget::ShouldUseDragEventMonitor()) |
| + SetupDragEventMonitor(); |
| + |
| DCHECK(parent); |
| window_delegate_.reset( |
| [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]); |
| @@ -876,26 +893,21 @@ void BridgedNativeWidget::OnWindowKeyStatusChangedTo(bool is_key) { |
| } |
| } |
| -bool BridgedNativeWidget::ShouldRepostPendingLeftMouseDown( |
| - NSPoint location_in_window) { |
| - if (!bridged_view_) |
| +bool BridgedNativeWidget::ShouldDragWindow(NSEvent* event) { |
| + if (!bridged_view_ || [event type] != NSLeftMouseDown) |
| return false; |
| - if ([bridged_view_ mouseDownCanMoveWindow]) { |
| - // This is a re-post, the movement has already started, so we can make the |
| - // window non-draggable again. |
| - SetDraggable(false); |
| - return false; |
| - } |
| - |
| + NSPoint location_in_window = [event locationInWindow]; |
| if (IsPointInResizeArea(location_in_window, window_)) |
| return false; |
| gfx::Point point(location_in_window.x, |
| NSHeight([window_ frame]) - location_in_window.y); |
| - bool should_move_window = |
| - native_widget_mac()->GetWidget()->GetNonClientComponent(point) == |
| - HTCAPTION; |
| + |
| + if (native_widget_mac()->GetWidget()->GetNonClientComponent(point) != |
| + HTCAPTION) { |
|
tapted
2016/11/08 05:03:16
nit: no curlies
karandeepb
2016/11/09 04:44:19
Done.
|
| + return false; |
| + } |
| // Check that the point is not obscured by non-content NSViews. |
| for (NSView* subview : [[bridged_view_ superview] subviews]) { |
| @@ -904,12 +916,28 @@ bool BridgedNativeWidget::ShouldRepostPendingLeftMouseDown( |
| if (![subview mouseDownCanMoveWindow] && |
| NSPointInRect(location_in_window, [subview frame])) { |
|
tapted
2016/11/08 05:03:16
nit: no curlies
karandeepb
2016/11/09 04:44:20
Done.
|
| - should_move_window = false; |
| - break; |
| + return false; |
| } |
| } |
| - if (!should_move_window) |
| + return true; |
| +} |
| + |
| +bool BridgedNativeWidget::ShouldRepostPendingLeftMouseDown(NSEvent* event) { |
| + DCHECK(BridgedNativeWidget::ShouldUseDragEventMonitor()); |
| + DCHECK_EQ(NSLeftMouseDown, [event type]); |
| + |
| + if (!bridged_view_) |
| + return false; |
| + |
| + if ([bridged_view_ mouseDownCanMoveWindow]) { |
| + // This is a re-post, the movement has already started, so we can make the |
| + // window non-draggable again. |
| + SetDraggable(false); |
| + return false; |
| + } |
| + |
| + if (!ShouldDragWindow(event)) |
| return false; |
| // Make the window draggable, then return true to repost the event. |
| @@ -1375,6 +1403,8 @@ NSMutableDictionary* BridgedNativeWidget::GetWindowProperties() const { |
| } |
| void BridgedNativeWidget::SetDraggable(bool draggable) { |
| + DCHECK(BridgedNativeWidget::ShouldUseDragEventMonitor()); |
| + |
| [bridged_view_ setMouseDownCanMoveWindow:draggable]; |
| // AppKit will not update its cache of mouseDownCanMoveWindow unless something |
| // changes. Previously we tried adding an NSView and removing it, but for some |