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/closure_blocks_leopard_compat.h" | 9 #include "base/mac/closure_blocks_leopard_compat.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
11 #include "base/memory/scoped_nsobject.h" | 11 #include "base/memory/scoped_nsobject.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
13 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 14 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
14 #include "content/public/browser/notification_observer.h" | 15 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" |
15 #include "content/public/browser/notification_registrar.h" | |
16 #include "content/public/browser/notification_service.h" | |
17 #include "content/public/browser/notification_types.h" | |
18 #include "grit/generated_resources.h" | 16 #include "grit/generated_resources.h" |
19 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
20 | 18 |
21 @interface BaseBubbleController (Private) | 19 @interface BaseBubbleController (Private) |
22 - (void)updateOriginFromAnchor; | 20 - (void)updateOriginFromAnchor; |
| 21 - (void)activateTabWithContents:(TabContentsWrapper*)newContents |
| 22 previousContents:(TabContentsWrapper*)oldContents |
| 23 atIndex:(NSInteger)index |
| 24 userGesture:(bool)wasUserGesture; |
23 @end | 25 @end |
24 | 26 |
25 #if !defined(MAC_OS_X_VERSION_10_6) || \ | 27 #if !defined(MAC_OS_X_VERSION_10_6) || \ |
26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | 28 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 |
27 typedef unsigned long long NSEventMask; | 29 typedef unsigned long long NSEventMask; |
28 | 30 |
29 @interface NSEvent (SnowLeopardDeclarations) | 31 @interface NSEvent (SnowLeopardDeclarations) |
30 + (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask | 32 + (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask |
31 handler:(NSEvent* (^)(NSEvent*))block; | 33 handler:(NSEvent* (^)(NSEvent*))block; |
32 + (void)removeMonitor:(id)eventMonitor; | 34 + (void)removeMonitor:(id)eventMonitor; |
33 @end | 35 @end |
34 | 36 |
35 @interface NSOperationQueue (SnowLeopardDeclarations) | 37 @interface NSOperationQueue (SnowLeopardDeclarations) |
36 + (id)mainQueue; | 38 + (id)mainQueue; |
37 @end | 39 @end |
38 | 40 |
39 @interface NSNotificationCenter (SnowLeopardDeclarations) | 41 @interface NSNotificationCenter (SnowLeopardDeclarations) |
40 - (id)addObserverForName:(NSString*)name | 42 - (id)addObserverForName:(NSString*)name |
41 object:(id)obj | 43 object:(id)obj |
42 queue:(NSOperationQueue*)queue | 44 queue:(NSOperationQueue*)queue |
43 usingBlock:(void (^)(NSNotification*))block; | 45 usingBlock:(void (^)(NSNotification*))block; |
44 @end | 46 @end |
45 #endif // MAC_OS_X_VERSION_10_6 | 47 #endif // MAC_OS_X_VERSION_10_6 |
46 | 48 |
47 namespace BaseBubbleControllerInternal { | |
48 | |
49 // This bridge listens for notifications so that the bubble closes when a user | |
50 // switches tabs (including by opening a new one). | |
51 class Bridge : public content::NotificationObserver { | |
52 public: | |
53 explicit Bridge(BaseBubbleController* controller) : controller_(controller) { | |
54 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_HIDDEN, | |
55 content::NotificationService::AllSources()); | |
56 } | |
57 | |
58 // content::NotificationObserver: | |
59 virtual void Observe(int type, | |
60 const content::NotificationSource& source, | |
61 const content::NotificationDetails& details) { | |
62 [controller_ close]; | |
63 } | |
64 | |
65 private: | |
66 BaseBubbleController* controller_; // Weak, owns this. | |
67 content::NotificationRegistrar registrar_; | |
68 }; | |
69 | |
70 } // namespace BaseBubbleControllerInternal | |
71 | |
72 @implementation BaseBubbleController | 49 @implementation BaseBubbleController |
73 | 50 |
74 @synthesize parentWindow = parentWindow_; | 51 @synthesize parentWindow = parentWindow_; |
75 @synthesize anchorPoint = anchor_; | 52 @synthesize anchorPoint = anchor_; |
76 @synthesize bubble = bubble_; | 53 @synthesize bubble = bubble_; |
77 | 54 |
78 - (id)initWithWindowNibPath:(NSString*)nibPath | 55 - (id)initWithWindowNibPath:(NSString*)nibPath |
79 parentWindow:(NSWindow*)parentWindow | 56 parentWindow:(NSWindow*)parentWindow |
80 anchoredAt:(NSPoint)anchoredAt { | 57 anchoredAt:(NSPoint)anchoredAt { |
81 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath | 58 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 } | 112 } |
136 return self; | 113 return self; |
137 } | 114 } |
138 | 115 |
139 - (void)awakeFromNib { | 116 - (void)awakeFromNib { |
140 // Check all connections have been made in Interface Builder. | 117 // Check all connections have been made in Interface Builder. |
141 DCHECK([self window]); | 118 DCHECK([self window]); |
142 DCHECK(bubble_); | 119 DCHECK(bubble_); |
143 DCHECK_EQ(self, [[self window] delegate]); | 120 DCHECK_EQ(self, [[self window] delegate]); |
144 | 121 |
145 baseBridge_.reset(new BaseBubbleControllerInternal::Bridge(self)); | 122 BrowserWindowController* bwc = |
| 123 [BrowserWindowController browserWindowControllerForWindow:parentWindow_]; |
| 124 if (bwc) { |
| 125 TabStripController* tabStripController = [bwc tabStripController]; |
| 126 TabStripModel* tabStripModel = [tabStripController tabStripModel]; |
| 127 tabStripObserverBridge_.reset(new TabStripModelObserverBridge(tabStripModel, |
| 128 self)); |
| 129 } |
146 | 130 |
147 [bubble_ setArrowLocation:info_bubble::kTopRight]; | 131 [bubble_ setArrowLocation:info_bubble::kTopRight]; |
148 } | 132 } |
149 | 133 |
150 - (void)dealloc { | 134 - (void)dealloc { |
151 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 135 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
152 [super dealloc]; | 136 [super dealloc]; |
153 } | 137 } |
154 | 138 |
155 - (void)setAnchorPoint:(NSPoint)anchor { | 139 - (void)setAnchorPoint:(NSPoint)anchor { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 eventTap_ = nil; | 182 eventTap_ = nil; |
199 } | 183 } |
200 if (resignationObserver_) { | 184 if (resignationObserver_) { |
201 [[NSNotificationCenter defaultCenter] | 185 [[NSNotificationCenter defaultCenter] |
202 removeObserver:resignationObserver_ | 186 removeObserver:resignationObserver_ |
203 name:NSWindowDidResignKeyNotification | 187 name:NSWindowDidResignKeyNotification |
204 object:nil]; | 188 object:nil]; |
205 resignationObserver_ = nil; | 189 resignationObserver_ = nil; |
206 } | 190 } |
207 | 191 |
| 192 tabStripObserverBridge_.reset(); |
| 193 |
208 [[[self window] parentWindow] removeChildWindow:[self window]]; | 194 [[[self window] parentWindow] removeChildWindow:[self window]]; |
209 [super close]; | 195 [super close]; |
210 } | 196 } |
211 | 197 |
212 // The controller is the delegate of the window so it receives did resign key | 198 // The controller is the delegate of the window so it receives did resign key |
213 // notifications. When key is resigned mirror Windows behavior and close the | 199 // notifications. When key is resigned mirror Windows behavior and close the |
214 // window. | 200 // window. |
215 - (void)windowDidResignKey:(NSNotification*)notification { | 201 - (void)windowDidResignKey:(NSNotification*)notification { |
216 NSWindow* window = [self window]; | 202 NSWindow* window = [self window]; |
217 DCHECK_EQ([notification object], window); | 203 DCHECK_EQ([notification object], window); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 break; | 284 break; |
299 | 285 |
300 default: | 286 default: |
301 NOTREACHED(); | 287 NOTREACHED(); |
302 } | 288 } |
303 | 289 |
304 origin.y -= NSHeight([window frame]); | 290 origin.y -= NSHeight([window frame]); |
305 [window setFrameOrigin:origin]; | 291 [window setFrameOrigin:origin]; |
306 } | 292 } |
307 | 293 |
| 294 - (void)activateTabWithContents:(TabContentsWrapper*)newContents |
| 295 previousContents:(TabContentsWrapper*)oldContents |
| 296 atIndex:(NSInteger)index |
| 297 userGesture:(bool)wasUserGesture { |
| 298 // The user switched tabs; close. |
| 299 [self close]; |
| 300 } |
| 301 |
308 @end // BaseBubbleController | 302 @end // BaseBubbleController |
OLD | NEW |