| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ui/views/cocoa/bridged_native_widget.h" | 5 #import "ui/views/cocoa/bridged_native_widget.h" |
| 6 | 6 |
| 7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #import "base/mac/foundation_util.h" | 12 #import "base/mac/foundation_util.h" |
| 13 #include "base/mac/mac_util.h" | 13 #include "base/mac/mac_util.h" |
| 14 #import "base/mac/sdk_forward_declarations.h" | 14 #import "base/mac/sdk_forward_declarations.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" | 16 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" |
| 17 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" | 17 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" |
| 18 #include "ui/base/hit_test.h" | 18 #include "ui/base/hit_test.h" |
| 19 #include "ui/base/ime/input_method.h" | 19 #include "ui/base/ime/input_method.h" |
| 20 #include "ui/base/ime/input_method_factory.h" | 20 #include "ui/base/ime/input_method_factory.h" |
| 21 #include "ui/display/display.h" | 21 #include "ui/display/display.h" |
| 22 #include "ui/display/screen.h" | 22 #include "ui/display/screen.h" |
| 23 #include "ui/gfx/geometry/dip_util.h" | 23 #include "ui/gfx/geometry/dip_util.h" |
| 24 #import "ui/gfx/mac/coordinate_conversion.h" | 24 #import "ui/gfx/mac/coordinate_conversion.h" |
| 25 #import "ui/gfx/mac/nswindow_frame_controls.h" | 25 #import "ui/gfx/mac/nswindow_frame_controls.h" |
| 26 #import "ui/views/cocoa/bridged_content_view.h" | 26 #import "ui/views/cocoa/bridged_content_view.h" |
| 27 #import "ui/views/cocoa/cocoa_mouse_capture.h" | 27 #import "ui/views/cocoa/cocoa_mouse_capture.h" |
| 28 #import "ui/views/cocoa/cocoa_window_move_loop.h" |
| 28 #include "ui/views/cocoa/tooltip_manager_mac.h" | 29 #include "ui/views/cocoa/tooltip_manager_mac.h" |
| 29 #import "ui/views/cocoa/views_nswindow_delegate.h" | 30 #import "ui/views/cocoa/views_nswindow_delegate.h" |
| 30 #import "ui/views/cocoa/widget_owner_nswindow_adapter.h" | 31 #import "ui/views/cocoa/widget_owner_nswindow_adapter.h" |
| 31 #include "ui/views/view.h" | 32 #include "ui/views/view.h" |
| 32 #include "ui/views/views_delegate.h" | 33 #include "ui/views/views_delegate.h" |
| 33 #include "ui/views/widget/native_widget_mac.h" | 34 #include "ui/views/widget/native_widget_mac.h" |
| 34 #include "ui/views/widget/widget.h" | 35 #include "ui/views/widget/widget.h" |
| 35 #include "ui/views/widget/widget_aura_utils.h" | 36 #include "ui/views/widget/widget_aura_utils.h" |
| 36 #include "ui/views/widget/widget_delegate.h" | 37 #include "ui/views/widget/widget_delegate.h" |
| 37 | 38 |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 } | 609 } |
| 609 | 610 |
| 610 void BridgedNativeWidget::ReleaseCapture() { | 611 void BridgedNativeWidget::ReleaseCapture() { |
| 611 mouse_capture_.reset(); | 612 mouse_capture_.reset(); |
| 612 } | 613 } |
| 613 | 614 |
| 614 bool BridgedNativeWidget::HasCapture() { | 615 bool BridgedNativeWidget::HasCapture() { |
| 615 return mouse_capture_ && mouse_capture_->IsActive(); | 616 return mouse_capture_ && mouse_capture_->IsActive(); |
| 616 } | 617 } |
| 617 | 618 |
| 619 Widget::MoveLoopResult BridgedNativeWidget::RunMoveLoop( |
| 620 const gfx::Vector2d& drag_offset) { |
| 621 DCHECK(!HasCapture()); |
| 622 DCHECK(!window_move_loop_); |
| 623 |
| 624 // First, position the window in the right place. The point |drag_offset| |
| 625 // away from the top-left corner needs to be positioned under the mouse. |
| 626 gfx::Point mouse_in_screen = |
| 627 display::Screen::GetScreen()->GetCursorScreenPoint(); |
| 628 |
| 629 // A window can't be moved vertically up out of the work area. Treat this case |
| 630 // as if the mouse location is at the point it would be when the window first |
| 631 // stopped moving. That is, vertically down such that the top edge of the |
| 632 // window touches the menubar (or top of the screen in a dual-screen setup). |
| 633 // Note on Mac we can assume that the y-coordinate of the work area origin is |
| 634 // the bottom of the menu bar and not the Dock which doesn't affect window |
| 635 // movement, but can reduce the work area on the bottom, left and right. |
| 636 const display::Display display = |
| 637 display::Screen::GetScreen()->GetDisplayNearestPoint(mouse_in_screen); |
| 638 const int min_y = display.work_area().y() + drag_offset.y(); |
| 639 if (mouse_in_screen.y() < min_y) |
| 640 mouse_in_screen.set_y(min_y); |
| 641 |
| 642 gfx::Rect frame = gfx::ScreenRectFromNSRect([window_ frame]); |
| 643 frame.set_x(mouse_in_screen.x() - drag_offset.x()); |
| 644 frame.set_y(mouse_in_screen.y() - drag_offset.y()); |
| 645 DCHECK_GE(frame.y(), display.work_area().y()); |
| 646 |
| 647 // After setting the frame to correct the initial offset, the drag controller |
| 648 // may immediately want to quit when it's notified of the new bounds. So the |
| 649 // MoveLoop must be set up before the call to setFrame. |
| 650 window_move_loop_.reset(new CocoaWindowMoveLoop(this, mouse_in_screen)); |
| 651 |
| 652 const NSRect ns_frame = gfx::ScreenRectToNSRect(frame); |
| 653 [window_ setFrame:ns_frame display:NO animate:NO]; |
| 654 |
| 655 // Setting the frame will call OnWidgetBoundsChanged(), which could result in |
| 656 // a call to EndMoveLoop(). |
| 657 if (!window_move_loop_) |
| 658 return Widget::MOVE_LOOP_SUCCESSFUL; |
| 659 |
| 660 return window_move_loop_->Run(); |
| 661 |
| 662 // |this| may be destroyed during the RunLoop, causing it to exit early. |
| 663 // Even if that doesn't happen, CocoaWindowMoveLoop will clean itself up by |
| 664 // calling EndMoveLoop(). So window_move_loop_ will always be null before the |
| 665 // function returns. But don't DCHECK since |this| might not be valid. |
| 666 } |
| 667 |
| 668 void BridgedNativeWidget::EndMoveLoop() { |
| 669 DCHECK(window_move_loop_); |
| 670 window_move_loop_->End(); |
| 671 window_move_loop_.reset(); |
| 672 } |
| 673 |
| 618 void BridgedNativeWidget::SetNativeWindowProperty(const char* name, | 674 void BridgedNativeWidget::SetNativeWindowProperty(const char* name, |
| 619 void* value) { | 675 void* value) { |
| 620 NSString* key = [NSString stringWithUTF8String:name]; | 676 NSString* key = [NSString stringWithUTF8String:name]; |
| 621 if (value) { | 677 if (value) { |
| 622 [GetWindowProperties() setObject:[NSValue valueWithPointer:value] | 678 [GetWindowProperties() setObject:[NSValue valueWithPointer:value] |
| 623 forKey:key]; | 679 forKey:key]; |
| 624 } else { | 680 } else { |
| 625 [GetWindowProperties() removeObjectForKey:key]; | 681 [GetWindowProperties() removeObjectForKey:key]; |
| 626 } | 682 } |
| 627 } | 683 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 | 782 |
| 727 // 10.9 is unable to generate a window shadow from the composited CALayer, so | 783 // 10.9 is unable to generate a window shadow from the composited CALayer, so |
| 728 // use Quartz. | 784 // use Quartz. |
| 729 // We don't update the window mask during a live resize, instead it is done | 785 // We don't update the window mask during a live resize, instead it is done |
| 730 // after the resize is completed in viewDidEndLiveResize: in | 786 // after the resize is completed in viewDidEndLiveResize: in |
| 731 // BridgedContentView. | 787 // BridgedContentView. |
| 732 if (base::mac::IsOSMavericksOrEarlier() && ![window_ inLiveResize]) | 788 if (base::mac::IsOSMavericksOrEarlier() && ![window_ inLiveResize]) |
| 733 [bridged_view_ updateWindowMask]; | 789 [bridged_view_ updateWindowMask]; |
| 734 } | 790 } |
| 735 | 791 |
| 792 void BridgedNativeWidget::OnPositionChanged() { |
| 793 native_widget_mac_->GetWidget()->OnNativeWidgetMove(); |
| 794 } |
| 795 |
| 736 void BridgedNativeWidget::OnVisibilityChanged() { | 796 void BridgedNativeWidget::OnVisibilityChanged() { |
| 737 OnVisibilityChangedTo([window_ isVisible]); | 797 OnVisibilityChangedTo([window_ isVisible]); |
| 738 } | 798 } |
| 739 | 799 |
| 740 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { | 800 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { |
| 741 if (window_visible_ == new_visibility) | 801 if (window_visible_ == new_visibility) |
| 742 return; | 802 return; |
| 743 | 803 |
| 744 window_visible_ = new_visibility; | 804 window_visible_ = new_visibility; |
| 745 | 805 |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 [bridged_view_ setMouseDownCanMoveWindow:draggable]; | 1363 [bridged_view_ setMouseDownCanMoveWindow:draggable]; |
| 1304 // AppKit will not update its cache of mouseDownCanMoveWindow unless something | 1364 // AppKit will not update its cache of mouseDownCanMoveWindow unless something |
| 1305 // changes. Previously we tried adding an NSView and removing it, but for some | 1365 // changes. Previously we tried adding an NSView and removing it, but for some |
| 1306 // reason it required reposting the mouse-down event, and didn't always work. | 1366 // reason it required reposting the mouse-down event, and didn't always work. |
| 1307 // Calling the below seems to be an effective solution. | 1367 // Calling the below seems to be an effective solution. |
| 1308 [window_ setMovableByWindowBackground:NO]; | 1368 [window_ setMovableByWindowBackground:NO]; |
| 1309 [window_ setMovableByWindowBackground:YES]; | 1369 [window_ setMovableByWindowBackground:YES]; |
| 1310 } | 1370 } |
| 1311 | 1371 |
| 1312 } // namespace views | 1372 } // namespace views |
| OLD | NEW |