| 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 09f7880cc8d3e501e047e89ce2f1eb0b49864527..d631dab28a5e449b3f0ddb4a722a75cbe84b711c 100644
|
| --- a/ui/views/cocoa/bridged_native_widget.mm
|
| +++ b/ui/views/cocoa/bridged_native_widget.mm
|
| @@ -35,16 +35,6 @@
|
| #include "ui/views/widget/widget_aura_utils.h"
|
| #include "ui/views/widget/widget_delegate.h"
|
|
|
| -extern "C" {
|
| -
|
| -typedef int32_t CGSConnection;
|
| -CGSConnection _CGSDefaultConnection();
|
| -CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection,
|
| - NSInteger windowNumber,
|
| - int radius);
|
| -
|
| -}
|
| -
|
| // The NSView that hosts the composited CALayer drawing the UI. It fills the
|
| // window but is not hittable so that accessibility hit tests always go to the
|
| // BridgedContentView.
|
| @@ -106,6 +96,8 @@ const int kResizeAreaCornerSize = 12;
|
|
|
| int kWindowPropertiesKey;
|
|
|
| +bool g_ignore_next_mouse_down_for_draggable_regions = false;
|
| +
|
| float GetDeviceScaleFactorFromView(NSView* view) {
|
| gfx::Display display =
|
| gfx::Screen::GetScreen()->GetDisplayNearestWindow(view);
|
| @@ -203,6 +195,11 @@ NSEvent* RepostEventIfHandledByWindow(NSEvent* ns_event) {
|
| // - any repost loop.
|
|
|
| if (repost_state == NONE) {
|
| + if (g_ignore_next_mouse_down_for_draggable_regions) {
|
| + g_ignore_next_mouse_down_for_draggable_regions = false;
|
| + return ns_event;
|
| + }
|
| +
|
| if (WindowWantsMouseDownReposted(ns_event)) {
|
| repost_state = EXPECTING_REPOST;
|
| reposted_event_number = event_number;
|
| @@ -311,6 +308,16 @@ NSComparisonResult SubviewSorter(NSViewComparatorValue lhs,
|
|
|
| } // namespace
|
|
|
| +extern "C" {
|
| +
|
| +typedef int32_t CGSConnection;
|
| +CGSConnection _CGSDefaultConnection();
|
| +CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection,
|
| + NSInteger windowNumber,
|
| + int radius);
|
| +
|
| +}
|
| +
|
| namespace views {
|
|
|
| // static
|
| @@ -615,6 +622,81 @@ bool BridgedNativeWidget::HasCapture() {
|
| return mouse_capture_ && mouse_capture_->IsActive();
|
| }
|
|
|
| +Widget::MoveLoopResult BridgedNativeWidget::RunMoveLoop(
|
| + const gfx::Vector2d& drag_offset) {
|
| + DCHECK(!HasCapture());
|
| + DCHECK(!window_move_loop_);
|
| +
|
| + // First, position the window in the right place. The point |drag_offset|
|
| + // away from the top-left corner needs to be positioned under the mouse.
|
| + // TODO(tapted): Figure out why the toolkit-views drag controller doesn't get
|
| + // this right when it first initializes the Widget.
|
| + gfx::Point mouse_in_screen = gfx::Screen::GetScreen()->GetCursorScreenPoint();
|
| +
|
| + // We won't be able to simulate MouseDown events on top of menu bar, so
|
| + // constrain the initial dragging.
|
| + const gfx::Display display =
|
| + gfx::Screen::GetScreen()->GetDisplayNearestPoint(mouse_in_screen);
|
| + mouse_in_screen =
|
| + gfx::ConstrainToEnclosingRect(display.work_area(), mouse_in_screen);
|
| +
|
| + gfx::Rect frame = gfx::ScreenRectFromNSRect([window_ frame]);
|
| + frame.set_x(mouse_in_screen.x() - drag_offset.x());
|
| + frame.set_y(mouse_in_screen.y() - drag_offset.y());
|
| +
|
| + // We won't be able to simulate MouseDown events on top of menu bar, so
|
| + // constrain the initial dragging. Don't use AdjustToFit(display.work_area())
|
| + // as it's totally fine to move beyond the other borders.
|
| + // DetachToBrowserTabDragControllerTest.MacDetachesWindowOnTopOfMacMenuBar
|
| + // will fail without this code.
|
| + if (frame.y() < display.work_area().y()) {
|
| + frame.set_y(display.work_area().y());
|
| + }
|
| +
|
| + // After setting the frame to correct the initial offset, the drag controller
|
| + // may immediately want to quit when it's notified of the new bounds. So the
|
| + // MoveLoop must be set up before the call to setFrame.
|
| + window_move_loop_.reset(new CocoaWindowMoveLoop(this, mouse_in_screen));
|
| +
|
| + // Animating may provide a less janky UX, but something custom would be
|
| + // required so that it follows updates to the mouse position.
|
| + const NSRect ns_frame = gfx::ScreenRectToNSRect(frame);
|
| + [window_ setFrame:ns_frame display:YES animate:NO];
|
| +
|
| + // Setting the frame will call OnWidgetBoundsChanged(), which could result in
|
| + // a call to EndMoveLoop().
|
| + if (!window_move_loop_)
|
| + return Widget::MOVE_LOOP_SUCCESSFUL;
|
| +
|
| + // Make sure WindowServer has caught up with moving the window, this is
|
| + // required in order to send the MouseDown click to the intended position.
|
| + // I was able to always replicate old window coordinates from
|
| + // CGSGetWindowBounds() on El Capitan.
|
| + // DetachToBrowserTabDragControllerTest.MacDetachesAndReattachesSecondTab will
|
| + // fail without the following NSRunLoop pass.
|
| + [[NSRunLoop currentRunLoop]
|
| + runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0]];
|
| + DCHECK(NSEqualRects(ns_frame, gfx::ScreenRectToNSRect(
|
| + native_widget_mac()->WindowServerFrame())));
|
| +
|
| + return window_move_loop_->Run();
|
| +
|
| + // |this| may be destroyed during the RunLoop, causing it to exit early.
|
| + // Even if that doesn't happen, CocoaWindowMoveLoop will clean itself up by
|
| + // calling EndMoveLoop(). So window_move_loop_ will always be null before the
|
| + // function returns. But don't DCHECK since |this| might not be valid.
|
| +}
|
| +
|
| +void BridgedNativeWidget::EndMoveLoop() {
|
| + DCHECK(window_move_loop_);
|
| + window_move_loop_->End();
|
| + window_move_loop_.reset();
|
| +}
|
| +
|
| +bool BridgedNativeWidget::IsRunMoveLoopActive() const {
|
| + return window_move_loop_.get();
|
| +}
|
| +
|
| void BridgedNativeWidget::SetNativeWindowProperty(const char* name,
|
| void* value) {
|
| NSString* key = [NSString stringWithUTF8String:name];
|
| @@ -636,6 +718,7 @@ void BridgedNativeWidget::SetCursor(NSCursor* cursor) {
|
| }
|
|
|
| void BridgedNativeWidget::OnWindowWillClose() {
|
| + DCHECK(!drag_run_loop_);
|
| if (parent_) {
|
| parent_->RemoveChildWindow(this);
|
| parent_ = nullptr;
|
| @@ -738,6 +821,10 @@ void BridgedNativeWidget::OnSizeChanged() {
|
| [bridged_view_ updateWindowMask];
|
| }
|
|
|
| +void BridgedNativeWidget::OnPositionChanged() {
|
| + native_widget_mac_->GetWidget()->OnNativeWidgetMove();
|
| +}
|
| +
|
| void BridgedNativeWidget::OnVisibilityChanged() {
|
| OnVisibilityChangedTo([window_ isVisible]);
|
| }
|
| @@ -1314,4 +1401,9 @@ void BridgedNativeWidget::SetDraggable(bool draggable) {
|
| [window_ setMovableByWindowBackground:YES];
|
| }
|
|
|
| +// static
|
| +void BridgedNativeWidget::IgnoreNextMouseDownForDraggableRegions() {
|
| + g_ignore_next_mouse_down_for_draggable_regions = true;
|
| +}
|
| +
|
| } // namespace views
|
|
|