Index: chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc |
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc |
index 9c9de92b83f593f649bc19a483eaab412db35aef..82ce2f822a278710fb85ccb7e5630799c905450a 100644 |
--- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc |
+++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc |
@@ -7,6 +7,7 @@ |
#include "ash/desktop_background/user_wallpaper_delegate.h" |
#include "ash/root_window_controller.h" |
#include "ash/shelf/shelf_layout_manager.h" |
+#include "ash/shelf/shelf_widget.h" |
#include "ash/shell.h" |
#include "ash/wm/mru_window_tracker.h" |
#include "ash/wm/window_positioner.h" |
@@ -53,7 +54,7 @@ UserSwichAnimatorChromeOS::UserSwichAnimatorChromeOS( |
new_user_id_(new_user_id), |
animation_speed_ms_(animation_speed_ms), |
animation_step_(ANIMATION_STEP_HIDE_OLD_USER), |
- screen_cover_(GetScreenCover()) { |
+ screen_cover_(GetScreenCover(NULL)) { |
AdvanceUserTransitionAnimation(); |
if (!animation_speed_ms_) { |
@@ -156,21 +157,33 @@ void UserSwichAnimatorChromeOS::TransitionWallpaper( |
void UserSwichAnimatorChromeOS::TransitionUserShelf( |
AnimationStep animation_step) { |
+ ChromeLauncherController* chrome_launcher_controller = |
+ ChromeLauncherController::instance(); |
// The shelf animation duration override. |
int duration_override = animation_speed_ms_; |
// Handle the shelf order of items. This is done once the old user is hidden. |
if (animation_step == ANIMATION_STEP_SHOW_NEW_USER) { |
// Some unit tests have no ChromeLauncherController. |
- if (ChromeLauncherController::instance()) |
- ChromeLauncherController::instance()->ActiveUserChanged(new_user_id_); |
- // We kicked off the shelf animation in the command above. As such we can |
- // disable the override now again. |
+ if (chrome_launcher_controller) |
+ chrome_launcher_controller->ActiveUserChanged(new_user_id_); |
+ // Hide the black rectangle on top of each shelf again. |
+ aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
+ for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
+ iter != root_windows.end(); ++iter) { |
+ ash::ShelfWidget* shelf = |
+ ash::RootWindowController::ForWindow(*iter)->shelf(); |
+ shelf->HideShelfBehindBlackBar(false, duration_override); |
+ } |
+ // We kicked off the shelf animation above and the override can be |
+ // removed. |
duration_override = 0; |
} |
if (!animation_speed_ms_ || animation_step == ANIMATION_STEP_FINALIZE) |
return; |
+ // Note: The animation duration override will be set before the old user gets |
+ // hidden and reset after the animations for the new user got kicked off. |
ash::Shell::RootWindowControllerList controller = |
ash::Shell::GetInstance()->GetAllRootWindowControllers(); |
for (ash::Shell::RootWindowControllerList::iterator iter = controller.begin(); |
@@ -179,11 +192,28 @@ void UserSwichAnimatorChromeOS::TransitionUserShelf( |
duration_override); |
} |
+ if (animation_step != ANIMATION_STEP_HIDE_OLD_USER) |
+ return; |
+ |
// For each root window hide the shelf. |
- if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) { |
- aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
- for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
- iter != root_windows.end(); ++iter) { |
+ aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
+ |
+ for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
+ iter != root_windows.end(); ++iter) { |
+ // Hiding the shelf will cause a resize on a maximized window. |
+ // If the shelf is then shown for the following user in the same location, |
+ // the window gets resized again. Since each resize can cause a considerable |
+ // CPU usage and therefore effect jank, we should avoid hiding the shelf if |
+ // the start and end location are the same and cover the shelf instead with |
+ // a black rectangle on top. |
+ if (GetScreenCover(*iter) != NO_USER_COVERS_SCREEN && |
+ (!chrome_launcher_controller || |
+ !chrome_launcher_controller->ShelfBoundsChangesProbablyWithUser( |
+ *iter, new_user_id_))) { |
+ ash::ShelfWidget* shelf = |
+ ash::RootWindowController::ForWindow(*iter)->shelf(); |
+ shelf->HideShelfBehindBlackBar(true, duration_override); |
+ } else { |
// This shelf change is only part of the animation and will be updated by |
// ChromeLauncherController::ActiveUserChanged() to the new users value. |
// Note that the user preference will not be changed. |
@@ -300,13 +330,15 @@ void UserSwichAnimatorChromeOS::TransitionWindows( |
} |
UserSwichAnimatorChromeOS::TransitioningScreenCover |
-UserSwichAnimatorChromeOS::GetScreenCover() { |
+UserSwichAnimatorChromeOS::GetScreenCover(aura::Window* root_window) { |
TransitioningScreenCover cover = NO_USER_COVERS_SCREEN; |
for (MultiUserWindowManagerChromeOS::WindowToEntryMap::const_iterator it_map = |
owner_->window_to_entry().begin(); |
it_map != owner_->window_to_entry().end(); |
++it_map) { |
aura::Window* window = it_map->first; |
+ if (root_window && window->GetRootWindow() != root_window) |
+ continue; |
if (window->IsVisible() && CoversScreen(window)) { |
if (cover == NEW_USER_COVERS_SCREEN) |
return BOTH_USERS_COVER_SCREEN; |