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

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

Issue 1259913003: MacViews: Implement Tab Dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20150529-ViewsBrowser-DisableCertificateDialog
Patch Set: update comments, still a TODO Created 5 years, 4 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
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/views_nswindow_delegate.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/run_loop.h"
10 #import "base/mac/foundation_util.h" 11 #import "base/mac/foundation_util.h"
11 #include "base/mac/mac_util.h" 12 #include "base/mac/mac_util.h"
12 #import "base/mac/sdk_forward_declarations.h" 13 #import "base/mac/sdk_forward_declarations.h"
13 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
14 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" 15 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
15 #include "ui/base/hit_test.h" 16 #include "ui/base/hit_test.h"
16 #include "ui/base/ime/input_method.h" 17 #include "ui/base/ime/input_method.h"
17 #include "ui/base/ime/input_method_factory.h" 18 #include "ui/base/ime/input_method_factory.h"
18 #include "ui/gfx/display.h" 19 #include "ui/gfx/display.h"
19 #include "ui/gfx/geometry/dip_util.h" 20 #include "ui/gfx/geometry/dip_util.h"
20 #import "ui/gfx/mac/coordinate_conversion.h" 21 #import "ui/gfx/mac/coordinate_conversion.h"
21 #import "ui/gfx/mac/nswindow_frame_controls.h" 22 #import "ui/gfx/mac/nswindow_frame_controls.h"
22 #include "ui/gfx/screen.h" 23 #include "ui/gfx/screen.h"
23 #import "ui/views/cocoa/bridged_content_view.h" 24 #import "ui/views/cocoa/bridged_content_view.h"
24 #import "ui/views/cocoa/cocoa_mouse_capture.h" 25 #import "ui/views/cocoa/cocoa_mouse_capture.h"
25 #include "ui/views/cocoa/tooltip_manager_mac.h" 26 #include "ui/views/cocoa/tooltip_manager_mac.h"
26 #import "ui/views/cocoa/views_nswindow_delegate.h" 27 #import "ui/views/cocoa/views_nswindow_delegate.h"
27 #import "ui/views/cocoa/widget_owner_nswindow_adapter.h" 28 #import "ui/views/cocoa/widget_owner_nswindow_adapter.h"
28 #include "ui/views/view.h" 29 #include "ui/views/view.h"
29 #include "ui/views/views_delegate.h" 30 #include "ui/views/views_delegate.h"
30 #include "ui/views/widget/native_widget_mac.h" 31 #include "ui/views/widget/native_widget_mac.h"
31 #include "ui/views/widget/widget.h" 32 #include "ui/views/widget/widget.h"
32 #include "ui/views/widget/widget_aura_utils.h" 33 #include "ui/views/widget/widget_aura_utils.h"
33 #include "ui/views/widget/widget_delegate.h" 34 #include "ui/views/widget/widget_delegate.h"
34 35
36 #include "base/debug/stack_trace.h"
37
35 // The NSView that hosts the composited CALayer drawing the UI. It fills the 38 // The NSView that hosts the composited CALayer drawing the UI. It fills the
36 // window but is not hittable so that accessibility hit tests always go to the 39 // window but is not hittable so that accessibility hit tests always go to the
37 // BridgedContentView. 40 // BridgedContentView.
38 @interface ViewsCompositorSuperview : NSView 41 @interface ViewsCompositorSuperview : NSView
39 @end 42 @end
40 43
41 @implementation ViewsCompositorSuperview 44 @implementation ViewsCompositorSuperview
42 - (NSView*)hitTest:(NSPoint)aPoint { 45 - (NSView*)hitTest:(NSPoint)aPoint {
43 return nil; 46 return nil;
44 } 47 }
(...skipping 20 matching lines...) Expand all
65 - (void)setCurrentProgress:(NSAnimationProgress)progress { 68 - (void)setCurrentProgress:(NSAnimationProgress)progress {
66 [super setCurrentProgress:progress]; 69 [super setCurrentProgress:progress];
67 [window_ invalidateShadow]; 70 [window_ invalidateShadow];
68 } 71 }
69 @end 72 @end
70 73
71 namespace { 74 namespace {
72 75
73 int kWindowPropertiesKey; 76 int kWindowPropertiesKey;
74 77
78 bool g_ignore_next_mouse_down_for_draggable_regions = false;
79
75 float GetDeviceScaleFactorFromView(NSView* view) { 80 float GetDeviceScaleFactorFromView(NSView* view) {
76 gfx::Display display = 81 gfx::Display display =
77 gfx::Screen::GetScreenFor(view)->GetDisplayNearestWindow(view); 82 gfx::Screen::GetScreenFor(view)->GetDisplayNearestWindow(view);
78 DCHECK(display.is_valid()); 83 DCHECK(display.is_valid());
79 return display.device_scale_factor(); 84 return display.device_scale_factor();
80 } 85 }
81 86
82 // Returns true if bounds passed to window in SetBounds should be treated as 87 // Returns true if bounds passed to window in SetBounds should be treated as
83 // though they are in screen coordinates. 88 // though they are in screen coordinates.
84 bool PositionWindowInScreenCoordinates(views::Widget* widget, 89 bool PositionWindowInScreenCoordinates(views::Widget* widget,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 NSInteger event_number = [ns_event eventNumber]; 137 NSInteger event_number = [ns_event eventNumber];
133 138
134 // The logic here is a bit convoluted because we want to mitigate race 139 // The logic here is a bit convoluted because we want to mitigate race
135 // conditions if somehow a different mouse-down occurs between reposts. 140 // conditions if somehow a different mouse-down occurs between reposts.
136 // Specifically, we want to avoid: 141 // Specifically, we want to avoid:
137 // - BridgedNativeWidget's draggability getting out of sync (e.g. if it is 142 // - BridgedNativeWidget's draggability getting out of sync (e.g. if it is
138 // draggable outside of a repost cycle), 143 // draggable outside of a repost cycle),
139 // - any repost loop. 144 // - any repost loop.
140 145
141 if (repost_state == NONE) { 146 if (repost_state == NONE) {
147 if (g_ignore_next_mouse_down_for_draggable_regions) {
148 g_ignore_next_mouse_down_for_draggable_regions = false;
149 return ns_event;
150 }
151
142 if (WindowWantsMouseDownReposted(ns_event)) { 152 if (WindowWantsMouseDownReposted(ns_event)) {
143 repost_state = EXPECTING_REPOST; 153 repost_state = EXPECTING_REPOST;
144 reposted_event_number = event_number; 154 reposted_event_number = event_number;
155 DLOG(INFO) << "Reposting event for window drag";
145 CGEventPost(kCGSessionEventTap, [ns_event CGEvent]); 156 CGEventPost(kCGSessionEventTap, [ns_event CGEvent]);
146 return nil; 157 return nil;
147 } 158 }
148 159
149 return ns_event; 160 return ns_event;
150 } 161 }
151 162
152 if (repost_state == EXPECTING_REPOST) { 163 if (repost_state == EXPECTING_REPOST) {
153 // Call through so that the window is made non-draggable again. 164 // Call through so that the window is made non-draggable again.
154 WindowWantsMouseDownReposted(ns_event); 165 WindowWantsMouseDownReposted(ns_event);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 if (monitor) 203 if (monitor)
193 return; 204 return;
194 205
195 monitor = [NSEvent 206 monitor = [NSEvent
196 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask 207 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask
197 handler:^NSEvent*(NSEvent* ns_event) { 208 handler:^NSEvent*(NSEvent* ns_event) {
198 return RepostEventIfHandledByWindow(ns_event); 209 return RepostEventIfHandledByWindow(ns_event);
199 }]; 210 }];
200 } 211 }
201 212
213 CGPoint GetCGMousePosition() {
214 return CGEventGetLocation(
215 base::ScopedCFTypeRef<CGEventRef>(CGEventCreate(nullptr)));
216 }
217
218 void SendCustomLeftMouseEvent(CGEventType type) {
219 base::ScopedCFTypeRef<CGEventRef> event(
220 CGEventCreateMouseEvent(
221 nullptr, type, GetCGMousePosition(),
222 kCGMouseButtonLeft));
223 CGEventSetIntegerValueField(event, kCGEventSourceUserData, 1);
224 CGEventPost(kCGSessionEventTap, event);
225 }
226
202 } // namespace 227 } // namespace
203 228
204 namespace views { 229 namespace views {
205 230
231 class CocoaWindowMoveLoop {
232 public:
233 explicit CocoaWindowMoveLoop(BridgedNativeWidget* owner)
234 : owner_(owner),
235 run_loop_(new base::RunLoop),
236 quit_closure_(run_loop_->QuitClosure()) {
237 // AppKit continues to send mouse events to the window, but toolkit-views
238 // goes berserk if it gets them during RunMoveLoop().
239 [owner_->ns_view() setIgnoreMouseEvents:YES];
240 owner_->SetDraggable(true);
241 }
242
243 ~CocoaWindowMoveLoop() {
244 owner_->SetDraggable(false);
245 // Note the crafted events in Run() should not make their way through to
246 // toolkit-views, but regular events after that should be. So stop ignoring.
247 [owner_->ns_view() setIgnoreMouseEvents:NO];
248
249 // Handle the pathological case, where |this| is destroyed while running.
250 if (exit_reason_ref_) {
251 *exit_reason_ref_ = WINDOW_DESTROYED;
252 quit_closure_.Run();
253 }
254
255 // Handle Run() never being called.
256 if (monitor_) {
257 [NSEvent removeMonitor:monitor_];
258 monitor_ = nil;
259 }
260 owner_ = nullptr;
261 }
262
263 Widget::MoveLoopResult Run() {
264 LoopExitReason exit_reason = ENDED_EXTERNALLY;
265 exit_reason_ref_ = &exit_reason;
266
267 // Move the RunLoop to the stack so our destructor can be called while it is
268 // running.
269 scoped_ptr<base::RunLoop> run_loop(run_loop_.Pass());
270
271 // A new window may have just been created, so post an event at the session
272 // tap level to initiate a window drag.
273 // TODO(tapted): Move this "inside" the window or stuff breaks when dragging
274 // the last tab/s off a browser.
275 SendCustomLeftMouseEvent(kCGEventLeftMouseDown);
276
277 NSEventMask mask = NSLeftMouseUpMask | NSKeyDownMask | NSLeftMouseDraggedMas k;
278 monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:mask
279 handler:^NSEvent*(NSEvent* event) {
280 DLOG(INFO) << "Saw a thing: " << this;
281 if ([event type] == NSLeftMouseDragged) {
282 DLOG(INFO) << "drag";
283 // AppKit doesn't supply position updates during a drag, so post a
284 // task to notify observers once AppKit has moved the window.
285 base::MessageLoop::current()->PostTask(FROM_HERE,
286 base::Bind(&BridgedNativeWidg et::OnPositionChanged,
287 base::Unretained(o wner_)));
288 return event;
289 }
290 DLOG(INFO) << "Quitting due to event in " << this;
291 quit_closure_.Run();
292 if ([event type] == NSLeftMouseUp) {
293 DLOG(INFO) << "mouseup";
294 *exit_reason_ref_ = MOUSE_UP;
295 return event; // Process the MouseUp.
296 }
297 *exit_reason_ref_ = ESCAPE_PRESSED;
298 DLOG(INFO) << "key";
299 return nil; // Swallow the keypress.
300 }];
301
302 // NSKeyDownMask doesn't work inside addLocalMonitorForEventsMatchingMask: t he
303 // event is swallowed by the window move loop before it gets to -[NSApp
304 // sendEvent:]. To see an escape keypress, hook in an event tap lower.
305
306 run_loop->Run();
307
308 if (exit_reason != WINDOW_DESTROYED && exit_reason != ENDED_EXTERNALLY) {
309 exit_reason_ref_ = nullptr; // Ensure End() doesn't replace the reason.
310 DLOG(INFO) << "Calling own EndMoveLoop in " << this;
311 owner_->EndMoveLoop(); // Deletes |this|.
312 }
313
314 if (exit_reason != MOUSE_UP) {
315 // Tell AppKit to stop moving the window. Otherwise, AppKit will refuse to
316 // start a new window drag. Note the window being dragged is going away in
317 // this case, so it doesn't really matter where the event is located.
318 SendCustomLeftMouseEvent(kCGEventLeftMouseUp);
319
320 if (exit_reason == ENDED_EXTERNALLY) {
321 // When not canceled, the non-moving drag in the original window must
322 // resume. To do this, AppKit needs to see a mouseDown so that it sends
323 // the correct events. Ideally, it also needs to be at the original
324 // offset, so that it hits a non-draggable region of the original window :
325 // The tab being dragged may move some distance from the cursor when it
326 // "snaps in", so the cursor may not be over a tab. Sadly, this method
327 // doesn't know which window that is. But all that really needs to be
328 // done is to prevent a custom-dragging area from starting a window-drag .
329 // So hook into the logic in RepostEventIfHandledByWindow() by setting a
330 // flag here. Note this assumes the custom mouseDown event is guaranteed
331 // to hit another BridgedNativeWidget when it gets to the front of the
332 // event queue.
333 // TODO(tapted): A better fix would be to keep the temporary window
334 // around and never call EndMoveLoop() on Mac, making this block of code
335 // obsolete.
336 g_ignore_next_mouse_down_for_draggable_regions = true;
337 SendCustomLeftMouseEvent(kCGEventLeftMouseDown);
338 }
339 }
340
341 return exit_reason == ESCAPE_PRESSED
342 ? Widget::MOVE_LOOP_CANCELED : Widget::MOVE_LOOP_SUCCESSFUL;
343 }
344
345 void End() {
346 DLOG(INFO) << "In End() for " << this << " reason_ref = " << exit_reason_ref _;
347 if (exit_reason_ref_) {
348 DCHECK_EQ(*exit_reason_ref_, ENDED_EXTERNALLY);
349 // Ensure the destructor doesn't replace the reason.
350 exit_reason_ref_ = nullptr;
351 quit_closure_.Run();
352 }
353 }
354
355 static CGEventRef EscapeKeypressMonitor(CGEventTapProxy proxy,
356 CGEventType type,
357 CGEventRef event,
358 void* refcon) {
359 CocoaWindowMoveLoop* self = static_cast<CocoaWindowMoveLoop*>(refcon);
360 (void)self;
361 return event;
362 }
363
364 private:
365 enum LoopExitReason {
366 ENDED_EXTERNALLY,
367 ESCAPE_PRESSED,
368 MOUSE_UP,
369 WINDOW_DESTROYED,
370 };
371
372 BridgedNativeWidget* owner_; // Weak. Owns this.
373 scoped_ptr<base::RunLoop> run_loop_;
374 id monitor_ = nil;
375
376 // Pointer to a stack variable holding the exit reason.
377 LoopExitReason* exit_reason_ref_ = nullptr;
378 base::Closure quit_closure_;
379
380 DISALLOW_COPY_AND_ASSIGN(CocoaWindowMoveLoop);
381 };
382
206 // static 383 // static
207 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize( 384 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize(
208 NSWindow* window, 385 NSWindow* window,
209 const gfx::Size& content_size) { 386 const gfx::Size& content_size) {
210 NSRect content_rect = 387 NSRect content_rect =
211 NSMakeRect(0, 0, content_size.width(), content_size.height()); 388 NSMakeRect(0, 0, content_size.width(), content_size.height());
212 NSRect frame_rect = [window frameRectForContentRect:content_rect]; 389 NSRect frame_rect = [window frameRectForContentRect:content_rect];
213 return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect)); 390 return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect));
214 } 391 }
215 392
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 display:YES 562 display:YES
386 animate:NO]; 563 animate:NO];
387 } 564 }
388 565
389 void BridgedNativeWidget::SetRootView(views::View* view) { 566 void BridgedNativeWidget::SetRootView(views::View* view) {
390 if (view == [bridged_view_ hostedView]) 567 if (view == [bridged_view_ hostedView])
391 return; 568 return;
392 569
393 // If this is ever false, the compositor will need to be properly torn down 570 // If this is ever false, the compositor will need to be properly torn down
394 // and replaced, pointing at the new view. 571 // and replaced, pointing at the new view.
572 if (view && compositor_widget_) {
573 DLOG(INFO) << "Gonna die: view=" << view << " compositor_widget=" << composi tor_widget_;
574 }
395 DCHECK(!view || !compositor_widget_); 575 DCHECK(!view || !compositor_widget_);
396 576
397 [bridged_view_ clearView]; 577 [bridged_view_ clearView];
398 bridged_view_.reset(); 578 bridged_view_.reset();
399 // Note that there can still be references to the old |bridged_view_| 579 // Note that there can still be references to the old |bridged_view_|
400 // floating around in Cocoa libraries at this point. However, references to 580 // floating around in Cocoa libraries at this point. However, references to
401 // the old views::View will be gone, so any method calls will become no-ops. 581 // the old views::View will be gone, so any method calls will become no-ops.
402 582
403 if (view) { 583 if (view) {
404 bridged_view_.reset([[BridgedContentView alloc] initWithView:view]); 584 bridged_view_.reset([[BridgedContentView alloc] initWithView:view]);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 // hasn't yet received a frame from the compositor at this stage, so it is 647 // hasn't yet received a frame from the compositor at this stage, so it is
468 // fully transparent until the GPU sends a frame swap IPC. For the blocking 648 // fully transparent until the GPU sends a frame swap IPC. For the blocking
469 // option, the animation needs to wait until AcceleratedWidgetSwapCompleted 649 // option, the animation needs to wait until AcceleratedWidgetSwapCompleted
470 // has been called at least once, otherwise it will animate nothing. 650 // has been called at least once, otherwise it will animate nothing.
471 [show_animation setAnimationBlockingMode:NSAnimationNonblocking]; 651 [show_animation setAnimationBlockingMode:NSAnimationNonblocking];
472 [show_animation startAnimation]; 652 [show_animation startAnimation];
473 } 653 }
474 } 654 }
475 655
476 void BridgedNativeWidget::AcquireCapture() { 656 void BridgedNativeWidget::AcquireCapture() {
657 base::debug::StackTrace().Print();
658 DLOG(INFO) << "AcquireCapture: " << this;
477 DCHECK(!HasCapture()); 659 DCHECK(!HasCapture());
478 if (!window_visible_) 660 if (!window_visible_)
479 return; // Capture on hidden windows is disallowed. 661 return; // Capture on hidden windows is disallowed.
480 662
481 mouse_capture_.reset(new CocoaMouseCapture(this)); 663 mouse_capture_.reset(new CocoaMouseCapture(this));
482 664
483 // Initiating global event capture with addGlobalMonitorForEventsMatchingMask: 665 // Initiating global event capture with addGlobalMonitorForEventsMatchingMask:
484 // will reset the mouse cursor to an arrow. Asking the window for an update 666 // will reset the mouse cursor to an arrow. Asking the window for an update
485 // here will restore what we want. However, it can sometimes cause the cursor 667 // here will restore what we want. However, it can sometimes cause the cursor
486 // to flicker, once, on the initial mouseDown. 668 // to flicker, once, on the initial mouseDown.
487 // TOOD(tapted): Make this unnecessary by only asking for global mouse capture 669 // TOOD(tapted): Make this unnecessary by only asking for global mouse capture
488 // for the cases that need it (e.g. menus, but not drag and drop). 670 // for the cases that need it (e.g. menus, but not drag and drop).
489 [window_ cursorUpdate:[NSApp currentEvent]]; 671 [window_ cursorUpdate:[NSApp currentEvent]];
490 } 672 }
491 673
492 void BridgedNativeWidget::ReleaseCapture() { 674 void BridgedNativeWidget::ReleaseCapture() {
675 base::debug::StackTrace().Print();
676 DLOG(INFO) << "ReleaseCapture: " << this << " drag_loop=" << drag_run_loop_;
493 mouse_capture_.reset(); 677 mouse_capture_.reset();
678 //if (drag_run_loop_) {
679 // drag_run_loop_->Quit();
680 // drag_run_loop_ = nullptr;
681 //}
494 } 682 }
495 683
496 bool BridgedNativeWidget::HasCapture() { 684 bool BridgedNativeWidget::HasCapture() {
497 return mouse_capture_ && mouse_capture_->IsActive(); 685 return mouse_capture_ && mouse_capture_->IsActive();
498 } 686 }
499 687
688 Widget::MoveLoopResult BridgedNativeWidget::RunMoveLoop(
689 const gfx::Vector2d& drag_offset) {
690 base::debug::StackTrace().Print();
691 DLOG(INFO) << "RunMoveLoop(): " << this << " drag_loop=" << drag_run_loop_;
692
693 DCHECK(!HasCapture());
694 DCHECK(!window_move_loop_);
695
696 // First, position the window in the right place. The point |drag_offset|
697 // away from the top-left corner needs to be positioned under the mouse.
698 // TODO(tapted): Figure out why the toolkit-views drag controller doesn't get
699 // this right when it first initializes the Widget.
700 NSPoint mouse_in_screen = [NSEvent mouseLocation];
701 NSRect frame = [window_ frame];
702 frame.origin.x = mouse_in_screen.x - drag_offset.x();
703 frame.origin.y = mouse_in_screen.y - NSHeight(frame) + drag_offset.y();
704 NSLog(@"mouse, frame, offset -> frame: %@, %@, %s, %@",
705 NSStringFromRect([window_ frame]),
706 NSStringFromPoint(mouse_in_screen),
707 drag_offset.ToString().c_str(),
708 NSStringFromRect(frame));
709
710 // After setting the frame to correct the initial offset, the drag controller
711 // may immediately want to quit when it's notified of the new bounds. So the
712 // MoveLoop must be set up before the call to setFrame.
713 window_move_loop_.reset(new CocoaWindowMoveLoop(this));
714
715 // Animating may provide a less janky UX, but something custom would be
716 // required so that it follows updates to the mouse position.
717 [window_ setFrame:frame display:YES animate:NO];
718
719 // Setting the frame will call OnWidgetBoundsChanged(), which could result in
720 // a call to EndMoveLoop().
721 if (!window_move_loop_)
722 return Widget::MOVE_LOOP_SUCCESSFUL;
723
724 return window_move_loop_->Run();
725
726 // |this| may be destroyed during the RunLoop, causing it to exit early.
727 // Even if that doesn't happen, CocoaWindowMoveLoop will clean itself up by
728 // calling EndMoveLoop(). So window_move_loop_ will always be null before the
729 // function returns. But don't DCHECK since |this| might not be valid.
730 }
731
732 void BridgedNativeWidget::EndMoveLoop() {
733 DCHECK(window_move_loop_);
734 DLOG(INFO) << "Quitting due to EndMoveLoop for " << window_move_loop_.get();
735 window_move_loop_->End();
736 DLOG(INFO) << "Resetting: " << window_move_loop_.get();
737 window_move_loop_.reset();
738 }
739
500 void BridgedNativeWidget::SetNativeWindowProperty(const char* name, 740 void BridgedNativeWidget::SetNativeWindowProperty(const char* name,
501 void* value) { 741 void* value) {
502 NSString* key = [NSString stringWithUTF8String:name]; 742 NSString* key = [NSString stringWithUTF8String:name];
503 if (value) { 743 if (value) {
504 [GetWindowProperties() setObject:[NSValue valueWithPointer:value] 744 [GetWindowProperties() setObject:[NSValue valueWithPointer:value]
505 forKey:key]; 745 forKey:key];
506 } else { 746 } else {
507 [GetWindowProperties() removeObjectForKey:key]; 747 [GetWindowProperties() removeObjectForKey:key];
508 } 748 }
509 } 749 }
510 750
511 void* BridgedNativeWidget::GetNativeWindowProperty(const char* name) const { 751 void* BridgedNativeWidget::GetNativeWindowProperty(const char* name) const {
512 NSString* key = [NSString stringWithUTF8String:name]; 752 NSString* key = [NSString stringWithUTF8String:name];
513 return [[GetWindowProperties() objectForKey:key] pointerValue]; 753 return [[GetWindowProperties() objectForKey:key] pointerValue];
514 } 754 }
515 755
516 void BridgedNativeWidget::SetCursor(NSCursor* cursor) { 756 void BridgedNativeWidget::SetCursor(NSCursor* cursor) {
517 [window_delegate_ setCursor:cursor]; 757 [window_delegate_ setCursor:cursor];
518 } 758 }
519 759
520 void BridgedNativeWidget::OnWindowWillClose() { 760 void BridgedNativeWidget::OnWindowWillClose() {
761 DCHECK(!drag_run_loop_);
521 if (parent_) { 762 if (parent_) {
522 parent_->RemoveChildWindow(this); 763 parent_->RemoveChildWindow(this);
523 parent_ = nullptr; 764 parent_ = nullptr;
524 } 765 }
525 [window_ setDelegate:nil]; 766 [window_ setDelegate:nil];
526 [[NSNotificationCenter defaultCenter] removeObserver:window_delegate_]; 767 [[NSNotificationCenter defaultCenter] removeObserver:window_delegate_];
527 native_widget_mac_->OnWindowWillClose(); 768 native_widget_mac_->OnWindowWillClose();
528 } 769 }
529 770
530 void BridgedNativeWidget::OnFullscreenTransitionStart( 771 void BridgedNativeWidget::OnFullscreenTransitionStart(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 [window_ toggleFullScreen:nil]; 843 [window_ toggleFullScreen:nil];
603 } 844 }
604 845
605 void BridgedNativeWidget::OnSizeChanged() { 846 void BridgedNativeWidget::OnSizeChanged() {
606 gfx::Size new_size = GetClientAreaSize(); 847 gfx::Size new_size = GetClientAreaSize();
607 native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(new_size); 848 native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(new_size);
608 if (layer()) 849 if (layer())
609 UpdateLayerProperties(); 850 UpdateLayerProperties();
610 } 851 }
611 852
853 void BridgedNativeWidget::OnPositionChanged() {
854 native_widget_mac_->GetWidget()->OnNativeWidgetMove();
855 }
856
612 void BridgedNativeWidget::OnVisibilityChanged() { 857 void BridgedNativeWidget::OnVisibilityChanged() {
613 OnVisibilityChangedTo([window_ isVisible]); 858 OnVisibilityChangedTo([window_ isVisible]);
614 } 859 }
615 860
616 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { 861 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) {
617 if (window_visible_ == new_visibility) 862 if (window_visible_ == new_visibility)
618 return; 863 return;
619 864
620 window_visible_ = new_visibility; 865 window_visible_ = new_visibility;
621 866
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 [bridged_view_ setMouseDownCanMoveWindow:draggable]; 1327 [bridged_view_ setMouseDownCanMoveWindow:draggable];
1083 // AppKit will not update its cache of mouseDownCanMoveWindow unless something 1328 // AppKit will not update its cache of mouseDownCanMoveWindow unless something
1084 // changes. Previously we tried adding an NSView and removing it, but for some 1329 // changes. Previously we tried adding an NSView and removing it, but for some
1085 // reason it required reposting the mouse-down event, and didn't always work. 1330 // reason it required reposting the mouse-down event, and didn't always work.
1086 // Calling the below seems to be an effective solution. 1331 // Calling the below seems to be an effective solution.
1087 [window_ setMovableByWindowBackground:NO]; 1332 [window_ setMovableByWindowBackground:NO];
1088 [window_ setMovableByWindowBackground:YES]; 1333 [window_ setMovableByWindowBackground:YES];
1089 } 1334 }
1090 1335
1091 } // namespace views 1336 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/views_nswindow_delegate.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698