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

Side by Side Diff: chrome/browser/app_controller_mac.mm

Issue 6625025: [Mac] Confirm-to-Quit: Wait for a KeyUp event if the user held Cmd+Q on the second tap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/confirm_quit_panel_controller.h » ('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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/app_controller_mac.h" 5 #import "chrome/browser/app_controller_mac.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)app { 278 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)app {
279 // Check if the experiment is enabled. 279 // Check if the experiment is enabled.
280 const CommandLine* commandLine(CommandLine::ForCurrentProcess()); 280 const CommandLine* commandLine(CommandLine::ForCurrentProcess());
281 if (commandLine->HasSwitch(switches::kDisableConfirmToQuit)) 281 if (commandLine->HasSwitch(switches::kDisableConfirmToQuit))
282 return NSTerminateNow; 282 return NSTerminateNow;
283 283
284 // If the application is going to terminate as the result of a Cmd+Q 284 // If the application is going to terminate as the result of a Cmd+Q
285 // invocation, use the special sauce to prevent accidental quitting. 285 // invocation, use the special sauce to prevent accidental quitting.
286 // http://dev.chromium.org/developers/design-documents/confirm-to-quit-experim ent 286 // http://dev.chromium.org/developers/design-documents/confirm-to-quit-experim ent
287 287
288 // How long the user must hold down Cmd+Q to confirm the quit.
289 const NSTimeInterval kTimeToConfirmQuit = 1.5;
290 // Leeway between the |targetDate| and the current time that will confirm a
291 // quit.
292 const NSTimeInterval kTimeDeltaFuzzFactor = 1.0;
293 // Duration of the window fade out animation.
294 const NSTimeInterval kWindowFadeAnimationDuration = 0.2;
295
296 // This logic is only for keyboard-initiated quits. 288 // This logic is only for keyboard-initiated quits.
297 NSEvent* currentEvent = [app currentEvent]; 289 if (![ConfirmQuitPanelController eventTriggersFeature:[app currentEvent]])
298 if ([currentEvent type] != NSKeyDown)
299 return NSTerminateNow;
300 ui::AcceleratorCocoa currentEventAccelerator([currentEvent characters],
301 [currentEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask);
302 if ([ConfirmQuitPanelController quitAccelerator] != currentEventAccelerator)
303 return NSTerminateNow; 290 return NSTerminateNow;
304 291
305 // If this is the second of two such attempts to quit within a certain time 292 return [[ConfirmQuitPanelController sharedController]
306 // interval, then just quit. 293 runModalLoopForApplication:app];
307 // Time of last quit attempt, if any.
308 static NSDate* lastQuitAttempt; // Initially nil, as it's static.
309 NSDate* timeNow = [NSDate date];
310 if (lastQuitAttempt &&
311 [timeNow timeIntervalSinceDate:lastQuitAttempt] < kTimeDeltaFuzzFactor) {
312 return NSTerminateNow;
313 } else {
314 [lastQuitAttempt release]; // Harmless if already nil.
315 lastQuitAttempt = [timeNow retain]; // Record this attempt for next time.
316 }
317
318 // Show the info panel that explains what the user must to do confirm quit.
319 [[ConfirmQuitPanelController sharedController] showWindow:self];
320
321 // Spin a nested run loop until the |targetDate| is reached or a KeyUp event
322 // is sent.
323 NSDate* targetDate =
324 [NSDate dateWithTimeIntervalSinceNow:kTimeToConfirmQuit];
325 BOOL willQuit = NO;
326 NSEvent* nextEvent = nil;
327 do {
328 // Dequeue events until a key up is received.
329 nextEvent = [app nextEventMatchingMask:NSKeyUpMask
330 untilDate:nil
331 inMode:NSEventTrackingRunLoopMode
332 dequeue:YES];
333
334 // Wait for the time expiry to happen. Once past the hold threshold,
335 // commit to quitting and hide all the open windows.
336 if (!willQuit) {
337 NSDate* now = [NSDate date];
338 NSTimeInterval difference = [targetDate timeIntervalSinceDate:now];
339 if (difference < kTimeDeltaFuzzFactor) {
340 willQuit = YES;
341
342 // At this point, the quit has been confirmed and windows should all
343 // fade out to convince the user to release the key combo to finalize
344 // the quit.
345 [NSAnimationContext beginGrouping];
346 [[NSAnimationContext currentContext] setDuration:
347 kWindowFadeAnimationDuration];
348 for (NSWindow* aWindow in [app windows]) {
349 // Windows that are set to animate and have a delegate do not
350 // expect to be animated by other things and could result in an
351 // invalid state. If a window is set up like so, just force the
352 // alpha value to 0. Otherwise, animate all pretty and stuff.
353 if (![[aWindow animationForKey:@"alphaValue"] delegate]) {
354 [[aWindow animator] setAlphaValue:0.0];
355 } else {
356 [aWindow setAlphaValue:0.0];
357 }
358 }
359 [NSAnimationContext endGrouping];
360 }
361 }
362 } while (!nextEvent);
363
364 // The user has released the key combo. Discard any events (i.e. the
365 // repeated KeyDown Cmd+Q).
366 [app discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
367
368 if (willQuit) {
369 // The user held down the combination long enough that quitting should
370 // happen.
371 return NSTerminateNow;
372 } else {
373 // Slowly fade the confirm window out in case the user doesn't
374 // understand what they have to do to quit.
375 [[ConfirmQuitPanelController sharedController] dismissPanel];
376 return NSTerminateCancel;
377 }
378
379 // Default case: terminate.
380 return NSTerminateNow;
381 } 294 }
382 295
383 // Called when the app is shutting down. Clean-up as appropriate. 296 // Called when the app is shutting down. Clean-up as appropriate.
384 - (void)applicationWillTerminate:(NSNotification*)aNotification { 297 - (void)applicationWillTerminate:(NSNotification*)aNotification {
385 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; 298 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
386 [em removeEventHandlerForEventClass:kInternetEventClass 299 [em removeEventHandlerForEventClass:kInternetEventClass
387 andEventID:kAEGetURL]; 300 andEventID:kAEGetURL];
388 [em removeEventHandlerForEventClass:'WWW!' 301 [em removeEventHandlerForEventClass:'WWW!'
389 andEventID:'OURL']; 302 andEventID:'OURL'];
390 303
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 [appController showPreferencesWindow:nil page:page profile:profile]; 1203 [appController showPreferencesWindow:nil page:page profile:profile];
1291 } 1204 }
1292 1205
1293 namespace app_controller_mac { 1206 namespace app_controller_mac {
1294 1207
1295 bool IsOpeningNewWindow() { 1208 bool IsOpeningNewWindow() {
1296 return g_is_opening_new_window; 1209 return g_is_opening_new_window;
1297 } 1210 }
1298 1211
1299 } // namespace app_controller_mac 1212 } // namespace app_controller_mac
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/confirm_quit_panel_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698