OLD | NEW |
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" |
| 6 |
5 #include <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
6 #import <Cocoa/Cocoa.h> | 8 #import <Cocoa/Cocoa.h> |
7 | 9 |
8 #include "apps/app_launcher.h" | 10 #include "apps/app_launcher.h" |
9 #include "apps/app_shim/app_shim_handler_mac.h" | |
10 #include "apps/app_shim/app_shim_mac.h" | 11 #include "apps/app_shim/app_shim_mac.h" |
11 #include "apps/pref_names.h" | 12 #include "apps/pref_names.h" |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
15 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
16 #include "base/mac/scoped_nsobject.h" | |
17 #include "base/memory/singleton.h" | 17 #include "base/memory/singleton.h" |
18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/extensions/extension_system.h" | 21 #include "chrome/browser/extensions/extension_system.h" |
22 #include "chrome/browser/profiles/profile_manager.h" | 22 #include "chrome/browser/profiles/profile_manager.h" |
23 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" | 23 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
24 #include "chrome/browser/ui/app_list/app_list_service.h" | 24 #include "chrome/browser/ui/app_list/app_list_service.h" |
25 #include "chrome/browser/ui/app_list/app_list_service_impl.h" | 25 #include "chrome/browser/ui/app_list/app_list_service_impl.h" |
26 #include "chrome/browser/ui/app_list/app_list_view_delegate.h" | 26 #include "chrome/browser/ui/app_list/app_list_view_delegate.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 70 |
71 // Version of the app list shortcut version installed. | 71 // Version of the app list shortcut version installed. |
72 const int kShortcutVersion = 1; | 72 const int kShortcutVersion = 1; |
73 | 73 |
74 // Duration of show and hide animations. | 74 // Duration of show and hide animations. |
75 const NSTimeInterval kAnimationDuration = 0.2; | 75 const NSTimeInterval kAnimationDuration = 0.2; |
76 | 76 |
77 // Distance towards the screen edge that the app list moves from when showing. | 77 // Distance towards the screen edge that the app list moves from when showing. |
78 const CGFloat kDistanceMovedOnShow = 20; | 78 const CGFloat kDistanceMovedOnShow = 20; |
79 | 79 |
80 // AppListServiceMac manages global resources needed for the app list to | |
81 // operate, and controls when the app list is opened and closed. | |
82 class AppListServiceMac : public AppListServiceImpl, | |
83 public apps::AppShimHandler { | |
84 public: | |
85 virtual ~AppListServiceMac(); | |
86 | |
87 static AppListServiceMac* GetInstance() { | |
88 return Singleton<AppListServiceMac, | |
89 LeakySingletonTraits<AppListServiceMac> >::get(); | |
90 } | |
91 | |
92 void ShowWindowNearDock(); | |
93 | |
94 // AppListService overrides: | |
95 virtual void Init(Profile* initial_profile) OVERRIDE; | |
96 virtual void CreateForProfile(Profile* requested_profile) OVERRIDE; | |
97 virtual void ShowForProfile(Profile* requested_profile) OVERRIDE; | |
98 virtual void DismissAppList() OVERRIDE; | |
99 virtual bool IsAppListVisible() const OVERRIDE; | |
100 virtual gfx::NativeWindow GetAppListWindow() OVERRIDE; | |
101 virtual AppListControllerDelegate* CreateControllerDelegate() OVERRIDE; | |
102 | |
103 // AppListServiceImpl overrides: | |
104 virtual void CreateShortcut() OVERRIDE; | |
105 | |
106 // AppShimHandler overrides: | |
107 virtual void OnShimLaunch(apps::AppShimHandler::Host* host, | |
108 apps::AppShimLaunchType launch_type) OVERRIDE; | |
109 virtual void OnShimClose(apps::AppShimHandler::Host* host) OVERRIDE; | |
110 virtual void OnShimFocus(apps::AppShimHandler::Host* host, | |
111 apps::AppShimFocusType focus_type) OVERRIDE; | |
112 virtual void OnShimSetHidden(apps::AppShimHandler::Host* host, | |
113 bool hidden) OVERRIDE; | |
114 virtual void OnShimQuit(apps::AppShimHandler::Host* host) OVERRIDE; | |
115 | |
116 private: | |
117 friend struct DefaultSingletonTraits<AppListServiceMac>; | |
118 | |
119 AppListServiceMac(); | |
120 | |
121 base::scoped_nsobject<AppListWindowController> window_controller_; | |
122 base::scoped_nsobject<AppListAnimationController> animation_controller_; | |
123 base::scoped_nsobject<NSRunningApplication> previously_active_application_; | |
124 NSPoint last_start_origin_; | |
125 | |
126 DISALLOW_COPY_AND_ASSIGN(AppListServiceMac); | |
127 }; | |
128 | |
129 class AppListControllerDelegateCocoa : public AppListControllerDelegate { | 80 class AppListControllerDelegateCocoa : public AppListControllerDelegate { |
130 public: | 81 public: |
131 AppListControllerDelegateCocoa(); | 82 AppListControllerDelegateCocoa(); |
132 virtual ~AppListControllerDelegateCocoa(); | 83 virtual ~AppListControllerDelegateCocoa(); |
133 | 84 |
134 private: | 85 private: |
135 // AppListControllerDelegate overrides: | 86 // AppListControllerDelegate overrides: |
136 virtual void DismissView() OVERRIDE; | 87 virtual void DismissView() OVERRIDE; |
137 virtual gfx::NativeWindow GetAppListWindow() OVERRIDE; | 88 virtual gfx::NativeWindow GetAppListWindow() OVERRIDE; |
138 virtual bool CanPin() OVERRIDE; | 89 virtual bool CanPin() OVERRIDE; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 Profile* profile, const extensions::Extension* extension, int event_flags) { | 261 Profile* profile, const extensions::Extension* extension, int event_flags) { |
311 LaunchApp(profile, extension, event_flags); | 262 LaunchApp(profile, extension, event_flags); |
312 } | 263 } |
313 | 264 |
314 void AppListControllerDelegateCocoa::LaunchApp( | 265 void AppListControllerDelegateCocoa::LaunchApp( |
315 Profile* profile, const extensions::Extension* extension, int event_flags) { | 266 Profile* profile, const extensions::Extension* extension, int event_flags) { |
316 chrome::OpenApplication(chrome::AppLaunchParams( | 267 chrome::OpenApplication(chrome::AppLaunchParams( |
317 profile, extension, NEW_FOREGROUND_TAB)); | 268 profile, extension, NEW_FOREGROUND_TAB)); |
318 } | 269 } |
319 | 270 |
| 271 enum DockLocation { |
| 272 DockLocationOtherDisplay, |
| 273 DockLocationBottom, |
| 274 DockLocationLeft, |
| 275 DockLocationRight, |
| 276 }; |
| 277 |
| 278 DockLocation DockLocationInDisplay(const gfx::Display& display) { |
| 279 // Assume the dock occupies part of the work area either on the left, right or |
| 280 // bottom of the display. Note in the autohide case, it is always 4 pixels. |
| 281 const gfx::Rect work_area = display.work_area(); |
| 282 const gfx::Rect display_bounds = display.bounds(); |
| 283 if (work_area.bottom() != display_bounds.bottom()) |
| 284 return DockLocationBottom; |
| 285 |
| 286 if (work_area.x() != display_bounds.x()) |
| 287 return DockLocationLeft; |
| 288 |
| 289 if (work_area.right() != display_bounds.right()) |
| 290 return DockLocationRight; |
| 291 |
| 292 return DockLocationOtherDisplay; |
| 293 } |
| 294 |
| 295 // If |work_area_edge| is too close to the |screen_edge| (e.g. autohide dock), |
| 296 // adjust |anchor| away from the edge by a constant amount to reduce overlap and |
| 297 // ensure the dock icon can still be clicked to dismiss the app list. |
| 298 int AdjustPointForDynamicDock(int anchor, int screen_edge, int work_area_edge) { |
| 299 const int kAutohideDockThreshold = 10; |
| 300 const int kExtraDistance = 50; // A dock with 40 items is about this size. |
| 301 if (abs(work_area_edge - screen_edge) > kAutohideDockThreshold) |
| 302 return anchor; |
| 303 |
| 304 return anchor + |
| 305 (screen_edge < work_area_edge ? kExtraDistance : -kExtraDistance); |
| 306 } |
| 307 |
| 308 void GetAppListWindowOrigins( |
| 309 NSWindow* window, NSPoint* target_origin, NSPoint* start_origin) { |
| 310 gfx::Screen* const screen = gfx::Screen::GetScreenFor([window contentView]); |
| 311 // Ensure y coordinates are flipped back into AppKit's coordinate system. |
| 312 const CGFloat max_y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]); |
| 313 if (!CGCursorIsVisible()) { |
| 314 // If Chrome is the active application, display on the same display as |
| 315 // Chrome's keyWindow since this will catch activations triggered, e.g, via |
| 316 // WebStore install. If another application is active, OSX doesn't provide a |
| 317 // reliable way to get the display in use. Fall back to the primary display |
| 318 // since it has the menu bar and is likely to be correct, e.g., for |
| 319 // activations from Spotlight. |
| 320 const gfx::NativeView key_view = [[NSApp keyWindow] contentView]; |
| 321 const gfx::Rect work_area = key_view && [NSApp isActive] ? |
| 322 screen->GetDisplayNearestWindow(key_view).work_area() : |
| 323 screen->GetPrimaryDisplay().work_area(); |
| 324 *target_origin = NSMakePoint(work_area.x(), max_y - work_area.bottom()); |
| 325 *start_origin = *target_origin; |
| 326 return; |
| 327 } |
| 328 |
| 329 gfx::Point anchor = screen->GetCursorScreenPoint(); |
| 330 const gfx::Display display = screen->GetDisplayNearestPoint(anchor); |
| 331 const DockLocation dock_location = DockLocationInDisplay(display); |
| 332 const gfx::Rect display_bounds = display.bounds(); |
| 333 |
| 334 if (dock_location == DockLocationOtherDisplay) { |
| 335 // Just display at the bottom-left of the display the cursor is on. |
| 336 *target_origin = NSMakePoint(display_bounds.x(), |
| 337 max_y - display_bounds.bottom()); |
| 338 *start_origin = *target_origin; |
| 339 return; |
| 340 } |
| 341 |
| 342 // Anchor the center of the window in a region that prevents the window |
| 343 // showing outside of the work area. |
| 344 const NSSize window_size = [window frame].size; |
| 345 const gfx::Rect work_area = display.work_area(); |
| 346 gfx::Rect anchor_area = work_area; |
| 347 anchor_area.Inset(window_size.width / 2, window_size.height / 2); |
| 348 anchor.SetToMax(anchor_area.origin()); |
| 349 anchor.SetToMin(anchor_area.bottom_right()); |
| 350 |
| 351 // Move anchor to the dock, keeping the other axis aligned with the cursor. |
| 352 switch (dock_location) { |
| 353 case DockLocationBottom: |
| 354 anchor.set_y(AdjustPointForDynamicDock( |
| 355 anchor_area.bottom(), display_bounds.bottom(), work_area.bottom())); |
| 356 break; |
| 357 case DockLocationLeft: |
| 358 anchor.set_x(AdjustPointForDynamicDock( |
| 359 anchor_area.x(), display_bounds.x(), work_area.x())); |
| 360 break; |
| 361 case DockLocationRight: |
| 362 anchor.set_x(AdjustPointForDynamicDock( |
| 363 anchor_area.right(), display_bounds.right(), work_area.right())); |
| 364 break; |
| 365 default: |
| 366 NOTREACHED(); |
| 367 } |
| 368 |
| 369 *target_origin = NSMakePoint(anchor.x() - window_size.width / 2, |
| 370 max_y - anchor.y() - window_size.height / 2); |
| 371 *start_origin = *target_origin; |
| 372 |
| 373 switch (dock_location) { |
| 374 case DockLocationBottom: |
| 375 start_origin->y -= kDistanceMovedOnShow; |
| 376 break; |
| 377 case DockLocationLeft: |
| 378 start_origin->x -= kDistanceMovedOnShow; |
| 379 break; |
| 380 case DockLocationRight: |
| 381 start_origin->x += kDistanceMovedOnShow; |
| 382 break; |
| 383 default: |
| 384 NOTREACHED(); |
| 385 } |
| 386 } |
| 387 |
| 388 } // namespace |
| 389 |
320 AppListServiceMac::AppListServiceMac() { | 390 AppListServiceMac::AppListServiceMac() { |
321 animation_controller_.reset([[AppListAnimationController alloc] init]); | 391 animation_controller_.reset([[AppListAnimationController alloc] init]); |
322 } | 392 } |
323 | 393 |
324 AppListServiceMac::~AppListServiceMac() {} | 394 AppListServiceMac::~AppListServiceMac() {} |
325 | 395 |
| 396 // static |
| 397 AppListServiceMac* AppListServiceMac::GetInstance() { |
| 398 return Singleton<AppListServiceMac, |
| 399 LeakySingletonTraits<AppListServiceMac> >::get(); |
| 400 } |
| 401 |
326 void AppListServiceMac::Init(Profile* initial_profile) { | 402 void AppListServiceMac::Init(Profile* initial_profile) { |
327 // On Mac, Init() is called multiple times for a process: any time there is no | 403 // On Mac, Init() is called multiple times for a process: any time there is no |
328 // browser window open and a new window is opened, and during process startup | 404 // browser window open and a new window is opened, and during process startup |
329 // to handle the silent launch case (e.g. for app shims). In the startup case, | 405 // to handle the silent launch case (e.g. for app shims). In the startup case, |
330 // a profile has not yet been determined so |initial_profile| will be NULL. | 406 // a profile has not yet been determined so |initial_profile| will be NULL. |
331 static bool init_called_with_profile = false; | 407 static bool init_called_with_profile = false; |
332 if (initial_profile && !init_called_with_profile) { | 408 if (initial_profile && !init_called_with_profile) { |
333 init_called_with_profile = true; | 409 init_called_with_profile = true; |
334 HandleCommandLineFlags(initial_profile); | 410 HandleCommandLineFlags(initial_profile); |
335 PrefService* local_state = g_browser_process->local_state(); | 411 PrefService* local_state = g_browser_process->local_state(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 void AppListServiceMac::OnShimClose(apps::AppShimHandler::Host* host) {} | 526 void AppListServiceMac::OnShimClose(apps::AppShimHandler::Host* host) {} |
451 | 527 |
452 void AppListServiceMac::OnShimFocus(apps::AppShimHandler::Host* host, | 528 void AppListServiceMac::OnShimFocus(apps::AppShimHandler::Host* host, |
453 apps::AppShimFocusType focus_type) {} | 529 apps::AppShimFocusType focus_type) {} |
454 | 530 |
455 void AppListServiceMac::OnShimSetHidden(apps::AppShimHandler::Host* host, | 531 void AppListServiceMac::OnShimSetHidden(apps::AppShimHandler::Host* host, |
456 bool hidden) {} | 532 bool hidden) {} |
457 | 533 |
458 void AppListServiceMac::OnShimQuit(apps::AppShimHandler::Host* host) {} | 534 void AppListServiceMac::OnShimQuit(apps::AppShimHandler::Host* host) {} |
459 | 535 |
460 enum DockLocation { | |
461 DockLocationOtherDisplay, | |
462 DockLocationBottom, | |
463 DockLocationLeft, | |
464 DockLocationRight, | |
465 }; | |
466 | |
467 DockLocation DockLocationInDisplay(const gfx::Display& display) { | |
468 // Assume the dock occupies part of the work area either on the left, right or | |
469 // bottom of the display. Note in the autohide case, it is always 4 pixels. | |
470 const gfx::Rect work_area = display.work_area(); | |
471 const gfx::Rect display_bounds = display.bounds(); | |
472 if (work_area.bottom() != display_bounds.bottom()) | |
473 return DockLocationBottom; | |
474 | |
475 if (work_area.x() != display_bounds.x()) | |
476 return DockLocationLeft; | |
477 | |
478 if (work_area.right() != display_bounds.right()) | |
479 return DockLocationRight; | |
480 | |
481 return DockLocationOtherDisplay; | |
482 } | |
483 | |
484 // If |work_area_edge| is too close to the |screen_edge| (e.g. autohide dock), | |
485 // adjust |anchor| away from the edge by a constant amount to reduce overlap and | |
486 // ensure the dock icon can still be clicked to dismiss the app list. | |
487 int AdjustPointForDynamicDock(int anchor, int screen_edge, int work_area_edge) { | |
488 const int kAutohideDockThreshold = 10; | |
489 const int kExtraDistance = 50; // A dock with 40 items is about this size. | |
490 if (abs(work_area_edge - screen_edge) > kAutohideDockThreshold) | |
491 return anchor; | |
492 | |
493 return anchor + | |
494 (screen_edge < work_area_edge ? kExtraDistance : -kExtraDistance); | |
495 } | |
496 | |
497 void GetAppListWindowOrigins( | |
498 NSWindow* window, NSPoint* target_origin, NSPoint* start_origin) { | |
499 gfx::Screen* const screen = gfx::Screen::GetScreenFor([window contentView]); | |
500 // Ensure y coordinates are flipped back into AppKit's coordinate system. | |
501 const CGFloat max_y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]); | |
502 if (!CGCursorIsVisible()) { | |
503 // If Chrome is the active application, display on the same display as | |
504 // Chrome's keyWindow since this will catch activations triggered, e.g, via | |
505 // WebStore install. If another application is active, OSX doesn't provide a | |
506 // reliable way to get the display in use. Fall back to the primary display | |
507 // since it has the menu bar and is likely to be correct, e.g., for | |
508 // activations from Spotlight. | |
509 const gfx::NativeView key_view = [[NSApp keyWindow] contentView]; | |
510 const gfx::Rect work_area = key_view && [NSApp isActive] ? | |
511 screen->GetDisplayNearestWindow(key_view).work_area() : | |
512 screen->GetPrimaryDisplay().work_area(); | |
513 *target_origin = NSMakePoint(work_area.x(), max_y - work_area.bottom()); | |
514 *start_origin = *target_origin; | |
515 return; | |
516 } | |
517 | |
518 gfx::Point anchor = screen->GetCursorScreenPoint(); | |
519 const gfx::Display display = screen->GetDisplayNearestPoint(anchor); | |
520 const DockLocation dock_location = DockLocationInDisplay(display); | |
521 const gfx::Rect display_bounds = display.bounds(); | |
522 | |
523 if (dock_location == DockLocationOtherDisplay) { | |
524 // Just display at the bottom-left of the display the cursor is on. | |
525 *target_origin = NSMakePoint(display_bounds.x(), | |
526 max_y - display_bounds.bottom()); | |
527 *start_origin = *target_origin; | |
528 return; | |
529 } | |
530 | |
531 // Anchor the center of the window in a region that prevents the window | |
532 // showing outside of the work area. | |
533 const NSSize window_size = [window frame].size; | |
534 const gfx::Rect work_area = display.work_area(); | |
535 gfx::Rect anchor_area = work_area; | |
536 anchor_area.Inset(window_size.width / 2, window_size.height / 2); | |
537 anchor.SetToMax(anchor_area.origin()); | |
538 anchor.SetToMin(anchor_area.bottom_right()); | |
539 | |
540 // Move anchor to the dock, keeping the other axis aligned with the cursor. | |
541 switch (dock_location) { | |
542 case DockLocationBottom: | |
543 anchor.set_y(AdjustPointForDynamicDock( | |
544 anchor_area.bottom(), display_bounds.bottom(), work_area.bottom())); | |
545 break; | |
546 case DockLocationLeft: | |
547 anchor.set_x(AdjustPointForDynamicDock( | |
548 anchor_area.x(), display_bounds.x(), work_area.x())); | |
549 break; | |
550 case DockLocationRight: | |
551 anchor.set_x(AdjustPointForDynamicDock( | |
552 anchor_area.right(), display_bounds.right(), work_area.right())); | |
553 break; | |
554 default: | |
555 NOTREACHED(); | |
556 } | |
557 | |
558 *target_origin = NSMakePoint(anchor.x() - window_size.width / 2, | |
559 max_y - anchor.y() - window_size.height / 2); | |
560 *start_origin = *target_origin; | |
561 | |
562 switch (dock_location) { | |
563 case DockLocationBottom: | |
564 start_origin->y -= kDistanceMovedOnShow; | |
565 break; | |
566 case DockLocationLeft: | |
567 start_origin->x -= kDistanceMovedOnShow; | |
568 break; | |
569 case DockLocationRight: | |
570 start_origin->x += kDistanceMovedOnShow; | |
571 break; | |
572 default: | |
573 NOTREACHED(); | |
574 } | |
575 } | |
576 | |
577 void AppListServiceMac::ShowWindowNearDock() { | 536 void AppListServiceMac::ShowWindowNearDock() { |
578 NSWindow* window = GetAppListWindow(); | 537 NSWindow* window = GetAppListWindow(); |
579 DCHECK(window); | 538 DCHECK(window); |
580 NSPoint target_origin; | 539 NSPoint target_origin; |
581 GetAppListWindowOrigins(window, &target_origin, &last_start_origin_); | 540 GetAppListWindowOrigins(window, &target_origin, &last_start_origin_); |
582 [window setFrameOrigin:last_start_origin_]; | 541 [window setFrameOrigin:last_start_origin_]; |
583 | 542 |
584 // Before activating, see if an application other than Chrome is currently the | 543 // Before activating, see if an application other than Chrome is currently the |
585 // active application, so that it can be reactivated when dismissing. | 544 // active application, so that it can be reactivated when dismissing. |
586 previously_active_application_.reset([ActiveApplicationNotChrome() retain]); | 545 previously_active_application_.reset([ActiveApplicationNotChrome() retain]); |
587 | 546 |
588 [animation_controller_ animateWindow:[window_controller_ window] | 547 [animation_controller_ animateWindow:[window_controller_ window] |
589 targetOrigin:target_origin | 548 targetOrigin:target_origin |
590 closing:NO]; | 549 closing:NO]; |
591 [window makeKeyAndOrderFront:nil]; | 550 [window makeKeyAndOrderFront:nil]; |
592 [NSApp activateIgnoringOtherApps:YES]; | 551 [NSApp activateIgnoringOtherApps:YES]; |
593 } | 552 } |
594 | 553 |
595 } // namespace | 554 // static |
| 555 AppListService* AppListService::Get() { |
| 556 return AppListServiceMac::GetInstance(); |
| 557 } |
| 558 |
| 559 // static |
| 560 void AppListService::InitAll(Profile* initial_profile) { |
| 561 Get()->Init(initial_profile); |
| 562 } |
596 | 563 |
597 @implementation AppListAnimationController | 564 @implementation AppListAnimationController |
598 | 565 |
599 - (BOOL)isClosing { | 566 - (BOOL)isClosing { |
600 return !!window_; | 567 return !!window_; |
601 } | 568 } |
602 | 569 |
603 - (void)animateWindow:(NSWindow*)window | 570 - (void)animateWindow:(NSWindow*)window |
604 targetOrigin:(NSPoint)targetOrigin | 571 targetOrigin:(NSPoint)targetOrigin |
605 closing:(BOOL)closing { | 572 closing:(BOOL)closing { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 [animation_ startAnimation]; | 604 [animation_ startAnimation]; |
638 } | 605 } |
639 | 606 |
640 - (void)animationDidEnd:(NSAnimation*)animation { | 607 - (void)animationDidEnd:(NSAnimation*)animation { |
641 [window_ close]; | 608 [window_ close]; |
642 window_.reset(); | 609 window_.reset(); |
643 animation_.reset(); | 610 animation_.reset(); |
644 } | 611 } |
645 | 612 |
646 @end | 613 @end |
647 | |
648 // static | |
649 AppListService* AppListService::Get() { | |
650 return AppListServiceMac::GetInstance(); | |
651 } | |
652 | |
653 // static | |
654 void AppListService::InitAll(Profile* initial_profile) { | |
655 Get()->Init(initial_profile); | |
656 } | |
OLD | NEW |