OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/cocoa/base_bubble_controller.h" | 5 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/mac/bundle_locations.h" | 8 #include "base/mac/bundle_locations.h" |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
11 #include "base/mac/scoped_nsobject.h" | 11 #include "base/mac/scoped_nsobject.h" |
12 #include "base/mac/sdk_forward_declarations.h" | 12 #include "base/mac/sdk_forward_declarations.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
15 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 15 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
16 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 16 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
17 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" | 17 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" |
18 #include "components/bubble/bubble_controller.h" | |
18 | 19 |
19 @interface BaseBubbleController (Private) | 20 @interface BaseBubbleController (Private) |
20 - (void)registerForNotifications; | 21 - (void)registerForNotifications; |
21 - (void)updateOriginFromAnchor; | 22 - (void)updateOriginFromAnchor; |
22 - (void)activateTabWithContents:(content::WebContents*)newContents | 23 - (void)activateTabWithContents:(content::WebContents*)newContents |
23 previousContents:(content::WebContents*)oldContents | 24 previousContents:(content::WebContents*)oldContents |
24 atIndex:(NSInteger)index | 25 atIndex:(NSInteger)index |
25 reason:(int)reason; | 26 reason:(int)reason; |
26 - (void)recordAnchorOffset; | 27 - (void)recordAnchorOffset; |
27 - (void)parentWindowDidResize:(NSNotification*)notification; | 28 - (void)parentWindowDidResize:(NSNotification*)notification; |
28 - (void)parentWindowWillClose:(NSNotification*)notification; | 29 - (void)parentWindowWillClose:(NSNotification*)notification; |
29 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification; | 30 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification; |
30 - (void)closeCleanup; | 31 - (void)closeCleanup; |
32 | |
33 // Temporary methods to decide how to close the bubble controller. | |
34 // TODO(hcarmona): remove these methods when all bubbles use the new API. | |
35 - (void)closeBubbleWithReason:(BubbleCloseReason)reason; | |
36 // Will be a noop in new bubble API because this is handled elsewhere. | |
37 - (void)closeBubbleWithoutReason; | |
groby-ooo-7-16
2015/09/04 19:13:38
Just call it closeBubble - it's not like we're act
hcarmona
2015/09/09 23:33:02
Done.
| |
31 @end | 38 @end |
32 | 39 |
33 @implementation BaseBubbleController | 40 @implementation BaseBubbleController |
34 | 41 |
35 @synthesize anchorPoint = anchor_; | 42 @synthesize anchorPoint = anchor_; |
36 @synthesize bubble = bubble_; | 43 @synthesize bubble = bubble_; |
37 @synthesize shouldOpenAsKeyWindow = shouldOpenAsKeyWindow_; | 44 @synthesize shouldOpenAsKeyWindow = shouldOpenAsKeyWindow_; |
38 @synthesize shouldCloseOnResignKey = shouldCloseOnResignKey_; | 45 @synthesize shouldCloseOnResignKey = shouldCloseOnResignKey_; |
46 @synthesize bubbleReference = bubbleReference_; | |
39 | 47 |
40 - (id)initWithWindowNibPath:(NSString*)nibPath | 48 - (id)initWithWindowNibPath:(NSString*)nibPath |
41 parentWindow:(NSWindow*)parentWindow | 49 parentWindow:(NSWindow*)parentWindow |
42 anchoredAt:(NSPoint)anchoredAt { | 50 anchoredAt:(NSPoint)anchoredAt { |
43 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath | 51 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath |
44 ofType:@"nib"]; | 52 ofType:@"nib"]; |
45 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { | 53 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { |
46 [self setParentWindow:parentWindow]; | 54 [self setParentWindow:parentWindow]; |
47 anchor_ = anchoredAt; | 55 anchor_ = anchoredAt; |
48 shouldOpenAsKeyWindow_ = YES; | 56 shouldOpenAsKeyWindow_ = YES; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 DCHECK_EQ(parentWindow_, [notification object]); | 229 DCHECK_EQ(parentWindow_, [notification object]); |
222 NSPoint newOrigin = NSMakePoint(NSMinX([parentWindow_ frame]), | 230 NSPoint newOrigin = NSMakePoint(NSMinX([parentWindow_ frame]), |
223 NSMaxY([parentWindow_ frame])); | 231 NSMaxY([parentWindow_ frame])); |
224 newOrigin.x -= anchorOffset_.x; | 232 newOrigin.x -= anchorOffset_.x; |
225 newOrigin.y -= anchorOffset_.y; | 233 newOrigin.y -= anchorOffset_.y; |
226 [self setAnchorPoint:newOrigin]; | 234 [self setAnchorPoint:newOrigin]; |
227 } | 235 } |
228 | 236 |
229 - (void)parentWindowWillClose:(NSNotification*)notification { | 237 - (void)parentWindowWillClose:(NSNotification*)notification { |
230 [self setParentWindow:nil]; | 238 [self setParentWindow:nil]; |
231 [self close]; | 239 [self closeBubbleWithoutReason]; |
232 } | 240 } |
233 | 241 |
234 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { | 242 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { |
235 [self setParentWindow:nil]; | 243 [self setParentWindow:nil]; |
236 [self close]; | 244 [self closeBubbleWithoutReason]; |
237 } | 245 } |
238 | 246 |
239 - (void)closeCleanup { | 247 - (void)closeCleanup { |
240 if (eventTap_) { | 248 if (eventTap_) { |
241 [NSEvent removeMonitor:eventTap_]; | 249 [NSEvent removeMonitor:eventTap_]; |
242 eventTap_ = nil; | 250 eventTap_ = nil; |
243 } | 251 } |
244 if (resignationObserver_) { | 252 if (resignationObserver_) { |
245 [[NSNotificationCenter defaultCenter] | 253 [[NSNotificationCenter defaultCenter] |
246 removeObserver:resignationObserver_ | 254 removeObserver:resignationObserver_ |
247 name:NSWindowDidResignKeyNotification | 255 name:NSWindowDidResignKeyNotification |
248 object:nil]; | 256 object:nil]; |
249 resignationObserver_ = nil; | 257 resignationObserver_ = nil; |
250 } | 258 } |
251 | 259 |
252 tabStripObserverBridge_.reset(); | 260 tabStripObserverBridge_.reset(); |
253 } | 261 } |
254 | 262 |
263 - (void)closeBubbleWithReason:(BubbleCloseReason)reason { | |
264 if ([self bubbleReference]) | |
265 [self bubbleReference]->CloseBubble(reason); | |
266 else | |
267 [self close]; | |
268 } | |
269 | |
270 - (void)closeBubbleWithoutReason { | |
groby-ooo-7-16
2015/09/04 19:13:38
That's rather... icky. This means that we won't cl
hcarmona
2015/09/04 20:58:01
This should only be called where it's redundant fo
groby-ooo-7-16
2015/09/04 21:38:03
Can we kill that duplication?
hcarmona
2015/09/04 21:49:39
That's what this is attempting to do by not callin
| |
271 if (![self bubbleReference]) | |
272 [self close]; | |
273 } | |
274 | |
255 - (void)windowWillClose:(NSNotification*)notification { | 275 - (void)windowWillClose:(NSNotification*)notification { |
256 [self closeCleanup]; | 276 [self closeCleanup]; |
257 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 277 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
258 [self autorelease]; | 278 [self autorelease]; |
259 } | 279 } |
260 | 280 |
261 // We want this to be a child of a browser window. addChildWindow: | 281 // We want this to be a child of a browser window. addChildWindow: |
262 // (called from this function) will bring the window on-screen; | 282 // (called from this function) will bring the window on-screen; |
263 // unfortunately, [NSWindowController showWindow:] will also bring it | 283 // unfortunately, [NSWindowController showWindow:] will also bring it |
264 // on-screen (but will cause unexpected changes to the window's | 284 // on-screen (but will cause unexpected changes to the window's |
(...skipping 24 matching lines...) Expand all Loading... | |
289 DCHECK_EQ([notification object], window); | 309 DCHECK_EQ([notification object], window); |
290 | 310 |
291 // If the window isn't visible, it is already closed, and this notification | 311 // If the window isn't visible, it is already closed, and this notification |
292 // has been sent as part of the closing operation, so no need to close. | 312 // has been sent as part of the closing operation, so no need to close. |
293 if (![window isVisible]) | 313 if (![window isVisible]) |
294 return; | 314 return; |
295 | 315 |
296 // Don't close when explicily disabled, or if there's an attached sheet (e.g. | 316 // Don't close when explicily disabled, or if there's an attached sheet (e.g. |
297 // Open File dialog). | 317 // Open File dialog). |
298 if ([self shouldCloseOnResignKey] && ![window attachedSheet]) { | 318 if ([self shouldCloseOnResignKey] && ![window attachedSheet]) { |
299 [self close]; | 319 [self closeBubbleWithReason:BUBBLE_CLOSE_FOCUS_LOST]; |
300 return; | 320 return; |
301 } | 321 } |
302 | 322 |
303 // The bubble should not receive key events when it is no longer key window, | 323 // The bubble should not receive key events when it is no longer key window, |
304 // so disable sharing parent key state. Share parent key state is only used | 324 // so disable sharing parent key state. Share parent key state is only used |
305 // to enable the close/minimize/maximize buttons of the parent window when | 325 // to enable the close/minimize/maximize buttons of the parent window when |
306 // the bubble has key state, so disabling it here is safe. | 326 // the bubble has key state, so disabling it here is safe. |
307 InfoBubbleWindow* bubbleWindow = | 327 InfoBubbleWindow* bubbleWindow = |
308 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); | 328 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); |
309 [bubbleWindow setAllowShareParentKeyState:NO]; | 329 [bubbleWindow setAllowShareParentKeyState:NO]; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 if (![[notif object] isSheet] && | 382 if (![[notif object] isSheet] && |
363 [NSApp keyWindow] != [self window]) | 383 [NSApp keyWindow] != [self window]) |
364 [self windowDidResignKey:note]; | 384 [self windowDidResignKey:note]; |
365 }]; | 385 }]; |
366 } | 386 } |
367 | 387 |
368 // By implementing this, ESC causes the window to go away. | 388 // By implementing this, ESC causes the window to go away. |
369 - (IBAction)cancel:(id)sender { | 389 - (IBAction)cancel:(id)sender { |
370 // This is not a "real" cancel as potential changes to the radio group are not | 390 // This is not a "real" cancel as potential changes to the radio group are not |
371 // undone. That's ok. | 391 // undone. That's ok. |
372 [self close]; | 392 [self closeBubbleWithReason:BUBBLE_CLOSE_CANCELED]; |
373 } | 393 } |
374 | 394 |
375 // Takes the |anchor_| point and adjusts the window's origin accordingly. | 395 // Takes the |anchor_| point and adjusts the window's origin accordingly. |
376 - (void)updateOriginFromAnchor { | 396 - (void)updateOriginFromAnchor { |
377 NSWindow* window = [self window]; | 397 NSWindow* window = [self window]; |
378 NSPoint origin = anchor_; | 398 NSPoint origin = anchor_; |
379 | 399 |
380 switch ([bubble_ alignment]) { | 400 switch ([bubble_ alignment]) { |
381 case info_bubble::kAlignArrowToAnchor: { | 401 case info_bubble::kAlignArrowToAnchor: { |
382 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + | 402 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
422 | 442 |
423 origin.y -= NSHeight([window frame]); | 443 origin.y -= NSHeight([window frame]); |
424 [window setFrameOrigin:origin]; | 444 [window setFrameOrigin:origin]; |
425 } | 445 } |
426 | 446 |
427 - (void)activateTabWithContents:(content::WebContents*)newContents | 447 - (void)activateTabWithContents:(content::WebContents*)newContents |
428 previousContents:(content::WebContents*)oldContents | 448 previousContents:(content::WebContents*)oldContents |
429 atIndex:(NSInteger)index | 449 atIndex:(NSInteger)index |
430 reason:(int)reason { | 450 reason:(int)reason { |
431 // The user switched tabs; close. | 451 // The user switched tabs; close. |
432 [self close]; | 452 [self closeBubbleWithoutReason]; |
433 } | 453 } |
434 | 454 |
435 @end // BaseBubbleController | 455 @end // BaseBubbleController |
OLD | NEW |