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

Side by Side Diff: chrome/browser/ui/cocoa/base_bubble_controller.mm

Issue 576643002: Mac: Ignore sheets when deciding whether to dismiss a browser action popup. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: -dot notation.. Created 6 years, 3 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 | chrome/browser/ui/cocoa/base_bubble_controller_unittest.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 (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/mac_util.h" 9 #include "base/mac/mac_util.h"
10 #include "base/mac/scoped_nsobject.h" 10 #include "base/mac/scoped_nsobject.h"
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 [self closeCleanup]; 234 [self closeCleanup];
235 [super close]; 235 [super close];
236 } 236 }
237 237
238 // The controller is the delegate of the window so it receives did resign key 238 // The controller is the delegate of the window so it receives did resign key
239 // notifications. When key is resigned mirror Windows behavior and close the 239 // notifications. When key is resigned mirror Windows behavior and close the
240 // window. 240 // window.
241 - (void)windowDidResignKey:(NSNotification*)notification { 241 - (void)windowDidResignKey:(NSNotification*)notification {
242 NSWindow* window = [self window]; 242 NSWindow* window = [self window];
243 DCHECK_EQ([notification object], window); 243 DCHECK_EQ([notification object], window);
244 if ([window isVisible] && [self shouldCloseOnResignKey]) { 244
245 // If the window isn't visible, it is already closed, and this notification 245 // If the window isn't visible, it is already closed, and this notification
246 // has been sent as part of the closing operation, so no need to close. 246 // has been sent as part of the closing operation, so no need to close.
247 if (![window isVisible])
248 return;
249
250 // Don't close when explicily disabled, or if there's an attached sheet (e.g.
251 // Open File dialog).
252 if ([self shouldCloseOnResignKey] && ![window attachedSheet]) {
247 [self close]; 253 [self close];
248 } else if ([window isVisible]) { 254 return;
249 // The bubble should not receive key events when it is no longer key window,
250 // so disable sharing parent key state. Share parent key state is only used
251 // to enable the close/minimize/maximize buttons of the parent window when
252 // the bubble has key state, so disabling it here is safe.
253 InfoBubbleWindow* bubbleWindow =
254 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]);
255 [bubbleWindow setAllowShareParentKeyState:NO];
256 } 255 }
256
257 // The bubble should not receive key events when it is no longer key window,
258 // so disable sharing parent key state. Share parent key state is only used
259 // to enable the close/minimize/maximize buttons of the parent window when
260 // the bubble has key state, so disabling it here is safe.
261 InfoBubbleWindow* bubbleWindow =
262 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]);
263 [bubbleWindow setAllowShareParentKeyState:NO];
257 } 264 }
258 265
259 - (void)windowDidBecomeKey:(NSNotification*)notification { 266 - (void)windowDidBecomeKey:(NSNotification*)notification {
260 // Re-enable share parent key state to make sure the close/minimize/maximize 267 // Re-enable share parent key state to make sure the close/minimize/maximize
261 // buttons of the parent window are active. 268 // buttons of the parent window are active.
262 InfoBubbleWindow* bubbleWindow = 269 InfoBubbleWindow* bubbleWindow =
263 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); 270 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]);
264 [bubbleWindow setAllowShareParentKeyState:YES]; 271 [bubbleWindow setAllowShareParentKeyState:YES];
265 } 272 }
266 273
267 // Since the bubble shares first responder with its parent window, set 274 // Since the bubble shares first responder with its parent window, set event
268 // event handlers to dismiss the bubble when it would normally lose key 275 // handlers to dismiss the bubble when it would normally lose key state.
269 // state. 276 // Events on sheets are ignored: this assumes the sheet belongs to the bubble
277 // since, to affect a sheet on a different window, the bubble would also lose
278 // key status in -[NSWindowDelegate windowDidResignKey:]. This keeps the logic
279 // simple, since -[NSWindow attachedSheet] returns nil while the sheet is still
280 // closing.
270 - (void)registerKeyStateEventTap { 281 - (void)registerKeyStateEventTap {
271 // Parent key state sharing is only avaiable on 10.7+. 282 // Parent key state sharing is only avaiable on 10.7+.
272 if (!base::mac::IsOSLionOrLater()) 283 if (!base::mac::IsOSLionOrLater())
273 return; 284 return;
274 285
275 NSWindow* window = self.window; 286 NSWindow* window = self.window;
276 NSNotification* note = 287 NSNotification* note =
277 [NSNotification notificationWithName:NSWindowDidResignKeyNotification 288 [NSNotification notificationWithName:NSWindowDidResignKeyNotification
278 object:window]; 289 object:window];
279 290
280 // The eventTap_ catches clicks within the application that are outside the 291 // The eventTap_ catches clicks within the application that are outside the
281 // window. 292 // window.
282 eventTap_ = [NSEvent 293 eventTap_ = [NSEvent
283 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask | 294 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask |
284 NSRightMouseDownMask 295 NSRightMouseDownMask
285 handler:^NSEvent* (NSEvent* event) { 296 handler:^NSEvent* (NSEvent* event) {
286 if (event.window != window) { 297 if ([event window] != window && ![[event window] isSheet]) {
287 // Do it right now, because if this event is right mouse event, 298 // Do it right now, because if this event is right mouse event,
288 // it may pop up a menu. windowDidResignKey: will not run until 299 // it may pop up a menu. windowDidResignKey: will not run until
289 // the menu is closed. 300 // the menu is closed.
290 if ([self respondsToSelector:@selector(windowDidResignKey:)]) { 301 if ([self respondsToSelector:@selector(windowDidResignKey:)]) {
291 [self windowDidResignKey:note]; 302 [self windowDidResignKey:note];
292 } 303 }
293 } 304 }
294 return event; 305 return event;
295 }]; 306 }];
296 307
297 // The resignationObserver_ watches for when a window resigns key state, 308 // The resignationObserver_ watches for when a window resigns key state,
298 // meaning the key window has changed and the bubble should be dismissed. 309 // meaning the key window has changed and the bubble should be dismissed.
299 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 310 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
300 resignationObserver_ = 311 resignationObserver_ =
301 [center addObserverForName:NSWindowDidResignKeyNotification 312 [center addObserverForName:NSWindowDidResignKeyNotification
302 object:nil 313 object:nil
303 queue:[NSOperationQueue mainQueue] 314 queue:[NSOperationQueue mainQueue]
304 usingBlock:^(NSNotification* notif) { 315 usingBlock:^(NSNotification* notif) {
305 [self windowDidResignKey:note]; 316 if (![[notif object] isSheet])
317 [self windowDidResignKey:note];
306 }]; 318 }];
307 } 319 }
308 320
309 // By implementing this, ESC causes the window to go away. 321 // By implementing this, ESC causes the window to go away.
310 - (IBAction)cancel:(id)sender { 322 - (IBAction)cancel:(id)sender {
311 // This is not a "real" cancel as potential changes to the radio group are not 323 // This is not a "real" cancel as potential changes to the radio group are not
312 // undone. That's ok. 324 // undone. That's ok.
313 [self close]; 325 [self close];
314 } 326 }
315 327
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 380
369 - (void)activateTabWithContents:(content::WebContents*)newContents 381 - (void)activateTabWithContents:(content::WebContents*)newContents
370 previousContents:(content::WebContents*)oldContents 382 previousContents:(content::WebContents*)oldContents
371 atIndex:(NSInteger)index 383 atIndex:(NSInteger)index
372 reason:(int)reason { 384 reason:(int)reason {
373 // The user switched tabs; close. 385 // The user switched tabs; close.
374 [self close]; 386 [self close];
375 } 387 }
376 388
377 @end // BaseBubbleController 389 @end // BaseBubbleController
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698