| 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
|
|
|