Index: chrome/browser/ui/app_list/app_list_service_mac.mm |
diff --git a/chrome/browser/ui/app_list/app_list_service_mac.mm b/chrome/browser/ui/app_list/app_list_service_mac.mm |
index d45672a154029eb0ed83e20a799e348345619916..490477582160b8f6f8e784073de3e832d173927f 100644 |
--- a/chrome/browser/ui/app_list/app_list_service_mac.mm |
+++ b/chrome/browser/ui/app_list/app_list_service_mac.mm |
@@ -43,6 +43,7 @@ |
#import "ui/app_list/cocoa/app_list_view_controller.h" |
#import "ui/app_list/cocoa/app_list_window_controller.h" |
#include "ui/app_list/search_box_model.h" |
+#import "ui/base/cocoa/window_animator.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
#include "ui/gfx/display.h" |
@@ -52,39 +53,11 @@ namespace gfx { |
class ImageSkia; |
} |
-// Controller for animations that show or hide the app list. |
-@interface AppListAnimationController : NSObject<NSAnimationDelegate> { |
- @private |
- // When closing, the window to close. Retained until the animation ends. |
- base::scoped_nsobject<NSWindow> window_; |
- // The animation started and owned by |self|. Reset when the animation ends. |
- base::scoped_nsobject<NSViewAnimation> animation_; |
-} |
- |
-// Returns whether |window_| is scheduled to be closed when the animation ends. |
-- (BOOL)isClosing; |
- |
-// Animate |window| to show or close it, after cancelling any current animation. |
-// Translates from the current location to |targetOrigin| and fades in or out. |
-- (void)animateWindow:(NSWindow*)window |
- targetOrigin:(NSPoint)targetOrigin |
- closing:(BOOL)closing; |
- |
-// Called on the UI thread once the animation has completed to reset the |
-// animation state, close the window (if it is a close animation), and possibly |
-// terminate Chrome. |
-- (void)cleanupOnUIThread; |
- |
-@end |
- |
namespace { |
// Version of the app list shortcut version installed. |
const int kShortcutVersion = 2; |
-// Duration of show and hide animations. |
-const NSTimeInterval kAnimationDuration = 0.2; |
- |
// Distance towards the screen edge that the app list moves from when showing. |
const CGFloat kDistanceMovedOnShow = 20; |
@@ -265,7 +238,7 @@ void GetAppListWindowOrigins( |
AppListServiceMac::AppListServiceMac() |
: profile_(NULL), |
controller_delegate_(new AppListControllerDelegateImpl(this)) { |
- animation_controller_.reset([[AppListAnimationController alloc] init]); |
+ animation_controller_.reset([[WindowAnimationController alloc] init]); |
} |
AppListServiceMac::~AppListServiceMac() {} |
@@ -420,9 +393,11 @@ void AppListServiceMac::DismissAppList() { |
if ([prior_app activateWithOptions:NSApplicationActivateIgnoringOtherApps]) |
return; |
+ base::Closure callback(base::Bind(&apps::AppShimHandler::MaybeTerminate)); |
[animation_controller_ animateWindow:[window_controller_ window] |
targetOrigin:last_start_origin_ |
- closing:YES]; |
+ closing:YES |
+ callback:callback]; |
} |
void AppListServiceMac::ShowForCustomLauncherPage(Profile* profile) { |
@@ -530,16 +505,13 @@ void AppListServiceMac::ShowWindowNearDock() { |
[animation_controller_ animateWindow:[window_controller_ window] |
targetOrigin:target_origin |
- closing:NO]; |
+ closing:NO |
+ callback:base::Closure()]; |
[window makeKeyAndOrderFront:nil]; |
[NSApp activateIgnoringOtherApps:YES]; |
RecordAppListLaunch(); |
} |
-void AppListServiceMac::WindowAnimationDidEnd() { |
- [animation_controller_ cleanupOnUIThread]; |
-} |
- |
// static |
AppListService* AppListService::Get(chrome::HostDesktopType desktop_type) { |
return AppListServiceMac::GetInstance(); |
@@ -551,73 +523,3 @@ void AppListService::InitAll(Profile* initial_profile, |
AppListServiceMac::GetInstance()->InitWithProfilePath(initial_profile, |
profile_path); |
} |
- |
-@implementation AppListAnimationController |
- |
-- (BOOL)isClosing { |
- return !!window_; |
-} |
- |
-- (void)animateWindow:(NSWindow*)window |
- targetOrigin:(NSPoint)targetOrigin |
- closing:(BOOL)closing { |
- // First, stop the existing animation, if there is one. |
- [animation_ stopAnimation]; |
- |
- NSRect targetFrame = [window frame]; |
- targetFrame.origin = targetOrigin; |
- |
- // NSViewAnimation has a quirk when setting the curve to NSAnimationEaseOut |
- // where it attempts to auto-reverse the animation. FadeOut becomes FadeIn |
- // (good), but FrameKey is also switched (bad). So |targetFrame| needs to be |
- // put on the StartFrameKey when using NSAnimationEaseOut for showing. |
- NSArray* animationArray = @[ |
- @{ |
- NSViewAnimationTargetKey : window, |
- NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect, |
- (closing ? NSViewAnimationEndFrameKey : NSViewAnimationStartFrameKey) : |
- [NSValue valueWithRect:targetFrame] |
- } |
- ]; |
- animation_.reset( |
- [[NSViewAnimation alloc] initWithViewAnimations:animationArray]); |
- [animation_ setDuration:kAnimationDuration]; |
- [animation_ setDelegate:self]; |
- |
- if (closing) { |
- [animation_ setAnimationCurve:NSAnimationEaseIn]; |
- window_.reset([window retain]); |
- } else { |
- [window setAlphaValue:0.0f]; |
- [animation_ setAnimationCurve:NSAnimationEaseOut]; |
- window_.reset(); |
- } |
- // This once used a threaded animation, but AppKit would too often ignore |
- // -[NSView canDrawConcurrently:] and just redraw whole view hierarchies on |
- // the animation thread anyway, creating a minefield of race conditions. |
- // Non-threaded means the animation isn't as smooth and doesn't begin unless |
- // the UI runloop has spun up (after profile loading). |
- [animation_ setAnimationBlockingMode:NSAnimationNonblocking]; |
- |
- [animation_ startAnimation]; |
-} |
- |
-- (void)cleanupOnUIThread { |
- bool closing = [self isClosing]; |
- [window_ close]; |
- window_.reset(); |
- animation_.reset(); |
- |
- if (closing) |
- apps::AppShimHandler::MaybeTerminate(); |
-} |
- |
-- (void)animationDidEnd:(NSAnimation*)animation { |
- content::BrowserThread::PostTask( |
- content::BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&AppListServiceMac::WindowAnimationDidEnd, |
- base::Unretained(AppListServiceMac::GetInstance()))); |
-} |
- |
-@end |