Index: ash/wm/activation_controller.cc |
diff --git a/ash/wm/activation_controller.cc b/ash/wm/activation_controller.cc |
deleted file mode 100644 |
index 328c34cafa7175c6c65920a1cec47fd70a8be64e..0000000000000000000000000000000000000000 |
--- a/ash/wm/activation_controller.cc |
+++ /dev/null |
@@ -1,413 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "ash/wm/activation_controller.h" |
- |
-#include "ash/root_window_controller.h" |
-#include "ash/shell.h" |
-#include "ash/shell_window_ids.h" |
-#include "ash/wm/activation_controller_delegate.h" |
-#include "ash/wm/property_util.h" |
-#include "ash/wm/window_util.h" |
-#include "base/auto_reset.h" |
-#include "ui/aura/client/activation_change_observer.h" |
-#include "ui/aura/client/activation_delegate.h" |
-#include "ui/aura/client/aura_constants.h" |
-#include "ui/aura/client/focus_client.h" |
-#include "ui/aura/env.h" |
-#include "ui/aura/root_window.h" |
-#include "ui/aura/window.h" |
-#include "ui/aura/window_delegate.h" |
-#include "ui/base/ui_base_types.h" |
-#include "ui/compositor/layer.h" |
-#include "ui/views/corewm/window_modality_controller.h" |
- |
-namespace ash { |
-namespace internal { |
-namespace { |
- |
-// These are the list of container ids of containers which may contain windows |
-// that need to be activated in the order that they should be activated. |
-const int kWindowContainerIds[] = { |
- kShellWindowId_LockSystemModalContainer, |
- kShellWindowId_SettingBubbleContainer, |
- kShellWindowId_LockScreenContainer, |
- kShellWindowId_SystemModalContainer, |
- kShellWindowId_AlwaysOnTopContainer, |
- kShellWindowId_AppListContainer, |
- kShellWindowId_DefaultContainer, |
- |
- // Docked, panel, launcher and status are intentionally checked after other |
- // containers even though these layers are higher. The user expects their |
- // windows to be focused before these elements. |
- kShellWindowId_DockedContainer, |
- kShellWindowId_PanelContainer, |
- kShellWindowId_ShelfContainer, |
- kShellWindowId_StatusContainer, |
-}; |
- |
-bool BelongsToContainerWithEqualOrGreaterId(const aura::Window* window, |
- int container_id) { |
- for (; window; window = window->parent()) { |
- if (window->id() >= container_id) |
- return true; |
- } |
- return false; |
-} |
- |
-// Returns true if children of |window| can be activated. |
-// These are the only containers in which windows can receive focus. |
-bool SupportsChildActivation(aura::Window* window) { |
- for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { |
- if (window->id() == kWindowContainerIds[i]) |
- return true; |
- } |
- return false; |
-} |
- |
-bool HasModalTransientChild(aura::Window* window) { |
- aura::Window::Windows::const_iterator it; |
- for (it = window->transient_children().begin(); |
- it != window->transient_children().end(); |
- ++it) { |
- if ((*it)->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_WINDOW) |
- return true; |
- } |
- return false; |
-} |
- |
-// See description in VisibilityMatches. |
-enum ActivateVisibilityType { |
- TARGET_VISIBILITY, |
- CURRENT_VISIBILITY, |
-}; |
- |
-// Used by CanActivateWindowWithEvent() to test the visibility of a window. |
-// This is used by two distinct code paths: |
-// . when activating from an event we only care about the actual visibility. |
-// . when activating because of a keyboard accelerator, in which case we |
-// care about the TargetVisibility. |
-bool VisibilityMatches(aura::Window* window, ActivateVisibilityType type) { |
- bool visible = (type == CURRENT_VISIBILITY) ? window->IsVisible() : |
- window->TargetVisibility(); |
- return visible || wm::IsWindowMinimized(window) || |
- (window->TargetVisibility() && |
- (window->parent()->id() == kShellWindowId_DefaultContainer || |
- window->parent()->id() == kShellWindowId_LockScreenContainer)); |
-} |
- |
-// Returns true if |window| can be activated or deactivated. |
-// A window manager typically defines some notion of "top level window" that |
-// supports activation/deactivation. |
-bool CanActivateWindowWithEvent(aura::Window* window, |
- const ui::Event* event, |
- ActivateVisibilityType visibility_type) { |
- return window && |
- VisibilityMatches(window, visibility_type) && |
- (!aura::client::GetActivationDelegate(window) || |
- aura::client::GetActivationDelegate(window)->ShouldActivate()) && |
- SupportsChildActivation(window->parent()) && |
- (BelongsToContainerWithEqualOrGreaterId( |
- window, kShellWindowId_SystemModalContainer) || |
- !Shell::GetInstance()->IsSystemModalWindowOpen()); |
-} |
- |
-// When a modal window is activated, we bring its entire transient parent chain |
-// to the front. This function must be called before the modal transient is |
-// stacked at the top to ensure correct stacking order. |
-void StackTransientParentsBelowModalWindow(aura::Window* window) { |
- if (window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_WINDOW) |
- return; |
- |
- aura::Window* transient_parent = window->transient_parent(); |
- while (transient_parent) { |
- transient_parent->parent()->StackChildAtTop(transient_parent); |
- transient_parent = transient_parent->transient_parent(); |
- } |
-} |
- |
-aura::Window* FindFocusableWindowFor(aura::Window* window) { |
- while (window && !window->CanFocus()) |
- window = window->parent(); |
- return window; |
-} |
- |
-} // namespace |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, public: |
- |
-ActivationController::ActivationController( |
- aura::client::FocusClient* focus_client, |
- ActivationControllerDelegate* delegate) |
- : focus_client_(focus_client), |
- updating_activation_(false), |
- active_window_(NULL), |
- observer_manager_(this), |
- delegate_(delegate) { |
- aura::Env::GetInstance()->AddObserver(this); |
- focus_client_->AddObserver(this); |
-} |
- |
-ActivationController::~ActivationController() { |
- aura::Env::GetInstance()->RemoveObserver(this); |
- focus_client_->RemoveObserver(this); |
-} |
- |
-// static |
-aura::Window* ActivationController::GetActivatableWindow( |
- aura::Window* window, |
- const ui::Event* event) { |
- aura::Window* parent = window->parent(); |
- aura::Window* child = window; |
- while (parent) { |
- if (CanActivateWindowWithEvent(child, event, CURRENT_VISIBILITY)) |
- return child; |
- // If |child| isn't activatable, but has transient parent, trace |
- // that path instead. |
- if (child->transient_parent()) |
- return GetActivatableWindow(child->transient_parent(), event); |
- parent = parent->parent(); |
- child = child->parent(); |
- } |
- return NULL; |
-} |
- |
-bool ActivationController::CanActivateWindow(aura::Window* window) const { |
- return CanActivateWindowWithEvent(window, NULL, TARGET_VISIBILITY) && |
- !HasModalTransientChild(window); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, aura::client::ActivationClient implementation: |
- |
-void ActivationController::AddObserver( |
- aura::client::ActivationChangeObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void ActivationController::RemoveObserver( |
- aura::client::ActivationChangeObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-void ActivationController::ActivateWindow(aura::Window* window) { |
- ActivateWindowWithEvent(window, NULL); |
-} |
- |
-void ActivationController::DeactivateWindow(aura::Window* window) { |
- if (window) |
- ActivateNextWindow(window); |
-} |
- |
-aura::Window* ActivationController::GetActiveWindow() { |
- return active_window_; |
-} |
- |
-aura::Window* ActivationController::GetActivatableWindow(aura::Window* window) { |
- return GetActivatableWindow(window, NULL); |
-} |
- |
-aura::Window* ActivationController::GetToplevelWindow(aura::Window* window) { |
- return GetActivatableWindow(window, NULL); |
-} |
- |
-bool ActivationController::OnWillFocusWindow(aura::Window* window, |
- const ui::Event* event) { |
- return CanActivateWindowWithEvent( |
- GetActivatableWindow(window, event), event, CURRENT_VISIBILITY); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, aura::WindowObserver implementation: |
- |
-void ActivationController::OnWindowVisibilityChanged(aura::Window* window, |
- bool visible) { |
- if (!visible) { |
- aura::Window* next_window = ActivateNextWindow(window); |
- if (next_window && next_window->parent() == window->parent()) { |
- // Despite the activation change, we need to keep the window being hidden |
- // stacked above the new window so it stays on top as it animates away. |
- window->layer()->parent()->StackAbove(window->layer(), |
- next_window->layer()); |
- } |
- } |
-} |
- |
-void ActivationController::OnWindowDestroying(aura::Window* window) { |
- // Don't use wm::IsActiveWidnow in case the |window| has already been |
- // removed from the root tree. |
- if (active_window_ == window) { |
- active_window_ = NULL; |
- FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, |
- observers_, |
- OnWindowActivated(NULL, window)); |
- ActivateWindow(GetTopmostWindowToActivate(window)); |
- } |
- observer_manager_.Remove(window); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, aura::EnvObserver implementation: |
- |
-void ActivationController::OnWindowInitialized(aura::Window* window) { |
- observer_manager_.Add(window); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, aura::RootWindowObserver implementation: |
- |
-void ActivationController::OnWindowFocused(aura::Window* gained_focus, |
- aura::Window* lost_focus) { |
- if (gained_focus) |
- ActivateWindow(GetActivatableWindow(gained_focus, NULL)); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, ui::EventHandler implementation: |
- |
-void ActivationController::OnKeyEvent(ui::KeyEvent* event) { |
-} |
- |
-void ActivationController::OnMouseEvent(ui::MouseEvent* event) { |
- if (event->type() == ui::ET_MOUSE_PRESSED) |
- FocusWindowWithEvent(event); |
-} |
- |
-void ActivationController::OnScrollEvent(ui::ScrollEvent* event) { |
-} |
- |
-void ActivationController::OnTouchEvent(ui::TouchEvent* event) { |
- if (event->type() == ui::ET_TOUCH_PRESSED) |
- FocusWindowWithEvent(event); |
-} |
- |
-void ActivationController::OnGestureEvent(ui::GestureEvent* event) { |
- if (event->type() == ui::ET_GESTURE_BEGIN && |
- event->details().touch_points() == 1) { |
- FocusWindowWithEvent(event); |
- } |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ActivationController, private: |
- |
-void ActivationController::ActivateWindowWithEvent(aura::Window* window, |
- const ui::Event* event) { |
- // Prevent recursion when called from focus. |
- if (updating_activation_) |
- return; |
- base::AutoReset<bool> in_activate_window(&updating_activation_, true); |
- |
- // We allow the delegate to change which window gets activated, or to prevent |
- // activation changes. |
- aura::Window* original_active_window = window; |
- window = delegate_->WillActivateWindow(window); |
- // TODO(beng): note that this breaks the previous behavior where an activation |
- // attempt by a window behind the lock screen would at least |
- // restack that window frontmost within its container. fix this. |
- if (!window && original_active_window != window) |
- return; |
- |
- // TODO(beng): This encapsulates additional Ash-specific restrictions on |
- // whether activation can change. Should move to the delegate. |
- if (window && !CanActivateWindowWithEvent(window, event, CURRENT_VISIBILITY)) |
- return; |
- |
- if (active_window_ == window) |
- return; |
- |
- aura::Window* old_active = active_window_; |
- active_window_ = window; |
- |
- if (window && |
- !window->Contains(aura::client::GetFocusClient(window)-> |
- GetFocusedWindow())) { |
- aura::client::GetFocusClient(window)->FocusWindow(window); |
- } |
- |
- if (window) { |
- StackTransientParentsBelowModalWindow(window); |
- window->parent()->StackChildAtTop(window); |
- } |
- |
- FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, |
- observers_, |
- OnWindowActivated(window, old_active)); |
- if (aura::client::GetActivationChangeObserver(old_active)) { |
- aura::client::GetActivationChangeObserver(old_active)->OnWindowActivated( |
- window, old_active); |
- } |
- if (aura::client::GetActivationChangeObserver(window)) { |
- aura::client::GetActivationChangeObserver(window)->OnWindowActivated( |
- window, old_active); |
- } |
-} |
- |
-aura::Window* ActivationController::ActivateNextWindow(aura::Window* window) { |
- aura::Window* next_window = NULL; |
- if (wm::IsActiveWindow(window)) { |
- next_window = GetTopmostWindowToActivate(window); |
- ActivateWindow(next_window); |
- } |
- return next_window; |
-} |
- |
-aura::Window* ActivationController::GetTopmostWindowToActivate( |
- aura::Window* ignore) const { |
- size_t current_container_index = 0; |
- // If the container of the window losing focus is in the list, start from that |
- // container. |
- aura::RootWindow* root = ignore->GetRootWindow(); |
- if (!root) |
- root = Shell::GetActiveRootWindow(); |
- for (size_t i = 0; ignore && i < arraysize(kWindowContainerIds); i++) { |
- aura::Window* container = Shell::GetContainer(root, kWindowContainerIds[i]); |
- if (container && container->Contains(ignore)) { |
- current_container_index = i; |
- break; |
- } |
- } |
- |
- // Look for windows to focus in that container and below. |
- aura::Window* window = NULL; |
- for (; !window && current_container_index < arraysize(kWindowContainerIds); |
- current_container_index++) { |
- aura::Window::Windows containers = Shell::GetContainersFromAllRootWindows( |
- kWindowContainerIds[current_container_index], |
- root); |
- for (aura::Window::Windows::const_iterator iter = containers.begin(); |
- iter != containers.end() && !window; ++iter) { |
- window = GetTopmostWindowToActivateInContainer((*iter), ignore); |
- } |
- } |
- return window; |
-} |
- |
-aura::Window* ActivationController::GetTopmostWindowToActivateInContainer( |
- aura::Window* container, |
- aura::Window* ignore) const { |
- for (aura::Window::Windows::const_reverse_iterator i = |
- container->children().rbegin(); |
- i != container->children().rend(); |
- ++i) { |
- if (*i != ignore && |
- CanActivateWindowWithEvent(*i, NULL, CURRENT_VISIBILITY) && |
- !wm::IsWindowMinimized(*i)) |
- return *i; |
- } |
- return NULL; |
-} |
- |
-void ActivationController::FocusWindowWithEvent(const ui::Event* event) { |
- aura::Window* window = static_cast<aura::Window*>(event->target()); |
- window = delegate_->WillFocusWindow(window); |
- if (GetActiveWindow() != window) { |
- aura::client::GetFocusClient(window)->FocusWindow( |
- FindFocusableWindowFor(window)); |
- } |
-} |
- |
-} // namespace internal |
-} // namespace ash |