| 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 1c9560f2e8834aeb19225abd760819145854b361..75f7367be5e9e6c50a530c5d07840cf56470b199 100644
|
| --- a/ui/views/cocoa/bridged_native_widget.mm
|
| +++ b/ui/views/cocoa/bridged_native_widget.mm
|
| @@ -25,6 +25,7 @@
|
| #import "ui/gfx/mac/nswindow_frame_controls.h"
|
| #import "ui/views/cocoa/bridged_content_view.h"
|
| #import "ui/views/cocoa/cocoa_mouse_capture.h"
|
| +#import "ui/views/cocoa/cocoa_window_move_loop.h"
|
| #include "ui/views/cocoa/tooltip_manager_mac.h"
|
| #import "ui/views/cocoa/views_nswindow_delegate.h"
|
| #import "ui/views/cocoa/widget_owner_nswindow_adapter.h"
|
| @@ -615,6 +616,61 @@ 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.
|
| + gfx::Point mouse_in_screen =
|
| + display::Screen::GetScreen()->GetCursorScreenPoint();
|
| +
|
| + // A window can't be moved vertically up out of the work area. Treat this case
|
| + // as if the mouse location is at the point it would be when the window first
|
| + // stopped moving. That is, vertically down such that the top edge of the
|
| + // window touches the menubar (or top of the screen in a dual-screen setup).
|
| + // Note on Mac we can assume that the y-coordinate of the work area origin is
|
| + // the bottom of the menu bar and not the Dock which doesn't affect window
|
| + // movement, but can reduce the work area on the bottom, left and right.
|
| + const display::Display display =
|
| + display::Screen::GetScreen()->GetDisplayNearestPoint(mouse_in_screen);
|
| + const int min_y = display.work_area().y() + drag_offset.y();
|
| + if (mouse_in_screen.y() < min_y)
|
| + mouse_in_screen.set_y(min_y);
|
| +
|
| + 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());
|
| + DCHECK_GE(frame.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));
|
| +
|
| + const NSRect ns_frame = gfx::ScreenRectToNSRect(frame);
|
| + [window_ setFrame:ns_frame display:NO 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;
|
| +
|
| + 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();
|
| +}
|
| +
|
| void BridgedNativeWidget::SetNativeWindowProperty(const char* name,
|
| void* value) {
|
| NSString* key = [NSString stringWithUTF8String:name];
|
| @@ -733,6 +789,10 @@ void BridgedNativeWidget::OnSizeChanged() {
|
| [bridged_view_ updateWindowMask];
|
| }
|
|
|
| +void BridgedNativeWidget::OnPositionChanged() {
|
| + native_widget_mac_->GetWidget()->OnNativeWidgetMove();
|
| +}
|
| +
|
| void BridgedNativeWidget::OnVisibilityChanged() {
|
| OnVisibilityChangedTo([window_ isVisible]);
|
| }
|
|
|