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

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

Issue 2629593005: MacViews: Support -[NSWindow close] on sheets. (Closed)
Patch Set: no doNothing Created 3 years, 11 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 | « no previous file | ui/views/cocoa/widget_owner_nswindow_adapter.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/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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | ui/views/cocoa/widget_owner_nswindow_adapter.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698