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

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

Issue 2475173002: MacViews: Fix window dragging on Sierra. (Closed)
Patch Set: Rebase. Update comment. #include=>#import. 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
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/bridged_native_widget_interactive_uitest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..5dded116ff5474a67c59f354da9a31290e809bf1 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 @@ BOOL WindowWantsMouseDownReposted(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 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
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 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
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]);
@@ -561,11 +578,14 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
// appear with a "flash" if they are made visible before the frame from the
// compositor arrives. To get around this, set the alpha value of the window
// to 0, till we receive the correct frame from the compositor. Also, ignore
- // mouse clicks till then.
+ // mouse clicks till then. Also check for an active task runner on the
+ // WindowResizeHelperMac instance to ensure visibility is only suppressed when
+ // there is an active GPU process.
// TODO(karandeepb): Investigate whether similar technique is needed for other
// dialog types.
if (layer() && [window_ isOpaque] && !window_visible_ &&
- !native_widget_mac_->GetWidget()->IsModal()) {
+ !native_widget_mac_->GetWidget()->IsModal() &&
+ ui::WindowResizeHelperMac::Get()->task_runner()) {
initial_visibility_suppressed_ = true;
[window_ setAlphaValue:0.0];
[window_ setIgnoresMouseEvents:YES];
@@ -876,26 +896,20 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
}
}
-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)
+ return false;
// Check that the point is not obscured by non-content NSViews.
for (NSView* subview : [[bridged_view_ superview] subviews]) {
@@ -903,13 +917,28 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
continue;
if (![subview mouseDownCanMoveWindow] &&
- NSPointInRect(location_in_window, [subview frame])) {
- should_move_window = false;
- break;
- }
+ NSPointInRect(location_in_window, [subview frame]))
+ return false;
+ }
+
+ 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 (!should_move_window)
+ if (!ShouldDragWindow(event))
return false;
// Make the window draggable, then return true to repost the event.
@@ -1375,6 +1404,8 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
}
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
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/bridged_native_widget_interactive_uitest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698