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

Unified Diff: ui/aura_shell/activation_controller.cc

Issue 8894018: Move the concept of Activation to the Shell. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/aura_shell/activation_controller.h ('k') | ui/aura_shell/activation_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/aura_shell/activation_controller.cc
===================================================================
--- ui/aura_shell/activation_controller.cc (revision 0)
+++ ui/aura_shell/activation_controller.cc (revision 0)
@@ -0,0 +1,185 @@
+// Copyright (c) 2011 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 "ui/aura_shell/activation_controller.h"
+
+#include "base/auto_reset.h"
+#include "ui/aura/client/activation_delegate.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_delegate.h"
+#include "ui/aura_shell/shell.h"
+#include "ui/aura_shell/shell_window_ids.h"
+#include "ui/aura_shell/window_util.h"
+
+namespace aura_shell {
+namespace internal {
+namespace {
+
+aura::Window* GetContainer(int id) {
+ return Shell::GetInstance()->GetContainer(id);
+}
+
+// Returns true if children of |window| can be activated.
+bool SupportsChildActivation(aura::Window* window) {
+ return window->id() == kShellWindowId_DefaultContainer ||
+ window->id() == kShellWindowId_AlwaysOnTopContainer ||
+ window->id() == kShellWindowId_ModalContainer ||
+ window->id() == kShellWindowId_LockModalContainer;
+}
+
+// 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 CanActivateWindow(aura::Window* window) {
+ return window &&
+ window->IsVisible() &&
+ (!aura::ActivationDelegate::GetActivationDelegate(window) ||
+ aura::ActivationDelegate::GetActivationDelegate(window)->
+ ShouldActivate(NULL)) &&
+ SupportsChildActivation(window->parent());
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// ActivationController, public:
+
+ActivationController::ActivationController()
+ : updating_activation_(false),
+ default_container_for_test_(NULL) {
+ aura::ActivationClient::SetActivationClient(this);
+ aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
+}
+
+ActivationController::~ActivationController() {
+ aura::RootWindow::GetInstance()->RemoveRootWindowObserver(this);
+}
+
+// static
+aura::Window* ActivationController::GetActivatableWindow(aura::Window* window) {
+ aura::Window* parent = window->parent();
+ aura::Window* child = window;
+ while (parent) {
+ if (SupportsChildActivation(parent))
+ return child;
+ // If |child| isn't activatable, but has transient parent, trace
+ // that path instead.
+ if (child->transient_parent())
+ return GetActivatableWindow(child->transient_parent());
+ parent = parent->parent();
+ child = child->parent();
+ }
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// StackingController, aura::ActivationClient implementation:
+
+void ActivationController::ActivateWindow(aura::Window* window) {
+ // Prevent recursion when called from focus.
+ if (updating_activation_)
+ return;
+
+ AutoReset<bool> in_activate_window(&updating_activation_, true);
+ if (!window)
+ return;
+ // Nothing may actually have changed.
+ aura::Window* old_active = GetActiveWindow();
+ if (old_active == window)
+ return;
+ // The stacking client may impose rules on what window configurations can be
+ // activated or deactivated.
+ if (!CanActivateWindow(window))
+ return;
+
+ if (!window->Contains(window->GetFocusManager()->GetFocusedWindow()))
+ window->GetFocusManager()->SetFocusedWindow(window);
+ aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
+ window);
+ // Invoke OnLostActive after we've changed the active window. That way if the
+ // delegate queries for active state it doesn't think the window is still
+ // active.
+ if (old_active && aura::ActivationDelegate::GetActivationDelegate(old_active))
+ aura::ActivationDelegate::GetActivationDelegate(old_active)->OnLostActive();
+ if (window) {
+ window->parent()->StackChildAtTop(window);
+ if (aura::ActivationDelegate::GetActivationDelegate(window))
+ aura::ActivationDelegate::GetActivationDelegate(window)->OnActivated();
+ }
+}
+
+void ActivationController::DeactivateWindow(aura::Window* window) {
+ if (window)
+ ActivateNextWindow(window);
+}
+
+aura::Window* ActivationController::GetActiveWindow() {
+ return reinterpret_cast<aura::Window*>(
+ aura::RootWindow::GetInstance()->GetProperty(
+ aura::kRootWindowActiveWindow));
+}
+
+bool ActivationController::CanFocusWindow(aura::Window* window) const {
+ return CanActivateWindow(GetActivatableWindow(window));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ActivationController, aura::WindowObserver implementation:
+
+void ActivationController::OnWindowVisibilityChanged(aura::Window* window,
+ bool visible) {
+ if (!visible)
+ ActivateNextWindow(window);
+}
+
+void ActivationController::OnWindowDestroyed(aura::Window* window) {
+ if (IsActiveWindow(window)) {
+ // Clear the property before activating something else, since
+ // ActivateWindow() will attempt to notify the window stored in this value
+ // otherwise.
+ aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
+ NULL);
+ ActivateWindow(GetTopmostWindowToActivate(window));
+ }
+ window->RemoveObserver(this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ActivationController, aura::RootWindowObserver implementation:
+
+void ActivationController::OnWindowInitialized(aura::Window* window) {
+ window->AddObserver(this);
+}
+
+void ActivationController::OnWindowFocused(aura::Window* window) {
+ ActivateWindow(GetActivatableWindow(window));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ActivationController, private:
+
+void ActivationController::ActivateNextWindow(aura::Window* window) {
+ if (IsActiveWindow(window))
+ ActivateWindow(GetTopmostWindowToActivate(window));
+}
+
+aura::Window* ActivationController::GetTopmostWindowToActivate(
+ aura::Window* ignore) const {
+ const aura::Window* container =
+ default_container_for_test_ ? default_container_for_test_ :
+ GetContainer(kShellWindowId_DefaultContainer);
+ for (aura::Window::Windows::const_reverse_iterator i =
+ container->children().rbegin();
+ i != container->children().rend();
+ ++i) {
+ if (*i != ignore && CanActivateWindow(*i))
+ return *i;
+ }
+ return NULL;
+}
+
+} // namespace internal
+} // namespace aura_shell
Property changes on: ui\aura_shell\activation_controller.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « ui/aura_shell/activation_controller.h ('k') | ui/aura_shell/activation_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698