Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 2475173002: MacViews: Fix window dragging on Sierra. (Closed)
Patch Set: Tests Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698