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

Side by Side Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 1747803003: MacViews: Implement Tab Dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed debug logging, use CGEvents for drag-n-drop. Created 4 years, 9 months 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698