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

Side by Side Diff: chrome/browser/ui/app_list/app_list_service_mac.mm

Issue 952793002: Mac: Make ui/base/cocoa WindowAnimator Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git add Created 5 years, 10 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/app_list/app_list_service_mac.h" 5 #import "chrome/browser/ui/app_list/app_list_service_mac.h"
6 6
7 #include <ApplicationServices/ApplicationServices.h> 7 #include <ApplicationServices/ApplicationServices.h>
8 #import <Cocoa/Cocoa.h> 8 #import <Cocoa/Cocoa.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 25 matching lines...) Expand all
36 #include "chrome/common/pref_names.h" 36 #include "chrome/common/pref_names.h"
37 #include "chrome/grit/google_chrome_strings.h" 37 #include "chrome/grit/google_chrome_strings.h"
38 #include "content/public/browser/browser_thread.h" 38 #include "content/public/browser/browser_thread.h"
39 #include "extensions/browser/extension_system.h" 39 #include "extensions/browser/extension_system.h"
40 #include "extensions/common/manifest_handlers/file_handler_info.h" 40 #include "extensions/common/manifest_handlers/file_handler_info.h"
41 #include "grit/chrome_unscaled_resources.h" 41 #include "grit/chrome_unscaled_resources.h"
42 #include "net/base/url_util.h" 42 #include "net/base/url_util.h"
43 #import "ui/app_list/cocoa/app_list_view_controller.h" 43 #import "ui/app_list/cocoa/app_list_view_controller.h"
44 #import "ui/app_list/cocoa/app_list_window_controller.h" 44 #import "ui/app_list/cocoa/app_list_window_controller.h"
45 #include "ui/app_list/search_box_model.h" 45 #include "ui/app_list/search_box_model.h"
46 #import "ui/base/cocoa/window_animator.h"
46 #include "ui/base/l10n/l10n_util.h" 47 #include "ui/base/l10n/l10n_util.h"
47 #include "ui/base/resource/resource_bundle.h" 48 #include "ui/base/resource/resource_bundle.h"
48 #include "ui/gfx/display.h" 49 #include "ui/gfx/display.h"
49 #include "ui/gfx/screen.h" 50 #include "ui/gfx/screen.h"
50 51
51 namespace gfx { 52 namespace gfx {
52 class ImageSkia; 53 class ImageSkia;
53 } 54 }
54 55
55 // Controller for animations that show or hide the app list.
56 @interface AppListAnimationController : NSObject<NSAnimationDelegate> {
57 @private
58 // When closing, the window to close. Retained until the animation ends.
59 base::scoped_nsobject<NSWindow> window_;
60 // The animation started and owned by |self|. Reset when the animation ends.
61 base::scoped_nsobject<NSViewAnimation> animation_;
62 }
63
64 // Returns whether |window_| is scheduled to be closed when the animation ends.
65 - (BOOL)isClosing;
66
67 // Animate |window| to show or close it, after cancelling any current animation.
68 // Translates from the current location to |targetOrigin| and fades in or out.
69 - (void)animateWindow:(NSWindow*)window
70 targetOrigin:(NSPoint)targetOrigin
71 closing:(BOOL)closing;
72
73 // Called on the UI thread once the animation has completed to reset the
74 // animation state, close the window (if it is a close animation), and possibly
75 // terminate Chrome.
76 - (void)cleanupOnUIThread;
77
78 @end
79
80 namespace { 56 namespace {
81 57
82 // Version of the app list shortcut version installed. 58 // Version of the app list shortcut version installed.
83 const int kShortcutVersion = 2; 59 const int kShortcutVersion = 2;
84 60
85 // Duration of show and hide animations.
86 const NSTimeInterval kAnimationDuration = 0.2;
87
88 // Distance towards the screen edge that the app list moves from when showing. 61 // Distance towards the screen edge that the app list moves from when showing.
89 const CGFloat kDistanceMovedOnShow = 20; 62 const CGFloat kDistanceMovedOnShow = 20;
90 63
91 web_app::ShortcutInfo GetAppListShortcutInfo( 64 web_app::ShortcutInfo GetAppListShortcutInfo(
92 const base::FilePath& profile_path) { 65 const base::FilePath& profile_path) {
93 web_app::ShortcutInfo shortcut_info; 66 web_app::ShortcutInfo shortcut_info;
94 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 67 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
95 if (channel == chrome::VersionInfo::CHANNEL_CANARY) { 68 if (channel == chrome::VersionInfo::CHANNEL_CANARY) {
96 shortcut_info.title = 69 shortcut_info.title =
97 l10n_util::GetStringUTF16(IDS_APP_LIST_SHORTCUT_NAME_CANARY); 70 l10n_util::GetStringUTF16(IDS_APP_LIST_SHORTCUT_NAME_CANARY);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 cursor, 231 cursor,
259 target_origin, 232 target_origin,
260 start_origin); 233 start_origin);
261 } 234 }
262 235
263 } // namespace 236 } // namespace
264 237
265 AppListServiceMac::AppListServiceMac() 238 AppListServiceMac::AppListServiceMac()
266 : profile_(NULL), 239 : profile_(NULL),
267 controller_delegate_(new AppListControllerDelegateImpl(this)) { 240 controller_delegate_(new AppListControllerDelegateImpl(this)) {
268 animation_controller_.reset([[AppListAnimationController alloc] init]); 241 animation_controller_.reset([[WindowAnimationController alloc] init]);
269 } 242 }
270 243
271 AppListServiceMac::~AppListServiceMac() {} 244 AppListServiceMac::~AppListServiceMac() {}
272 245
273 // static 246 // static
274 AppListServiceMac* AppListServiceMac::GetInstance() { 247 AppListServiceMac* AppListServiceMac::GetInstance() {
275 return Singleton<AppListServiceMac, 248 return Singleton<AppListServiceMac,
276 LeakySingletonTraits<AppListServiceMac> >::get(); 249 LeakySingletonTraits<AppListServiceMac> >::get();
277 } 250 }
278 251
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 else 386 else
414 previously_active_application_.reset(); 387 previously_active_application_.reset();
415 388
416 // If activation is successful, the app list will lose main status and try to 389 // If activation is successful, the app list will lose main status and try to
417 // close itself again. It can't be closed in this runloop iteration without 390 // close itself again. It can't be closed in this runloop iteration without
418 // OSX deciding to raise the next Chrome window, and _then_ activating the 391 // OSX deciding to raise the next Chrome window, and _then_ activating the
419 // application on top. This also occurs if no activation option is given. 392 // application on top. This also occurs if no activation option is given.
420 if ([prior_app activateWithOptions:NSApplicationActivateIgnoringOtherApps]) 393 if ([prior_app activateWithOptions:NSApplicationActivateIgnoringOtherApps])
421 return; 394 return;
422 395
396 base::Closure callback(base::Bind(&apps::AppShimHandler::MaybeTerminate));
423 [animation_controller_ animateWindow:[window_controller_ window] 397 [animation_controller_ animateWindow:[window_controller_ window]
424 targetOrigin:last_start_origin_ 398 targetOrigin:last_start_origin_
425 closing:YES]; 399 closing:YES
400 callback:callback];
426 } 401 }
427 402
428 void AppListServiceMac::ShowForCustomLauncherPage(Profile* profile) { 403 void AppListServiceMac::ShowForCustomLauncherPage(Profile* profile) {
429 NOTIMPLEMENTED(); 404 NOTIMPLEMENTED();
430 } 405 }
431 406
432 bool AppListServiceMac::IsAppListVisible() const { 407 bool AppListServiceMac::IsAppListVisible() const {
433 return [[window_controller_ window] isVisible] && 408 return [[window_controller_ window] isVisible] &&
434 ![animation_controller_ isClosing]; 409 ![animation_controller_ isClosing];
435 } 410 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 NSPoint target_origin; 498 NSPoint target_origin;
524 GetAppListWindowOrigins(window, &target_origin, &last_start_origin_); 499 GetAppListWindowOrigins(window, &target_origin, &last_start_origin_);
525 [window setFrameOrigin:last_start_origin_]; 500 [window setFrameOrigin:last_start_origin_];
526 501
527 // Before activating, see if an application other than Chrome is currently the 502 // Before activating, see if an application other than Chrome is currently the
528 // active application, so that it can be reactivated when dismissing. 503 // active application, so that it can be reactivated when dismissing.
529 previously_active_application_.reset([ActiveApplicationNotChrome() retain]); 504 previously_active_application_.reset([ActiveApplicationNotChrome() retain]);
530 505
531 [animation_controller_ animateWindow:[window_controller_ window] 506 [animation_controller_ animateWindow:[window_controller_ window]
532 targetOrigin:target_origin 507 targetOrigin:target_origin
533 closing:NO]; 508 closing:NO
509 callback:base::Closure()];
534 [window makeKeyAndOrderFront:nil]; 510 [window makeKeyAndOrderFront:nil];
535 [NSApp activateIgnoringOtherApps:YES]; 511 [NSApp activateIgnoringOtherApps:YES];
536 RecordAppListLaunch(); 512 RecordAppListLaunch();
537 } 513 }
538 514
539 void AppListServiceMac::WindowAnimationDidEnd() {
540 [animation_controller_ cleanupOnUIThread];
541 }
542
543 // static 515 // static
544 AppListService* AppListService::Get(chrome::HostDesktopType desktop_type) { 516 AppListService* AppListService::Get(chrome::HostDesktopType desktop_type) {
545 return AppListServiceMac::GetInstance(); 517 return AppListServiceMac::GetInstance();
546 } 518 }
547 519
548 // static 520 // static
549 void AppListService::InitAll(Profile* initial_profile, 521 void AppListService::InitAll(Profile* initial_profile,
550 const base::FilePath& profile_path) { 522 const base::FilePath& profile_path) {
551 AppListServiceMac::GetInstance()->InitWithProfilePath(initial_profile, 523 AppListServiceMac::GetInstance()->InitWithProfilePath(initial_profile,
552 profile_path); 524 profile_path);
553 } 525 }
554
555 @implementation AppListAnimationController
556
557 - (BOOL)isClosing {
558 return !!window_;
559 }
560
561 - (void)animateWindow:(NSWindow*)window
562 targetOrigin:(NSPoint)targetOrigin
563 closing:(BOOL)closing {
564 // First, stop the existing animation, if there is one.
565 [animation_ stopAnimation];
566
567 NSRect targetFrame = [window frame];
568 targetFrame.origin = targetOrigin;
569
570 // NSViewAnimation has a quirk when setting the curve to NSAnimationEaseOut
571 // where it attempts to auto-reverse the animation. FadeOut becomes FadeIn
572 // (good), but FrameKey is also switched (bad). So |targetFrame| needs to be
573 // put on the StartFrameKey when using NSAnimationEaseOut for showing.
574 NSArray* animationArray = @[
575 @{
576 NSViewAnimationTargetKey : window,
577 NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect,
578 (closing ? NSViewAnimationEndFrameKey : NSViewAnimationStartFrameKey) :
579 [NSValue valueWithRect:targetFrame]
580 }
581 ];
582 animation_.reset(
583 [[NSViewAnimation alloc] initWithViewAnimations:animationArray]);
584 [animation_ setDuration:kAnimationDuration];
585 [animation_ setDelegate:self];
586
587 if (closing) {
588 [animation_ setAnimationCurve:NSAnimationEaseIn];
589 window_.reset([window retain]);
590 } else {
591 [window setAlphaValue:0.0f];
592 [animation_ setAnimationCurve:NSAnimationEaseOut];
593 window_.reset();
594 }
595 // This once used a threaded animation, but AppKit would too often ignore
596 // -[NSView canDrawConcurrently:] and just redraw whole view hierarchies on
597 // the animation thread anyway, creating a minefield of race conditions.
598 // Non-threaded means the animation isn't as smooth and doesn't begin unless
599 // the UI runloop has spun up (after profile loading).
600 [animation_ setAnimationBlockingMode:NSAnimationNonblocking];
601
602 [animation_ startAnimation];
603 }
604
605 - (void)cleanupOnUIThread {
606 bool closing = [self isClosing];
607 [window_ close];
608 window_.reset();
609 animation_.reset();
610
611 if (closing)
612 apps::AppShimHandler::MaybeTerminate();
613 }
614
615 - (void)animationDidEnd:(NSAnimation*)animation {
616 content::BrowserThread::PostTask(
617 content::BrowserThread::UI,
618 FROM_HERE,
619 base::Bind(&AppListServiceMac::WindowAnimationDidEnd,
620 base::Unretained(AppListServiceMac::GetInstance())));
621 }
622
623 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/app_list/app_list_service_mac.h ('k') | chrome/browser/ui/cocoa/base_bubble_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698