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

Side by Side Diff: chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc

Issue 223823004: Improving the user transition to add special cases for maximized windows and make the transition "m… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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
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 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" 5 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
6 6
7 #include "apps/app_window.h" 7 #include "apps/app_window.h"
8 #include "apps/app_window_registry.h" 8 #include "apps/app_window_registry.h"
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/desktop_background/user_wallpaper_delegate.h" 10 #include "ash/desktop_background/user_wallpaper_delegate.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 // in / out. 54 // in / out.
55 static int kAnimationTimeMS = 100; 55 static int kAnimationTimeMS = 100;
56 56
57 // The animation time in millseconds for the fade in and / or out when switching 57 // The animation time in millseconds for the fade in and / or out when switching
58 // users. 58 // users.
59 static int kUserFadeTimeMS = 110; 59 static int kUserFadeTimeMS = 110;
60 60
61 // The animation time in ms for a window which get teleported to another screen. 61 // The animation time in ms for a window which get teleported to another screen.
62 static int kTeleportAnimationTimeMS = 300; 62 static int kTeleportAnimationTimeMS = 300;
63 63
64 // The minimal possible animation time for animations which should happen
65 // "instantly".
66 static int kMinimalAnimationTime = 1;
oshima 2014/04/03 19:21:41 kMinimalAnimationTimeMs (assuming it's millisecond
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Done.
67
64 // Checks if a given event is a user event. 68 // Checks if a given event is a user event.
65 bool IsUserEvent(ui::Event* e) { 69 bool IsUserEvent(ui::Event* e) {
oshima 2014/04/03 19:21:41 const ui::Event*
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Done.
66 if (e) { 70 if (e) {
67 ui::EventType type = e->type(); 71 ui::EventType type = e->type();
68 if (type != ui::ET_CANCEL_MODE && 72 if (type != ui::ET_CANCEL_MODE &&
69 type != ui::ET_UMA_DATA && 73 type != ui::ET_UMA_DATA &&
70 type != ui::ET_UNKNOWN) 74 type != ui::ET_UNKNOWN)
71 return true; 75 return true;
72 } 76 }
73 return false; 77 return false;
74 } 78 }
75 79
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 233
230 DISALLOW_COPY_AND_ASSIGN(AppObserver); 234 DISALLOW_COPY_AND_ASSIGN(AppObserver);
231 }; 235 };
232 236
233 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( 237 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS(
234 const std::string& current_user_id) 238 const std::string& current_user_id)
235 : current_user_id_(current_user_id), 239 : current_user_id_(current_user_id),
236 notification_blocker_(new MultiUserNotificationBlockerChromeOS( 240 notification_blocker_(new MultiUserNotificationBlockerChromeOS(
237 message_center::MessageCenter::Get(), this, current_user_id)), 241 message_center::MessageCenter::Get(), this, current_user_id)),
238 suppress_visibility_changes_(false), 242 suppress_visibility_changes_(false),
239 animations_disabled_(false) { 243 screen_cover_(NO_USER_COVERS_SCREEN),
244 animation_step_(ANIMATION_STEP_ENDED),
245 animations_disabled_(false),
246 wallpaper_user_id_(current_user_id) {
240 // Add a session state observer to be able to monitor session changes. 247 // Add a session state observer to be able to monitor session changes.
241 if (ash::Shell::HasInstance()) 248 if (ash::Shell::HasInstance())
242 ash::Shell::GetInstance()->session_state_delegate()-> 249 ash::Shell::GetInstance()->session_state_delegate()->
243 AddSessionStateObserver(this); 250 AddSessionStateObserver(this);
244 251
245 // The BrowserListObserver would have been better to use then the old 252 // The BrowserListObserver would have been better to use then the old
246 // notification system, but that observer fires before the window got created. 253 // notification system, but that observer fires before the window got created.
247 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, 254 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY,
248 content::NotificationService::AllSources()); 255 content::NotificationService::AllSources());
249 256
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 observers_.AddObserver(observer); 411 observers_.AddObserver(observer);
405 } 412 }
406 413
407 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { 414 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) {
408 observers_.RemoveObserver(observer); 415 observers_.RemoveObserver(observer);
409 } 416 }
410 417
411 void MultiUserWindowManagerChromeOS::ActiveUserChanged( 418 void MultiUserWindowManagerChromeOS::ActiveUserChanged(
412 const std::string& user_id) { 419 const std::string& user_id) {
413 DCHECK(user_id != current_user_id_); 420 DCHECK(user_id != current_user_id_);
414 current_user_id_ = user_id;
415 // If there is an animation in progress finish the pending switch which also
416 // kills the timer (if there is one).
417 if (user_changed_animation_timer_.get())
418 TransitionUser(SHOW_NEW_USER);
419 421
420 // Start the animation by hiding the old user. 422 // Kick off a new animation (this will first finish outstanding animations).
421 TransitionUser(HIDE_OLD_USER); 423 StartUserTransitionAnimation(user_id);
422 424
423 // If animations are disabled we immediately switch to the new user, otherwise 425 // Immediately switch to new layer if animations are disabled, otherwise
424 // we create a timer which will fade in the new user once the other user has 426 // create a timer which will fade in the new user once the other user has
425 // been faded away. 427 // been faded away.
426 if (animations_disabled_) { 428 if (animations_disabled_) {
427 TransitionUser(SHOW_NEW_USER); 429 while (ANIMATION_STEP_ENDED != animation_step_)
430 AdvanceUserTransitionAnimation();
428 } else { 431 } else {
429 user_changed_animation_timer_.reset(new base::Timer( 432 user_changed_animation_timer_.reset(new base::Timer(
430 FROM_HERE, 433 FROM_HERE,
431 base::TimeDelta::FromMilliseconds(kUserFadeTimeMS), 434 base::TimeDelta::FromMilliseconds(kUserFadeTimeMS),
432 base::Bind(&MultiUserWindowManagerChromeOS::TransitionUser, 435 base::Bind(
433 base::Unretained(this), 436 &MultiUserWindowManagerChromeOS::AdvanceUserTransitionAnimation,
434 SHOW_NEW_USER), 437 base::Unretained(this)),
oshima 2014/04/03 19:21:41 can you change to use weak pointer? 110 ms is a bi
oshima 2014/04/03 20:13:20 never mind. I somehow thought it's passed to messa
435 false)); 438 true));
436 user_changed_animation_timer_->Reset(); 439 user_changed_animation_timer_->Reset();
437 } 440 }
438 } 441 }
439 442
440 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { 443 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) {
441 if (GetWindowOwner(window).empty()) { 444 if (GetWindowOwner(window).empty()) {
442 // This must be a window in the transient chain - remove it and its 445 // This must be a window in the transient chain - remove it and its
443 // children from the owner. 446 // children from the owner.
444 RemoveTransientOwnerRecursive(window); 447 RemoveTransientOwnerRecursive(window);
445 return; 448 return;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 SetWindowVisibility(window, true, kTeleportAnimationTimeMS); 576 SetWindowVisibility(window, true, kTeleportAnimationTimeMS);
574 } else { 577 } else {
575 SetWindowVisibility(window, false, kTeleportAnimationTimeMS); 578 SetWindowVisibility(window, false, kTeleportAnimationTimeMS);
576 } 579 }
577 580
578 // Notify entry change. 581 // Notify entry change.
579 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window)); 582 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window));
580 return true; 583 return true;
581 } 584 }
582 585
583 void MultiUserWindowManagerChromeOS::TransitionUser(
584 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
585 TransitionWallpaper(animation_step);
586 TransitionUserShelf(animation_step);
587
588 // Disable the window position manager and the MRU window tracker temporarily.
589 scoped_ptr<UserChangeActionDisabler> disabler(new UserChangeActionDisabler);
590
591 // We need to show/hide the windows in the same order as they were created in
592 // their parent window(s) to keep the layer / window hierarchy in sync. To
593 // achieve that we first collect all parent windows and then enumerate all
594 // windows in those parent windows and show or hide them accordingly.
595
596 // Create a list of all parent windows we have to check and their parents.
597 std::set<aura::Window*> parent_list;
598 for (WindowToEntryMap::iterator it = window_to_entry_.begin();
599 it != window_to_entry_.end(); ++it) {
600 aura::Window* parent = it->first->parent();
601 if (parent_list.find(parent) == parent_list.end())
602 parent_list.insert(parent);
603 }
604
605 // Traverse the found parent windows to handle their child windows in order of
606 // their appearance.
607 for (std::set<aura::Window*>::iterator it_parents = parent_list.begin();
608 it_parents != parent_list.end(); ++it_parents) {
609 const aura::Window::Windows window_list = (*it_parents)->children();
610 for (aura::Window::Windows::const_iterator it_window = window_list.begin();
611 it_window != window_list.end(); ++it_window) {
612 aura::Window* window = *it_window;
613 WindowToEntryMap::iterator it_map = window_to_entry_.find(window);
614 if (it_map != window_to_entry_.end()) {
615 bool should_be_visible =
616 it_map->second->show_for_user() == current_user_id_ &&
617 it_map->second->show();
618 bool is_visible = window->IsVisible();
619 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
620 if (animation_step == SHOW_NEW_USER &&
621 it_map->second->owner() == current_user_id_ &&
622 it_map->second->show_for_user() != current_user_id_ &&
623 window_state->IsMinimized()) {
624 // Pull back minimized visiting windows to the owners desktop.
625 ShowWindowForUserIntern(window, current_user_id_);
626 window_state->Unminimize();
627 } else if (should_be_visible != is_visible &&
628 should_be_visible == (animation_step == SHOW_NEW_USER)) {
629 SetWindowVisibility(window, should_be_visible, kUserFadeTimeMS);
630 }
631 }
632 }
633 }
634
635 // Activation and real switch are happening after the other user gets shown.
636 if (animation_step == SHOW_NEW_USER) {
637 // Finally we need to restore the previously active window.
638 ash::MruWindowTracker::WindowList mru_list =
639 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
640 if (mru_list.size()) {
641 aura::Window* window = mru_list[0];
642 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
643 if (IsWindowOnDesktopOfUser(window, current_user_id_) &&
644 !window_state->IsMinimized()) {
645 aura::client::ActivationClient* client =
646 aura::client::GetActivationClient(window->GetRootWindow());
647 // Several unit tests come here without an activation client.
648 if (client)
649 client->ActivateWindow(window);
650 }
651 }
652
653 // This is called directly here to make sure notification_blocker will see
654 // the new window status.
655 notification_blocker_->ActiveUserChanged(current_user_id_);
656
657 // We can reset the timer at this point.
658 // Note: The timer can be destroyed while it is performing its task.
659 user_changed_animation_timer_.reset();
660 }
661 }
662
663 void MultiUserWindowManagerChromeOS::TransitionWallpaper(
664 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
665 // Handle the wallpaper switch.
666 ash::UserWallpaperDelegate* wallpaper_delegate =
667 ash::Shell::GetInstance()->user_wallpaper_delegate();
668 if (animation_step == HIDE_OLD_USER) {
669 // Set the wallpaper cross dissolve animation duration to our complete
670 // animation cycle for a fade in and fade out.
671 wallpaper_delegate->SetAnimationDurationOverride(2 * kUserFadeTimeMS);
672 chromeos::WallpaperManager::Get()->SetUserWallpaperDelayed(
673 current_user_id_);
674 } else {
675 // Revert the wallpaper cross dissolve animation duration back to the
676 // default.
677 wallpaper_delegate->SetAnimationDurationOverride(0);
678 }
679 }
680
681 void MultiUserWindowManagerChromeOS::TransitionUserShelf(
682 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
683 // The shelf animation duration override.
684 int duration_override = kUserFadeTimeMS;
685 // Handle the shelf order of items. This is done once the old user is hidden.
686 if (animation_step == SHOW_NEW_USER) {
687 // Some unit tests have no ChromeLauncherController.
688 if (ChromeLauncherController::instance())
689 ChromeLauncherController::instance()->ActiveUserChanged(current_user_id_);
690 // We kicked off the shelf animation in the command above. As such we can
691 // disable the override now again.
692 duration_override = 0;
693 }
694
695 if (animations_disabled_)
696 return;
697
698 ash::Shell::RootWindowControllerList controller =
699 ash::Shell::GetInstance()->GetAllRootWindowControllers();
700 for (ash::Shell::RootWindowControllerList::iterator it1 = controller.begin();
701 it1 != controller.end(); ++it1) {
702 (*it1)->GetShelfLayoutManager()->SetAnimationDurationOverride(
703 duration_override);
704 }
705
706 // For each root window hide the shelf.
707 if (animation_step == HIDE_OLD_USER) {
708 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
709 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
710 iter != root_windows.end(); ++iter) {
711 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(
712 ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, *iter);
713 }
714 }
715 }
716
717 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) { 586 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) {
718 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can 587 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can
719 // come here with no valid window. 588 // come here with no valid window.
720 if (!browser->window() || !browser->window()->GetNativeWindow()) 589 if (!browser->window() || !browser->window()->GetNativeWindow())
721 return; 590 return;
722 SetWindowOwner(browser->window()->GetNativeWindow(), 591 SetWindowOwner(browser->window()->GetNativeWindow(),
723 multi_user_util::GetUserIDFromProfile(browser->profile())); 592 multi_user_util::GetUserIDFromProfile(browser->profile()));
724 } 593 }
725 594
726 void MultiUserWindowManagerChromeOS::SetWindowVisibility( 595 void MultiUserWindowManagerChromeOS::SetWindowVisibility(
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 if (visible) 731 if (visible)
863 window->Show(); 732 window->Show();
864 else 733 else
865 window->Hide(); 734 window->Hide();
866 735
867 // Make sure that animations have no influence on the window state after the 736 // Make sure that animations have no influence on the window state after the
868 // call. 737 // call.
869 DCHECK_EQ(visible, window->IsVisible()); 738 DCHECK_EQ(visible, window->IsVisible());
870 } 739 }
871 740
741 void MultiUserWindowManagerChromeOS::StartUserTransitionAnimation(
742 const std::string& user_id) {
743 // If there is an animation in progress, finish it before the new one starts.
744 while (ANIMATION_STEP_ENDED != animation_step_)
745 AdvanceUserTransitionAnimation();
746
747 // Set up the transition parameters before the animation gets called the first
748 // time. Note that the screen cover state needs to be analyzed and remembered
749 // before the animation starts and after the user got set.
750 current_user_id_ = user_id;
751 screen_cover_ = GetScreenCover();
752 animation_step_ = ANIMATION_STEP_HIDE_OLD_USER;
753
754 AdvanceUserTransitionAnimation();
755 }
756
757 void MultiUserWindowManagerChromeOS::AdvanceUserTransitionAnimation() {
758 DCHECK_NE(animation_step_, ANIMATION_STEP_ENDED);
759
760 TransitionWallpaper(animation_step_);
761 TransitionUserShelf(animation_step_);
762 TransitionWindows(animation_step_);
763
764 // Advance to the next step.
765 if (animation_step_ == ANIMATION_STEP_FINALIZE) {
oshima 2014/04/03 19:21:41 optional: using switch would make it easy to under
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Done.
766 user_changed_animation_timer_.reset();
767 animation_step_ = ANIMATION_STEP_ENDED;
768 } else {
769 animation_step_ = animation_step_ == ANIMATION_STEP_HIDE_OLD_USER ?
770 ANIMATION_STEP_SHOW_NEW_USER : ANIMATION_STEP_FINALIZE;
771 }
772 }
773
774 void MultiUserWindowManagerChromeOS::TransitionWallpaper(
775 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
776 // Handle the wallpaper switch.
777 ash::UserWallpaperDelegate* wallpaper_delegate =
778 ash::Shell::GetInstance()->user_wallpaper_delegate();
779 if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) {
780 // Set the wallpaper cross dissolve animation duration to our complete
781 // animation cycle for a fade in and fade out.
782 wallpaper_delegate->SetAnimationDurationOverride(
783 NO_USER_COVERS_SCREEN == screen_cover_ ? (2 * kUserFadeTimeMS) :
784 kMinimalAnimationTime);
785 if (screen_cover_ != NEW_USER_COVERS_SCREEN) {
786 chromeos::WallpaperManager::Get()->SetUserWallpaperNow(current_user_id_);
787 wallpaper_user_id_ = NO_USER_COVERS_SCREEN == screen_cover_ ?
788 (wallpaper_user_id_ + "->" + current_user_id_) : current_user_id_;
789 }
790 } else if (animation_step == ANIMATION_STEP_FINALIZE) {
791 // Revert the wallpaper cross dissolve animation duration back to the
792 // default.
793 if (screen_cover_ == NEW_USER_COVERS_SCREEN)
794 chromeos::WallpaperManager::Get()->SetUserWallpaperNow(current_user_id_);
795
796 // Coming here the wallpaper user id is the final result. No matter how we
797 // got here.
798 wallpaper_user_id_ = current_user_id_;
799 wallpaper_delegate->SetAnimationDurationOverride(0);
800 }
801 }
802
803 void MultiUserWindowManagerChromeOS::TransitionUserShelf(
804 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
805 // The shelf animation duration override.
806 int duration_override = kUserFadeTimeMS;
807 // Handle the shelf order of items. This is done once the old user is hidden.
808 if (animation_step == ANIMATION_STEP_SHOW_NEW_USER) {
809 // Some unit tests have no ChromeLauncherController.
810 if (ChromeLauncherController::instance())
811 ChromeLauncherController::instance()->ActiveUserChanged(current_user_id_);
812 // We kicked off the shelf animation in the command above. As such we can
813 // disable the override now again.
814 duration_override = 0;
815 }
816
817 if (animations_disabled_ || animation_step == ANIMATION_STEP_FINALIZE)
818 return;
819
820 ash::Shell::RootWindowControllerList controller =
821 ash::Shell::GetInstance()->GetAllRootWindowControllers();
822 for (ash::Shell::RootWindowControllerList::iterator it1 = controller.begin();
823 it1 != controller.end(); ++it1) {
824 (*it1)->GetShelfLayoutManager()->SetAnimationDurationOverride(
825 duration_override);
826 }
827
828 // For each root window hide the shelf.
829 if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) {
830 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
831 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
832 iter != root_windows.end(); ++iter) {
833 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(
834 ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, *iter);
oshima 2014/04/03 19:21:41 q: how/where the user's shelf setting is restored?
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Added comment to explain.
835 }
836 }
837 }
838
839 void MultiUserWindowManagerChromeOS::TransitionWindows(
840 AnimationStep animation_step) {
841 // Disable the window position manager and the MRU window tracker temporarily.
842 scoped_ptr<UserChangeActionDisabler> disabler(new UserChangeActionDisabler);
oshima 2014/04/03 19:21:41 This can be just created on stack ?
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Done.
843
844 if (animation_step == ANIMATION_STEP_HIDE_OLD_USER ||
845 (animation_step == ANIMATION_STEP_FINALIZE &&
846 screen_cover_ == BOTH_USERS_COVER_SCREEN)) {
847 // We need to show/hide the windows in the same order as they were created
848 // in their parent window(s) to keep the layer / window hierarchy in sync.
849 // To achieve that we first collect all parent windows and then enumerate
850 // all windows in those parent windows and show or hide them accordingly.
851
852 // Create a list of all parent windows we have to check.
853 std::set<aura::Window*> parent_list;
854 for (WindowToEntryMap::iterator it = window_to_entry_.begin();
855 it != window_to_entry_.end(); ++it) {
856 aura::Window* parent = it->first->parent();
857 if (parent_list.find(parent) == parent_list.end())
858 parent_list.insert(parent);
859 }
860
861 for (std::set<aura::Window*>::iterator it_parents = parent_list.begin();
862 it_parents != parent_list.end(); ++it_parents) {
863 const aura::Window::Windows window_list = (*it_parents)->children();
864 // In case of |BOTH_USERS_COVER_SCREEN| the desktop might shine through
865 // if all windows fade (in or out). To avoid this we only fade the topmost
866 // covering window (in / out) and make / keep all other covering windows
867 // visible while animating. |foreground_window_found| will get set when
868 // the top fading window was found.
869 bool foreground_window_found = false;
870 // Covering windows which follow the fade direction will also fade - all
871 // others will get immediately shown / kept shown until the animation is
872 // finished.
873 bool foreground_becomes_visible = false;
874 for (aura::Window::Windows::const_reverse_iterator it_window =
875 window_list.rbegin();
876 it_window != window_list.rend(); ++it_window) {
877 aura::Window* window = *it_window;
878 WindowToEntryMap::iterator it_map = window_to_entry_.find(window);
879 if (it_map != window_to_entry_.end()) {
880 bool should_be_visible =
881 it_map->second->show_for_user() == current_user_id_ &&
882 it_map->second->show();
883 bool is_visible = window->IsVisible();
884 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
885 if (it_map->second->owner() == current_user_id_ &&
886 it_map->second->show_for_user() != current_user_id_ &&
887 window_state->IsMinimized()) {
888 // Pull back minimized visiting windows to the owners desktop.
889 ShowWindowForUserIntern(window, current_user_id_);
890 window_state->Unminimize();
891 } else if (should_be_visible != is_visible) {
892 bool animate = true;
893 int duration = animation_step == ANIMATION_STEP_FINALIZE ?
894 kMinimalAnimationTime : (2 * kUserFadeTimeMS);
895 if (animation_step != ANIMATION_STEP_FINALIZE &&
896 screen_cover_ == BOTH_USERS_COVER_SCREEN &&
897 CoversScreen(window)) {
898 if (!foreground_window_found) {
899 foreground_window_found = true;
900 foreground_becomes_visible = should_be_visible;
901 } else if (should_be_visible != foreground_becomes_visible) {
902 // Covering windows behind the foreground window which are
903 // inverting their visibility should immediately become visible
904 // or stay visible until the animation is finished.
905 duration = kMinimalAnimationTime;
906 if (!should_be_visible)
907 animate = false;
908 }
909 }
910 if (animate)
911 SetWindowVisibility(window, should_be_visible, duration);
912 }
913 }
914 }
915 }
916 }
917
918 // Activation and real switch are happening after the other user gets shown.
919 if (animation_step == ANIMATION_STEP_SHOW_NEW_USER) {
920 // Finally we need to restore the previously active window.
921 ash::MruWindowTracker::WindowList mru_list =
922 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
923 if (mru_list.size()) {
oshima 2014/04/03 19:21:41 !empty()
Mr4D (OOO till 08-26) 2014/04/03 22:57:00 Done.
924 aura::Window* window = mru_list[0];
925 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
926 if (IsWindowOnDesktopOfUser(window, current_user_id_) &&
927 !window_state->IsMinimized()) {
928 aura::client::ActivationClient* client =
929 aura::client::GetActivationClient(window->GetRootWindow());
930 // Several unit tests come here without an activation client.
931 if (client)
932 client->ActivateWindow(window);
933 }
934 }
935
936 // This is called directly here to make sure notification_blocker will see
937 // the new window status.
938 notification_blocker_->ActiveUserChanged(current_user_id_);
939 }
940 }
941
942 MultiUserWindowManagerChromeOS::TransitioningScreenCover
943 MultiUserWindowManagerChromeOS::GetScreenCover() {
944 TransitioningScreenCover cover = NO_USER_COVERS_SCREEN;
945 for (WindowToEntryMap::iterator it_map = window_to_entry_.begin();
946 it_map != window_to_entry_.end();
947 ++it_map) {
948 aura::Window* window = it_map->first;
949 if (window->IsVisible() && CoversScreen(window)) {
950 if (cover == NEW_USER_COVERS_SCREEN)
951 return BOTH_USERS_COVER_SCREEN;
952 else
953 cover = OLD_USER_COVERS_SCREEN;
954 } else if (IsWindowOnDesktopOfUser(window, current_user_id_) &&
955 CoversScreen(window)) {
956 if (cover == OLD_USER_COVERS_SCREEN)
957 return BOTH_USERS_COVER_SCREEN;
958 else
959 cover = NEW_USER_COVERS_SCREEN;
960 }
961 }
962 return cover;
963 }
964
965 bool MultiUserWindowManagerChromeOS::CoversScreen(aura::Window* window) {
966 // Full screen covers the screen naturally. Maximized however can be smaller
967 // then the work area - so we do not check for that mode, but instead check if
968 // the window is covering everything.
969 if (ash::wm::GetWindowState(window)->IsFullscreen())
970 return true;
971 gfx::Rect bounds = window->GetBoundsInRootWindow();
972 gfx::Rect work_area = gfx::Screen::GetScreenFor(window)->
973 GetDisplayNearestWindow(window).work_area();
974 bounds.Intersect(work_area);
975 return work_area == bounds;
976 }
977
872 } // namespace chrome 978 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698