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/run_loop.h" |
15 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
16 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" | 17 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" |
17 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" | 18 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" |
18 #include "ui/base/hit_test.h" | 19 #include "ui/base/hit_test.h" |
19 #include "ui/base/ime/input_method.h" | 20 #include "ui/base/ime/input_method.h" |
20 #include "ui/base/ime/input_method_factory.h" | 21 #include "ui/base/ime/input_method_factory.h" |
21 #include "ui/gfx/display.h" | 22 #include "ui/gfx/display.h" |
22 #include "ui/gfx/geometry/dip_util.h" | 23 #include "ui/gfx/geometry/dip_util.h" |
23 #import "ui/gfx/mac/coordinate_conversion.h" | 24 #import "ui/gfx/mac/coordinate_conversion.h" |
24 #import "ui/gfx/mac/nswindow_frame_controls.h" | 25 #import "ui/gfx/mac/nswindow_frame_controls.h" |
25 #include "ui/gfx/screen.h" | 26 #include "ui/gfx/screen.h" |
26 #import "ui/views/cocoa/bridged_content_view.h" | 27 #import "ui/views/cocoa/bridged_content_view.h" |
27 #import "ui/views/cocoa/cocoa_mouse_capture.h" | 28 #import "ui/views/cocoa/cocoa_mouse_capture.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 |
38 extern "C" { | |
39 | |
40 typedef int32_t CGSConnection; | |
41 CGSConnection _CGSDefaultConnection(); | |
42 CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection, | |
43 NSInteger windowNumber, | |
44 int radius); | |
45 | |
46 } | |
47 | |
48 // The NSView that hosts the composited CALayer drawing the UI. It fills the | 39 // The NSView that hosts the composited CALayer drawing the UI. It fills the |
49 // window but is not hittable so that accessibility hit tests always go to the | 40 // window but is not hittable so that accessibility hit tests always go to the |
50 // BridgedContentView. | 41 // BridgedContentView. |
51 @interface ViewsCompositorSuperview : NSView | 42 @interface ViewsCompositorSuperview : NSView |
52 @end | 43 @end |
53 | 44 |
54 @implementation ViewsCompositorSuperview | 45 @implementation ViewsCompositorSuperview |
55 - (NSView*)hitTest:(NSPoint)aPoint { | 46 - (NSView*)hitTest:(NSPoint)aPoint { |
56 return nil; | 47 return nil; |
57 } | 48 } |
(...skipping 29 matching lines...) Expand all Loading... |
87 const CGFloat kYosemiteMenuOpacity = 194.0 / 255.0; | 78 const CGFloat kYosemiteMenuOpacity = 194.0 / 255.0; |
88 const int kYosemiteMenuBlur = 80; | 79 const int kYosemiteMenuBlur = 80; |
89 | 80 |
90 // Margin at edge and corners of the window that trigger resizing. These match | 81 // Margin at edge and corners of the window that trigger resizing. These match |
91 // actual Cocoa resize margins. | 82 // actual Cocoa resize margins. |
92 const int kResizeAreaEdgeSize = 3; | 83 const int kResizeAreaEdgeSize = 3; |
93 const int kResizeAreaCornerSize = 12; | 84 const int kResizeAreaCornerSize = 12; |
94 | 85 |
95 int kWindowPropertiesKey; | 86 int kWindowPropertiesKey; |
96 | 87 |
| 88 bool g_ignore_next_mouse_down_for_draggable_regions = false; |
| 89 |
97 float GetDeviceScaleFactorFromView(NSView* view) { | 90 float GetDeviceScaleFactorFromView(NSView* view) { |
98 gfx::Display display = | 91 gfx::Display display = |
99 gfx::Screen::GetScreen()->GetDisplayNearestWindow(view); | 92 gfx::Screen::GetScreen()->GetDisplayNearestWindow(view); |
100 DCHECK(display.is_valid()); | 93 DCHECK(display.is_valid()); |
101 return display.device_scale_factor(); | 94 return display.device_scale_factor(); |
102 } | 95 } |
103 | 96 |
104 // Returns true if bounds passed to window in SetBounds should be treated as | 97 // Returns true if bounds passed to window in SetBounds should be treated as |
105 // though they are in screen coordinates. | 98 // though they are in screen coordinates. |
106 bool PositionWindowInScreenCoordinates(views::Widget* widget, | 99 bool PositionWindowInScreenCoordinates(views::Widget* widget, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 NSInteger event_number = [ns_event eventNumber]; | 177 NSInteger event_number = [ns_event eventNumber]; |
185 | 178 |
186 // The logic here is a bit convoluted because we want to mitigate race | 179 // The logic here is a bit convoluted because we want to mitigate race |
187 // conditions if somehow a different mouse-down occurs between reposts. | 180 // conditions if somehow a different mouse-down occurs between reposts. |
188 // Specifically, we want to avoid: | 181 // Specifically, we want to avoid: |
189 // - BridgedNativeWidget's draggability getting out of sync (e.g. if it is | 182 // - BridgedNativeWidget's draggability getting out of sync (e.g. if it is |
190 // draggable outside of a repost cycle), | 183 // draggable outside of a repost cycle), |
191 // - any repost loop. | 184 // - any repost loop. |
192 | 185 |
193 if (repost_state == NONE) { | 186 if (repost_state == NONE) { |
| 187 if (g_ignore_next_mouse_down_for_draggable_regions) { |
| 188 g_ignore_next_mouse_down_for_draggable_regions = false; |
| 189 return ns_event; |
| 190 } |
| 191 |
194 if (WindowWantsMouseDownReposted(ns_event)) { | 192 if (WindowWantsMouseDownReposted(ns_event)) { |
195 repost_state = EXPECTING_REPOST; | 193 repost_state = EXPECTING_REPOST; |
196 reposted_event_number = event_number; | 194 reposted_event_number = event_number; |
197 CGEventPost(kCGSessionEventTap, [ns_event CGEvent]); | 195 CGEventPost(kCGSessionEventTap, [ns_event CGEvent]); |
198 return nil; | 196 return nil; |
199 } | 197 } |
200 | 198 |
201 return ns_event; | 199 return ns_event; |
202 } | 200 } |
203 | 201 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // resize operations to coordinate with frames provided by the GPU process. | 254 // resize operations to coordinate with frames provided by the GPU process. |
257 scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() { | 255 scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() { |
258 // If the WindowResizeHelper's pumpable task runner is set, it means the GPU | 256 // If the WindowResizeHelper's pumpable task runner is set, it means the GPU |
259 // process is directing messages there, and the compositor can synchronize | 257 // process is directing messages there, and the compositor can synchronize |
260 // with it. Otherwise, just use the UI thread. | 258 // with it. Otherwise, just use the UI thread. |
261 scoped_refptr<base::SingleThreadTaskRunner> task_runner = | 259 scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
262 ui::WindowResizeHelperMac::Get()->task_runner(); | 260 ui::WindowResizeHelperMac::Get()->task_runner(); |
263 return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get(); | 261 return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get(); |
264 } | 262 } |
265 | 263 |
| 264 CGPoint GetCGMousePosition() { |
| 265 return CGEventGetLocation( |
| 266 base::ScopedCFTypeRef<CGEventRef>(CGEventCreate(nullptr))); |
| 267 } |
| 268 |
| 269 void SendCustomLeftMouseEvent(CGEventType type) { |
| 270 base::ScopedCFTypeRef<CGEventRef> event( |
| 271 CGEventCreateMouseEvent( |
| 272 nullptr, type, GetCGMousePosition(), |
| 273 kCGMouseButtonLeft)); |
| 274 CGEventSetIntegerValueField(event, kCGEventSourceUserData, 1); |
| 275 CGEventPost(kCGSessionEventTap, event); |
| 276 } |
| 277 |
266 } // namespace | 278 } // namespace |
267 | 279 |
| 280 extern "C" { |
| 281 |
| 282 typedef int32_t CGSConnection; |
| 283 CGSConnection _CGSDefaultConnection(); |
| 284 CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection, |
| 285 NSInteger windowNumber, |
| 286 int radius); |
| 287 |
| 288 } |
| 289 |
268 namespace views { | 290 namespace views { |
269 | 291 |
| 292 class CocoaWindowMoveLoop { |
| 293 public: |
| 294 explicit CocoaWindowMoveLoop(BridgedNativeWidget* owner) |
| 295 : owner_(owner), |
| 296 run_loop_(new base::RunLoop), |
| 297 quit_closure_(run_loop_->QuitClosure()) { |
| 298 // AppKit continues to send mouse events to the window, but toolkit-views |
| 299 // goes berserk if it gets them during RunMoveLoop(). |
| 300 [owner_->ns_view() setIgnoreMouseEvents:YES]; |
| 301 owner_->SetDraggable(true); |
| 302 } |
| 303 |
| 304 ~CocoaWindowMoveLoop() { |
| 305 owner_->SetDraggable(false); |
| 306 // Note the crafted events in Run() should not make their way through to |
| 307 // toolkit-views, but regular events after that should be. So stop ignoring. |
| 308 [owner_->ns_view() setIgnoreMouseEvents:NO]; |
| 309 |
| 310 // Handle the pathological case, where |this| is destroyed while running. |
| 311 if (exit_reason_ref_) { |
| 312 *exit_reason_ref_ = WINDOW_DESTROYED; |
| 313 quit_closure_.Run(); |
| 314 } |
| 315 |
| 316 // Handle Run() never being called. |
| 317 if (monitor_) { |
| 318 [NSEvent removeMonitor:monitor_]; |
| 319 monitor_ = nil; |
| 320 } |
| 321 owner_ = nullptr; |
| 322 } |
| 323 |
| 324 Widget::MoveLoopResult Run() { |
| 325 LoopExitReason exit_reason = ENDED_EXTERNALLY; |
| 326 exit_reason_ref_ = &exit_reason; |
| 327 |
| 328 // Move the RunLoop to the stack so our destructor can be called while it is |
| 329 // running. |
| 330 scoped_ptr<base::RunLoop> run_loop(std::move(run_loop_)); |
| 331 |
| 332 // A new window may have just been created, so post an event at the session |
| 333 // tap level to initiate a window drag. |
| 334 // TODO(tapted): Move this "inside" the window or stuff breaks when dragging |
| 335 // the last tab/s off a browser. |
| 336 SendCustomLeftMouseEvent(kCGEventLeftMouseDown); |
| 337 |
| 338 NSEventMask mask = |
| 339 NSLeftMouseUpMask | NSKeyDownMask | NSLeftMouseDraggedMask; |
| 340 monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:mask |
| 341 handler:^NSEvent*(NSEvent* event) { |
| 342 if ([event type] == NSLeftMouseDragged) { |
| 343 // AppKit doesn't supply position updates during a drag, so post a |
| 344 // task to notify observers once AppKit has moved the window. |
| 345 base::MessageLoop::current()->PostTask( |
| 346 FROM_HERE, base::Bind(&BridgedNativeWidget::OnPositionChanged, |
| 347 base::Unretained(owner_))); |
| 348 return event; |
| 349 } |
| 350 quit_closure_.Run(); |
| 351 if ([event type] == NSLeftMouseUp) { |
| 352 *exit_reason_ref_ = MOUSE_UP; |
| 353 return event; // Process the MouseUp. |
| 354 } |
| 355 *exit_reason_ref_ = ESCAPE_PRESSED; |
| 356 return nil; // Swallow the keypress. |
| 357 }]; |
| 358 |
| 359 // NSKeyDownMask doesn't work inside addLocalMonitorForEventsMatchingMask: |
| 360 // the event is swallowed by the window move loop before it gets to -[NSApp |
| 361 // sendEvent:]. To see an escape keypress, hook in an event tap lower. |
| 362 |
| 363 run_loop->Run(); |
| 364 |
| 365 if (exit_reason != WINDOW_DESTROYED && exit_reason != ENDED_EXTERNALLY) { |
| 366 exit_reason_ref_ = nullptr; // Ensure End() doesn't replace the reason. |
| 367 owner_->EndMoveLoop(); // Deletes |this|. |
| 368 } |
| 369 |
| 370 if (exit_reason != MOUSE_UP) { |
| 371 // Tell AppKit to stop moving the window. Otherwise, AppKit will refuse to |
| 372 // start a new window drag. Note the window being dragged is going away in |
| 373 // this case, so it doesn't really matter where the event is located. |
| 374 SendCustomLeftMouseEvent(kCGEventLeftMouseUp); |
| 375 |
| 376 if (exit_reason == ENDED_EXTERNALLY) { |
| 377 // When not canceled, the non-moving drag in the original window must |
| 378 // resume. To do this, AppKit needs to see a mouseDown so that it sends |
| 379 // the correct events. Ideally, it also needs to be at the original |
| 380 // offset, so that it hits a non-draggable region of the original |
| 381 // window: The tab being dragged may move some distance from the cursor |
| 382 // when it "snaps in", so the cursor may not be over a tab. Sadly, this |
| 383 // method doesn't know which window that is. But all that really needs |
| 384 // to be done is to prevent a custom-dragging area from starting a |
| 385 // window-drag. So hook into the logic in RepostEventIfHandledByWindow() |
| 386 // by setting a flag here. Note this assumes the custom mouseDown event |
| 387 // is guaranteed to hit another BridgedNativeWidget when it gets to the |
| 388 // front of the event queue. |
| 389 // TODO(tapted): A better fix would be to keep the temporary window |
| 390 // around and never call EndMoveLoop() on Mac, making this block of code |
| 391 // obsolete. |
| 392 g_ignore_next_mouse_down_for_draggable_regions = true; |
| 393 SendCustomLeftMouseEvent(kCGEventLeftMouseDown); |
| 394 } |
| 395 } |
| 396 |
| 397 return exit_reason == ESCAPE_PRESSED |
| 398 ? Widget::MOVE_LOOP_CANCELED : Widget::MOVE_LOOP_SUCCESSFUL; |
| 399 } |
| 400 |
| 401 void End() { |
| 402 if (exit_reason_ref_) { |
| 403 DCHECK_EQ(*exit_reason_ref_, ENDED_EXTERNALLY); |
| 404 // Ensure the destructor doesn't replace the reason. |
| 405 exit_reason_ref_ = nullptr; |
| 406 quit_closure_.Run(); |
| 407 } |
| 408 } |
| 409 |
| 410 static CGEventRef EscapeKeypressMonitor(CGEventTapProxy proxy, |
| 411 CGEventType type, |
| 412 CGEventRef event, |
| 413 void* refcon) { |
| 414 CocoaWindowMoveLoop* self = static_cast<CocoaWindowMoveLoop*>(refcon); |
| 415 (void)self; |
| 416 return event; |
| 417 } |
| 418 |
| 419 private: |
| 420 enum LoopExitReason { |
| 421 ENDED_EXTERNALLY, |
| 422 ESCAPE_PRESSED, |
| 423 MOUSE_UP, |
| 424 WINDOW_DESTROYED, |
| 425 }; |
| 426 |
| 427 BridgedNativeWidget* owner_; // Weak. Owns this. |
| 428 scoped_ptr<base::RunLoop> run_loop_; |
| 429 id monitor_ = nil; |
| 430 |
| 431 // Pointer to a stack variable holding the exit reason. |
| 432 LoopExitReason* exit_reason_ref_ = nullptr; |
| 433 base::Closure quit_closure_; |
| 434 |
| 435 DISALLOW_COPY_AND_ASSIGN(CocoaWindowMoveLoop); |
| 436 }; |
| 437 |
270 // static | 438 // static |
271 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize( | 439 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize( |
272 NSWindow* window, | 440 NSWindow* window, |
273 const gfx::Size& content_size) { | 441 const gfx::Size& content_size) { |
274 NSRect content_rect = | 442 NSRect content_rect = |
275 NSMakeRect(0, 0, content_size.width(), content_size.height()); | 443 NSMakeRect(0, 0, content_size.width(), content_size.height()); |
276 NSRect frame_rect = [window frameRectForContentRect:content_rect]; | 444 NSRect frame_rect = [window frameRectForContentRect:content_rect]; |
277 return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect)); | 445 return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect)); |
278 } | 446 } |
279 | 447 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 } | 730 } |
563 | 731 |
564 void BridgedNativeWidget::ReleaseCapture() { | 732 void BridgedNativeWidget::ReleaseCapture() { |
565 mouse_capture_.reset(); | 733 mouse_capture_.reset(); |
566 } | 734 } |
567 | 735 |
568 bool BridgedNativeWidget::HasCapture() { | 736 bool BridgedNativeWidget::HasCapture() { |
569 return mouse_capture_ && mouse_capture_->IsActive(); | 737 return mouse_capture_ && mouse_capture_->IsActive(); |
570 } | 738 } |
571 | 739 |
| 740 Widget::MoveLoopResult BridgedNativeWidget::RunMoveLoop( |
| 741 const gfx::Vector2d& drag_offset) { |
| 742 DCHECK(!HasCapture()); |
| 743 DCHECK(!window_move_loop_); |
| 744 |
| 745 // First, position the window in the right place. The point |drag_offset| |
| 746 // away from the top-left corner needs to be positioned under the mouse. |
| 747 // TODO(tapted): Figure out why the toolkit-views drag controller doesn't get |
| 748 // this right when it first initializes the Widget. |
| 749 NSPoint mouse_in_screen = gfx::ScreenPointToNSPoint( |
| 750 gfx::Screen::GetScreen()->GetCursorScreenPoint()); |
| 751 NSRect frame = [window_ frame]; |
| 752 frame.origin.x = mouse_in_screen.x - drag_offset.x(); |
| 753 frame.origin.y = mouse_in_screen.y - NSHeight(frame) + drag_offset.y(); |
| 754 |
| 755 // After setting the frame to correct the initial offset, the drag controller |
| 756 // may immediately want to quit when it's notified of the new bounds. So the |
| 757 // MoveLoop must be set up before the call to setFrame. |
| 758 window_move_loop_.reset(new CocoaWindowMoveLoop(this)); |
| 759 |
| 760 // Animating may provide a less janky UX, but something custom would be |
| 761 // required so that it follows updates to the mouse position. |
| 762 [window_ setFrame:frame display:YES animate:NO]; |
| 763 |
| 764 // Setting the frame will call OnWidgetBoundsChanged(), which could result in |
| 765 // a call to EndMoveLoop(). |
| 766 if (!window_move_loop_) |
| 767 return Widget::MOVE_LOOP_SUCCESSFUL; |
| 768 |
| 769 return window_move_loop_->Run(); |
| 770 |
| 771 // |this| may be destroyed during the RunLoop, causing it to exit early. |
| 772 // Even if that doesn't happen, CocoaWindowMoveLoop will clean itself up by |
| 773 // calling EndMoveLoop(). So window_move_loop_ will always be null before the |
| 774 // function returns. But don't DCHECK since |this| might not be valid. |
| 775 } |
| 776 |
| 777 void BridgedNativeWidget::EndMoveLoop() { |
| 778 DCHECK(window_move_loop_); |
| 779 window_move_loop_->End(); |
| 780 window_move_loop_.reset(); |
| 781 } |
| 782 |
572 void BridgedNativeWidget::SetNativeWindowProperty(const char* name, | 783 void BridgedNativeWidget::SetNativeWindowProperty(const char* name, |
573 void* value) { | 784 void* value) { |
574 NSString* key = [NSString stringWithUTF8String:name]; | 785 NSString* key = [NSString stringWithUTF8String:name]; |
575 if (value) { | 786 if (value) { |
576 [GetWindowProperties() setObject:[NSValue valueWithPointer:value] | 787 [GetWindowProperties() setObject:[NSValue valueWithPointer:value] |
577 forKey:key]; | 788 forKey:key]; |
578 } else { | 789 } else { |
579 [GetWindowProperties() removeObjectForKey:key]; | 790 [GetWindowProperties() removeObjectForKey:key]; |
580 } | 791 } |
581 } | 792 } |
582 | 793 |
583 void* BridgedNativeWidget::GetNativeWindowProperty(const char* name) const { | 794 void* BridgedNativeWidget::GetNativeWindowProperty(const char* name) const { |
584 NSString* key = [NSString stringWithUTF8String:name]; | 795 NSString* key = [NSString stringWithUTF8String:name]; |
585 return [[GetWindowProperties() objectForKey:key] pointerValue]; | 796 return [[GetWindowProperties() objectForKey:key] pointerValue]; |
586 } | 797 } |
587 | 798 |
588 void BridgedNativeWidget::SetCursor(NSCursor* cursor) { | 799 void BridgedNativeWidget::SetCursor(NSCursor* cursor) { |
589 [window_delegate_ setCursor:cursor]; | 800 [window_delegate_ setCursor:cursor]; |
590 } | 801 } |
591 | 802 |
592 void BridgedNativeWidget::OnWindowWillClose() { | 803 void BridgedNativeWidget::OnWindowWillClose() { |
| 804 DCHECK(!drag_run_loop_); |
593 if (parent_) { | 805 if (parent_) { |
594 parent_->RemoveChildWindow(this); | 806 parent_->RemoveChildWindow(this); |
595 parent_ = nullptr; | 807 parent_ = nullptr; |
596 } | 808 } |
597 [window_ setDelegate:nil]; | 809 [window_ setDelegate:nil]; |
598 [[NSNotificationCenter defaultCenter] removeObserver:window_delegate_]; | 810 [[NSNotificationCenter defaultCenter] removeObserver:window_delegate_]; |
599 native_widget_mac_->OnWindowWillClose(); | 811 native_widget_mac_->OnWindowWillClose(); |
600 } | 812 } |
601 | 813 |
602 void BridgedNativeWidget::OnFullscreenTransitionStart( | 814 void BridgedNativeWidget::OnFullscreenTransitionStart( |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 | 897 |
686 // 10.9 is unable to generate a window shadow from the composited CALayer, so | 898 // 10.9 is unable to generate a window shadow from the composited CALayer, so |
687 // use Quartz. | 899 // use Quartz. |
688 // We don't update the window mask during a live resize, instead it is done | 900 // We don't update the window mask during a live resize, instead it is done |
689 // after the resize is completed in viewDidEndLiveResize: in | 901 // after the resize is completed in viewDidEndLiveResize: in |
690 // BridgedContentView. | 902 // BridgedContentView. |
691 if (base::mac::IsOSMavericksOrEarlier() && ![window_ inLiveResize]) | 903 if (base::mac::IsOSMavericksOrEarlier() && ![window_ inLiveResize]) |
692 [bridged_view_ updateWindowMask]; | 904 [bridged_view_ updateWindowMask]; |
693 } | 905 } |
694 | 906 |
| 907 void BridgedNativeWidget::OnPositionChanged() { |
| 908 native_widget_mac_->GetWidget()->OnNativeWidgetMove(); |
| 909 } |
| 910 |
695 void BridgedNativeWidget::OnVisibilityChanged() { | 911 void BridgedNativeWidget::OnVisibilityChanged() { |
696 OnVisibilityChangedTo([window_ isVisible]); | 912 OnVisibilityChangedTo([window_ isVisible]); |
697 } | 913 } |
698 | 914 |
699 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { | 915 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { |
700 if (window_visible_ == new_visibility) | 916 if (window_visible_ == new_visibility) |
701 return; | 917 return; |
702 | 918 |
703 window_visible_ = new_visibility; | 919 window_visible_ = new_visibility; |
704 | 920 |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 [bridged_view_ setMouseDownCanMoveWindow:draggable]; | 1454 [bridged_view_ setMouseDownCanMoveWindow:draggable]; |
1239 // AppKit will not update its cache of mouseDownCanMoveWindow unless something | 1455 // AppKit will not update its cache of mouseDownCanMoveWindow unless something |
1240 // changes. Previously we tried adding an NSView and removing it, but for some | 1456 // changes. Previously we tried adding an NSView and removing it, but for some |
1241 // reason it required reposting the mouse-down event, and didn't always work. | 1457 // reason it required reposting the mouse-down event, and didn't always work. |
1242 // Calling the below seems to be an effective solution. | 1458 // Calling the below seems to be an effective solution. |
1243 [window_ setMovableByWindowBackground:NO]; | 1459 [window_ setMovableByWindowBackground:NO]; |
1244 [window_ setMovableByWindowBackground:YES]; | 1460 [window_ setMovableByWindowBackground:YES]; |
1245 } | 1461 } |
1246 | 1462 |
1247 } // namespace views | 1463 } // namespace views |
OLD | NEW |