OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "chrome/browser/ui/cocoa/notifications/balloon_controller.h" | 5 #include "chrome/browser/ui/cocoa/notifications/balloon_controller.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/mac/nsimage_cache.h" | 8 #include "app/mac/nsimage_cache.h" |
9 #import "base/mac/cocoa_protocols.h" | 9 #import "base/mac/cocoa_protocols.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 114 } |
115 | 115 |
116 - (void) mouseEntered:(NSEvent*)event { | 116 - (void) mouseEntered:(NSEvent*)event { |
117 [[closeButton_ cell] setHighlighted:YES]; | 117 [[closeButton_ cell] setHighlighted:YES]; |
118 } | 118 } |
119 | 119 |
120 - (void) mouseExited:(NSEvent*)event { | 120 - (void) mouseExited:(NSEvent*)event { |
121 [[closeButton_ cell] setHighlighted:NO]; | 121 [[closeButton_ cell] setHighlighted:NO]; |
122 } | 122 } |
123 | 123 |
| 124 - (void)closeBalloonNow:(bool)byUser { |
| 125 if (!balloon_) |
| 126 return; |
| 127 [self close]; |
| 128 if (htmlContents_.get()) |
| 129 htmlContents_->Shutdown(); |
| 130 if (balloon_) |
| 131 balloon_->OnClose(byUser); |
| 132 balloon_ = NULL; |
| 133 } |
| 134 |
124 - (IBAction)optionsButtonPressed:(id)sender { | 135 - (IBAction)optionsButtonPressed:(id)sender { |
| 136 optionMenuIsActive_ = YES; |
125 [NSMenu popUpContextMenu:[menuController_ menu] | 137 [NSMenu popUpContextMenu:[menuController_ menu] |
126 withEvent:[NSApp currentEvent] | 138 withEvent:[NSApp currentEvent] |
127 forView:optionsButton_]; | 139 forView:optionsButton_]; |
| 140 optionMenuIsActive_ = NO; |
| 141 if (delayedClose_) |
| 142 [self closeBalloonNow: false]; // always by script. |
128 } | 143 } |
129 | 144 |
130 - (IBAction)permissionRevoked:(id)sender { | 145 - (IBAction)permissionRevoked:(id)sender { |
131 DesktopNotificationService* service = | 146 DesktopNotificationService* service = |
132 balloon_->profile()->GetDesktopNotificationService(); | 147 balloon_->profile()->GetDesktopNotificationService(); |
133 service->DenyPermission(balloon_->notification().origin_url()); | 148 service->DenyPermission(balloon_->notification().origin_url()); |
134 } | 149 } |
135 | 150 |
136 - (IBAction)closeButtonPressed:(id)sender { | 151 - (IBAction)closeButtonPressed:(id)sender { |
137 [self closeBalloon:YES]; | 152 [self closeBalloon:YES]; |
138 [self close]; | 153 [self close]; |
139 } | 154 } |
140 | 155 |
141 - (void)close { | 156 - (void)close { |
142 if (closeButtonTrackingTag_) | 157 if (closeButtonTrackingTag_) |
143 [shelf_ removeTrackingRect:closeButtonTrackingTag_]; | 158 [shelf_ removeTrackingRect:closeButtonTrackingTag_]; |
144 | 159 |
145 [super close]; | 160 [super close]; |
146 } | 161 } |
147 | 162 |
148 - (void)closeBalloon:(bool)byUser { | 163 - (void)closeBalloon:(bool)byUser { |
149 if (!balloon_) | 164 // Keep alive while user is interacting with popup menu. |
| 165 // Otherwise the script can close the notification and underlying balloon |
| 166 // will be destroyed while user select a menu command. |
| 167 if (!byUser && optionMenuIsActive_) { |
| 168 delayedClose_ = YES; |
150 return; | 169 return; |
151 [self close]; | 170 } |
152 if (htmlContents_.get()) | 171 [self closeBalloonNow: byUser]; |
153 htmlContents_->Shutdown(); | |
154 if (balloon_) | |
155 balloon_->OnClose(byUser); | |
156 balloon_ = NULL; | |
157 } | 172 } |
158 | 173 |
159 - (void)updateContents { | 174 - (void)updateContents { |
160 DCHECK(htmlContents_.get()) << "BalloonView::Update called before Show"; | 175 DCHECK(htmlContents_.get()) << "BalloonView::Update called before Show"; |
161 if (htmlContents_->render_view_host()) | 176 if (htmlContents_->render_view_host()) |
162 htmlContents_->render_view_host()->NavigateToURL( | 177 htmlContents_->render_view_host()->NavigateToURL( |
163 balloon_->notification().content_url()); | 178 balloon_->notification().content_url()); |
164 } | 179 } |
165 | 180 |
166 - (void)repositionToBalloon { | 181 - (void)repositionToBalloon { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 htmlContents_.reset(new BalloonViewHost(balloon_)); | 214 htmlContents_.reset(new BalloonViewHost(balloon_)); |
200 htmlContents_->Init(); | 215 htmlContents_->Init(); |
201 } | 216 } |
202 | 217 |
203 // NSWindowDelegate notification. | 218 // NSWindowDelegate notification. |
204 - (void)windowWillClose:(NSNotification*)notif { | 219 - (void)windowWillClose:(NSNotification*)notif { |
205 [self autorelease]; | 220 [self autorelease]; |
206 } | 221 } |
207 | 222 |
208 @end | 223 @end |
OLD | NEW |