| 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/views_nswindow_delegate.h" | 5 #import "ui/views/cocoa/views_nswindow_delegate.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #import "base/mac/bind_objc_block.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" |
| 8 #import "ui/views/cocoa/bridged_content_view.h" | 10 #import "ui/views/cocoa/bridged_content_view.h" |
| 9 #import "ui/views/cocoa/bridged_native_widget.h" | 11 #import "ui/views/cocoa/bridged_native_widget.h" |
| 10 #include "ui/views/widget/native_widget_mac.h" | 12 #include "ui/views/widget/native_widget_mac.h" |
| 11 | 13 |
| 12 @implementation ViewsNSWindowDelegate | 14 @implementation ViewsNSWindowDelegate |
| 13 | 15 |
| 14 - (id)initWithBridgedNativeWidget:(views::BridgedNativeWidget*)parent { | 16 - (id)initWithBridgedNativeWidget:(views::BridgedNativeWidget*)parent { |
| 15 DCHECK(parent); | 17 DCHECK(parent); |
| 16 if ((self = [super init])) { | 18 if ((self = [super init])) { |
| 17 parent_ = parent; | 19 parent_ = parent; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 39 parent_->OnVisibilityChanged(); | 41 parent_->OnVisibilityChanged(); |
| 40 } | 42 } |
| 41 | 43 |
| 42 - (void)onSystemControlTintChanged:(NSNotification*)notification { | 44 - (void)onSystemControlTintChanged:(NSNotification*)notification { |
| 43 parent_->OnSystemControlTintChanged(); | 45 parent_->OnSystemControlTintChanged(); |
| 44 } | 46 } |
| 45 | 47 |
| 46 - (void)sheetDidEnd:(NSWindow*)sheet | 48 - (void)sheetDidEnd:(NSWindow*)sheet |
| 47 returnCode:(NSInteger)returnCode | 49 returnCode:(NSInteger)returnCode |
| 48 contextInfo:(void*)contextInfo { | 50 contextInfo:(void*)contextInfo { |
| 51 // |parent_| will be null when triggered from the block in -windowWillClose:. |
| 52 if (!parent_) |
| 53 return; |
| 54 |
| 49 [sheet orderOut:nil]; | 55 [sheet orderOut:nil]; |
| 50 parent_->OnWindowWillClose(); | 56 parent_->OnWindowWillClose(); |
| 51 } | 57 } |
| 52 | 58 |
| 53 // NSWindowDelegate implementation. | 59 // NSWindowDelegate implementation. |
| 54 | 60 |
| 55 - (void)windowDidFailToEnterFullScreen:(NSWindow*)window { | 61 - (void)windowDidFailToEnterFullScreen:(NSWindow*)window { |
| 56 // Cocoa should already have sent an (unexpected) windowDidExitFullScreen: | 62 // Cocoa should already have sent an (unexpected) windowDidExitFullScreen: |
| 57 // notification, and the attempt to get back into fullscreen should fail. | 63 // notification, and the attempt to get back into fullscreen should fail. |
| 58 // Nothing to do except verify |parent_| is no longer trying to fullscreen. | 64 // Nothing to do except verify |parent_| is no longer trying to fullscreen. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 80 | 86 |
| 81 - (void)windowDidBecomeKey:(NSNotification*)notification { | 87 - (void)windowDidBecomeKey:(NSNotification*)notification { |
| 82 parent_->OnWindowKeyStatusChangedTo(true); | 88 parent_->OnWindowKeyStatusChangedTo(true); |
| 83 } | 89 } |
| 84 | 90 |
| 85 - (void)windowDidResignKey:(NSNotification*)notification { | 91 - (void)windowDidResignKey:(NSNotification*)notification { |
| 86 parent_->OnWindowKeyStatusChangedTo(false); | 92 parent_->OnWindowKeyStatusChangedTo(false); |
| 87 } | 93 } |
| 88 | 94 |
| 89 - (void)windowWillClose:(NSNotification*)notification { | 95 - (void)windowWillClose:(NSNotification*)notification { |
| 90 DCHECK([parent_->ns_window() isEqual:[notification object]]); | 96 // Retain |self|. |parent_| should be cleared. OnWindowWillClose() may delete |
| 97 // |parent_|, but it may also dealloc |self| before returning. However, the |
| 98 // observers it notifies before that need a valid |parent_| on the delegate, |
| 99 // so it can only be cleared after OnWindowWillClose() returns. |
| 100 base::scoped_nsobject<NSObject> keepAlive(self, base::scoped_policy::RETAIN); |
| 101 NSWindow* window = parent_->ns_window(); |
| 102 if (NSWindow* sheetParent = [window sheetParent]) { |
| 103 // On no! Something called -[NSWindow close] on a sheet rather than calling |
| 104 // -[NSWindow endSheet:] on its parent. If the modal session is not ended |
| 105 // then the parent will never be able to show another sheet. But calling |
| 106 // -endSheet: here will block the thread with an animation, so post a task. |
| 107 // Use a block: The argument to -endSheet: must be retained, since it's the |
| 108 // window that is closing and -performSelector: won't retain the argument. |
| 109 // The NSWindowDelegate (i.e. |self|) must also be explicitly retained. Even |
| 110 // though the call to OnWindowWillClose() below will remove |self| as the |
| 111 // NSWindow delegate, the call to -[NSApp beginSheet:] also took a weak |
| 112 // reference to the delegate, which will be destroyed when the sheet's |
| 113 // BridgedNativeWidget is destroyed. |
| 114 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::BindBlock(^{ |
| 115 [sheetParent endSheet:window]; |
| 116 [[self retain] release]; // Force |self| to be retained for the block. |
| 117 })); |
| 118 } |
| 119 DCHECK([window isEqual:[notification object]]); |
| 91 parent_->OnWindowWillClose(); | 120 parent_->OnWindowWillClose(); |
| 121 parent_ = nullptr; |
| 92 } | 122 } |
| 93 | 123 |
| 94 - (void)windowDidMiniaturize:(NSNotification*)notification { | 124 - (void)windowDidMiniaturize:(NSNotification*)notification { |
| 95 parent_->OnVisibilityChanged(); | 125 parent_->OnVisibilityChanged(); |
| 96 } | 126 } |
| 97 | 127 |
| 98 - (void)windowDidDeminiaturize:(NSNotification*)notification { | 128 - (void)windowDidDeminiaturize:(NSNotification*)notification { |
| 99 parent_->OnVisibilityChanged(); | 129 parent_->OnVisibilityChanged(); |
| 100 } | 130 } |
| 101 | 131 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 usingRect:(NSRect)defaultSheetLocation { | 165 usingRect:(NSRect)defaultSheetLocation { |
| 136 // As per NSWindowDelegate documentation, the origin indicates the top left | 166 // As per NSWindowDelegate documentation, the origin indicates the top left |
| 137 // point of the host frame in window coordinates. The width changes the | 167 // point of the host frame in window coordinates. The width changes the |
| 138 // animation from vertical to trapezoid if it is smaller than the width of the | 168 // animation from vertical to trapezoid if it is smaller than the width of the |
| 139 // dialog. The height is ignored but should be set to zero. | 169 // dialog. The height is ignored but should be set to zero. |
| 140 return NSMakeRect(0, [self nativeWidgetMac]->SheetPositionY(), | 170 return NSMakeRect(0, [self nativeWidgetMac]->SheetPositionY(), |
| 141 NSWidth(defaultSheetLocation), 0); | 171 NSWidth(defaultSheetLocation), 0); |
| 142 } | 172 } |
| 143 | 173 |
| 144 @end | 174 @end |
| OLD | NEW |