summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-30 22:10:14 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-30 22:10:14 +0000
commita857dbe9dab3f8df2b452d8fac0e2f1795ac8926 (patch)
tree3417cecbbab60f2ad69f05c1157eb8a7bcd9192f
parent800c8d730fc85e7bf9b548947f5842828346c485 (diff)
downloadchromium_src-a857dbe9dab3f8df2b452d8fac0e2f1795ac8926.zip
chromium_src-a857dbe9dab3f8df2b452d8fac0e2f1795ac8926.tar.gz
chromium_src-a857dbe9dab3f8df2b452d8fac0e2f1795ac8926.tar.bz2
Decouple FocusManager from RootWindow.
- Added FocusChangeObserver Store active window in ActivationController instead of in RootWindow as there will be multiple root windows. BUG=123160 TEST=no functional change. all tests must pass. Review URL: https://chromiumcodereview.appspot.com/10453019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139647 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/monitor/monitor_controller.cc28
-rw-r--r--ash/shell.cc28
-rw-r--r--ash/shell.h20
-rw-r--r--ash/wm/activation_controller.cc28
-rw-r--r--ash/wm/activation_controller.h8
-rw-r--r--ash/wm/app_list_controller.cc28
-rw-r--r--ash/wm/app_list_controller.h7
-rw-r--r--ash/wm/root_window_event_filter_unittest.cc7
-rw-r--r--chrome/browser/ui/views/omnibox/omnibox_view_views.cc3
-rw-r--r--ui/aura/aura.gyp2
-rw-r--r--ui/aura/desktop/desktop_activation_client.cc4
-rw-r--r--ui/aura/desktop/desktop_activation_client.h5
-rw-r--r--ui/aura/env_observer.h1
-rw-r--r--ui/aura/event_filter_unittest.cc1
-rw-r--r--ui/aura/focus_change_observer.h26
-rw-r--r--ui/aura/focus_manager.cc66
-rw-r--r--ui/aura/focus_manager.h23
-rw-r--r--ui/aura/root_window.cc76
-rw-r--r--ui/aura/root_window.h33
-rw-r--r--ui/aura/root_window_observer.h3
-rw-r--r--ui/aura/root_window_unittest.cc1
-rw-r--r--ui/aura/test/aura_test_helper.cc14
-rw-r--r--ui/aura/test/aura_test_helper.h4
-rw-r--r--ui/aura/window.cc9
-rw-r--r--ui/aura/window.h9
-rw-r--r--ui/aura/window_unittest.cc1
-rw-r--r--ui/views/widget/native_widget_aura.cc1
27 files changed, 277 insertions, 159 deletions
diff --git a/ash/monitor/monitor_controller.cc b/ash/monitor/monitor_controller.cc
index 59c6b41..9bc85b4 100644
--- a/ash/monitor/monitor_controller.cc
+++ b/ash/monitor/monitor_controller.cc
@@ -5,13 +5,7 @@
#include "ash/monitor/monitor_controller.h"
#include "ash/monitor/multi_monitor_manager.h"
-#include "ash/monitor/secondary_monitor_view.h"
#include "ash/shell.h"
-#include "ash/wm/base_layout_manager.h"
-#include "ash/wm/root_window_layout_manager.h"
-#include "base/bind.h"
-#include "base/stl_util.h"
-#include "base/time.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
@@ -20,24 +14,6 @@
namespace ash {
namespace internal {
-namespace {
-
-void SetupAsSecondaryMonitor(aura::RootWindow* root) {
- root->SetFocusWhenShown(false);
- root->SetLayoutManager(new internal::RootWindowLayoutManager(root));
- aura::Window* container = new aura::Window(NULL);
- container->SetName("SecondaryMonitorContainer");
- container->Init(ui::LAYER_NOT_DRAWN);
- root->AddChild(container);
- container->SetLayoutManager(new internal::BaseLayoutManager(root));
- CreateSecondaryMonitorWidget(container);
- container->Show();
- root->layout_manager()->OnWindowResized();
- root->ShowRootWindow();
-}
-
-} // namespace
-
MonitorController::MonitorController() {
aura::Env::GetInstance()->monitor_manager()->AddObserver(this);
Init();
@@ -66,7 +42,7 @@ void MonitorController::OnMonitorAdded(const gfx::Monitor& monitor) {
aura::RootWindow* root = aura::Env::GetInstance()->monitor_manager()->
CreateRootWindowForMonitor(monitor);
root_windows_[monitor.id()] = root;
- SetupAsSecondaryMonitor(root);
+ Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root);
}
void MonitorController::OnMonitorRemoved(const gfx::Monitor& monitor) {
@@ -95,7 +71,7 @@ void MonitorController::Init() {
aura::RootWindow* root =
monitor_manager->CreateRootWindowForMonitor(monitor);
root_windows_[monitor.id()] = root;
- SetupAsSecondaryMonitor(root);
+ Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root);
}
}
}
diff --git a/ash/shell.cc b/ash/shell.cc
index 9d4f7de..0b137f18 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -19,6 +19,7 @@
#include "ash/magnifier/magnification_controller.h"
#include "ash/monitor/monitor_controller.h"
#include "ash/monitor/multi_monitor_manager.h"
+#include "ash/monitor/secondary_monitor_view.h"
#include "ash/screen_ash.h"
#include "ash/shell_context_menu.h"
#include "ash/shell_delegate.h"
@@ -66,6 +67,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/monitor_manager.h"
#include "ui/aura/root_window.h"
@@ -652,12 +654,21 @@ aura::RootWindow* Shell::GetPrimaryRootWindow() {
return GetInstance()->root_window_.get();
}
+aura::RootWindow* Shell::GetActiveRootWindow() {
+ return GetInstance()->active_root_window_;
+}
+
void Shell::Init() {
// Install the custom factory first so that views::FocusManagers for Tray,
// Launcher, and WallPaper could be created by the factory.
views::FocusManagerFactory::Install(new AshFocusManagerFactory);
aura::RootWindow* root_window = GetPrimaryRootWindow();
+ active_root_window_ = root_window;
+
+ focus_manager_.reset(new aura::FocusManager);
+ root_window_->set_focus_manager(focus_manager_.get());
+
root_filter_ = new aura::shared::RootWindowEventFilter(root_window);
#if !defined(OS_MACOSX)
nested_dispatcher_controller_.reset(new NestedDispatcherController);
@@ -665,7 +676,7 @@ void Shell::Init() {
#endif
shell_context_menu_.reset(new internal::ShellContextMenu);
// Pass ownership of the filter to the root window.
- GetPrimaryRootWindow()->SetEventFilter(root_filter_);
+ root_window->SetEventFilter(root_filter_);
// KeyRewriterEventFilter must be the first one.
DCHECK(!GetRootWindowEventFilterCount());
@@ -920,6 +931,21 @@ bool Shell::IsInMaximizedMode() const {
return workspace_controller_->workspace_manager()->IsInMaximizedMode();
}
+void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) {
+ root->set_focus_manager(focus_manager_.get());
+ root->SetFocusWhenShown(false);
+ root->SetLayoutManager(new internal::RootWindowLayoutManager(root));
+ aura::Window* container = new aura::Window(NULL);
+ container->SetName("SecondaryMonitorContainer");
+ container->Init(ui::LAYER_NOT_DRAWN);
+ root->AddChild(container);
+ container->SetLayoutManager(new internal::BaseLayoutManager(root));
+ CreateSecondaryMonitorWidget(container);
+ container->Show();
+ root->layout_manager()->OnWindowResized();
+ root->ShowRootWindow();
+}
+
////////////////////////////////////////////////////////////////////////////////
// Shell, private:
diff --git a/ash/shell.h b/ash/shell.h
index 12e7c15..e212335 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -25,6 +25,7 @@ class SkBitmap;
namespace aura {
class EventFilter;
+class FocusManager;
class Monitor;
class RootWindow;
class Window;
@@ -133,10 +134,20 @@ class ASH_EXPORT Shell {
static void DeleteInstance();
- // Gets the primary RootWindow. The primary RootWindow is the root window
+ // Gets the primary RootWindow. The primary RootWindow is the one
// that has a launcher.
static aura::RootWindow* GetPrimaryRootWindow();
+ // Gets the active RootWindow. The active RootWindow is the one that
+ // contains the current active window as a decendant child. The active
+ // RootWindow remains the same even when the active window becomes NULL,
+ // until the another window who has a different root window becomes active.
+ static aura::RootWindow* GetActiveRootWindow();
+
+ void set_active_root_window(aura::RootWindow* active_root_window) {
+ active_root_window_ = active_root_window;
+ }
+
internal::RootWindowLayoutManager* root_window_layout() const {
return root_window_layout_;
}
@@ -294,6 +305,9 @@ class ASH_EXPORT Shell {
browser_context_ = browser_context;
}
+ // Initialize the root window to be used for a secondary monitor.
+ void InitRootWindowForSecondaryMonitor(aura::RootWindow* root);
+
private:
FRIEND_TEST_ALL_PREFIXES(RootWindowEventFilterTest, MouseEventCursors);
FRIEND_TEST_ALL_PREFIXES(RootWindowEventFilterTest, TransformActivate);
@@ -320,6 +334,9 @@ class ASH_EXPORT Shell {
scoped_ptr<aura::RootWindow> root_window_;
ScreenAsh* screen_;
+ // Active root window. Never become NULL.
+ aura::RootWindow* active_root_window_;
+
aura::shared::RootWindowEventFilter* root_filter_; // not owned
std::vector<WindowAndBoundsPair> to_restore_;
@@ -358,6 +375,7 @@ class ASH_EXPORT Shell {
scoped_ptr<HighContrastController> high_contrast_controller_;
scoped_ptr<internal::MagnificationController> magnification_controller_;
scoped_ptr<internal::ScreenDimmer> screen_dimmer_;
+ scoped_ptr<aura::FocusManager> focus_manager_;
// An event filter that rewrites or drops a key event.
scoped_ptr<internal::KeyRewriterEventFilter> key_rewriter_filter_;
diff --git a/ash/wm/activation_controller.cc b/ash/wm/activation_controller.cc
index 8507508..0758571 100644
--- a/ash/wm/activation_controller.cc
+++ b/ash/wm/activation_controller.cc
@@ -12,6 +12,7 @@
#include "ui/aura/client/activation_delegate.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
@@ -117,15 +118,16 @@ void StackTransientParentsBelowModalWindow(aura::Window* window) {
ActivationController::ActivationController()
: updating_activation_(false),
+ active_window_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(observer_manager_(this)) {
aura::client::SetActivationClient(Shell::GetPrimaryRootWindow(), this);
aura::Env::GetInstance()->AddObserver(this);
- Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
+ Shell::GetPrimaryRootWindow()->GetFocusManager()->AddObserver(this);
}
ActivationController::~ActivationController() {
- Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
aura::Env::GetInstance()->RemoveObserver(this);
+ Shell::GetPrimaryRootWindow()->GetFocusManager()->RemoveObserver(this);
}
// static
@@ -165,8 +167,7 @@ void ActivationController::DeactivateWindow(aura::Window* window) {
}
aura::Window* ActivationController::GetActiveWindow() {
- return Shell::GetPrimaryRootWindow()->GetProperty(
- aura::client::kRootWindowActiveWindowKey);
+ return active_window_;
}
bool ActivationController::OnWillFocusWindow(aura::Window* window,
@@ -192,10 +193,15 @@ void ActivationController::OnWindowVisibilityChanged(aura::Window* window,
}
void ActivationController::OnWindowDestroying(aura::Window* window) {
- if (wm::IsActiveWindow(window)) {
+ // Don't use wm::IsActiveWidnow in case the |window| has
+ // removed from the root tree.
+ if (active_window_ == window) {
+ active_window_ = NULL;
// Clear the property before activating something else, since
// ActivateWindow() will attempt to notify the window stored in this value
// otherwise.
+ // TODO(oshima): NativeWidgetAura relies on this property now.
+ // Fix NativeWidgetAura not to depend on this and remove this.
Shell::GetPrimaryRootWindow()->ClearProperty(
aura::client::kRootWindowActiveWindowKey);
ActivateWindow(GetTopmostWindowToActivate(window));
@@ -258,8 +264,18 @@ void ActivationController::ActivateWindowWithEvent(aura::Window* window,
!window->Contains(window->GetFocusManager()->GetFocusedWindow())) {
window->GetFocusManager()->SetFocusedWindow(window, event);
}
+
+ active_window_ = window;
+ if (window) {
+ DCHECK(window->GetRootWindow());
+ Shell::GetInstance()->set_active_root_window(window->GetRootWindow());
+ }
+
+ // TODO(oshima): Remove this (see comment in OnWindowDestroying above)
Shell::GetPrimaryRootWindow()->SetProperty(
- aura::client::kRootWindowActiveWindowKey, window);
+ aura::client::kRootWindowActiveWindowKey,
+ 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.
diff --git a/ash/wm/activation_controller.h b/ash/wm/activation_controller.h
index 32fe65e..b53c787 100644
--- a/ash/wm/activation_controller.h
+++ b/ash/wm/activation_controller.h
@@ -11,7 +11,7 @@
#include "base/compiler_specific.h"
#include "ui/aura/client/activation_client.h"
#include "ui/aura/env_observer.h"
-#include "ui/aura/root_window_observer.h"
+#include "ui/aura/focus_change_observer.h"
#include "ui/aura/window_observer.h"
#include "ash/ash_export.h"
@@ -23,7 +23,7 @@ class ASH_EXPORT ActivationController
: public aura::client::ActivationClient,
public aura::WindowObserver,
public aura::EnvObserver,
- public aura::RootWindowObserver {
+ public aura::FocusChangeObserver {
public:
ActivationController();
virtual ~ActivationController();
@@ -50,7 +50,7 @@ class ASH_EXPORT ActivationController
// Overridden from aura::EnvObserver:
virtual void OnWindowInitialized(aura::Window* window) OVERRIDE;
- // Overridden from aura::RootWindowObserver:
+ // Overridden from aura::FocusChangeObserver:
virtual void OnWindowFocused(aura::Window* window) OVERRIDE;
private:
@@ -75,6 +75,8 @@ class ASH_EXPORT ActivationController
// change notifications causing activation.
bool updating_activation_;
+ aura::Window* active_window_;
+
ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
DISALLOW_COPY_AND_ASSIGN(ActivationController);
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index e95f4c4..fb6159b 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -15,6 +15,7 @@
#include "ui/app_list/app_list_view.h"
#include "ui/app_list/icon_cache.h"
#include "ui/aura/event.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
@@ -152,7 +153,7 @@ void AppListController::SetView(app_list::AppListView* view) {
widget->AddObserver(this);
Shell::GetInstance()->AddRootWindowEventFilter(this);
widget->GetNativeView()->GetRootWindow()->AddRootWindowObserver(this);
-
+ widget->GetNativeView()->GetFocusManager()->AddObserver(this);
widget->SetOpacity(0);
ScheduleAnimation();
@@ -171,6 +172,7 @@ void AppListController::ResetView() {
GetLayer(widget)->GetAnimator()->RemoveObserver(this);
Shell::GetInstance()->RemoveRootWindowEventFilter(this);
widget->GetNativeView()->GetRootWindow()->RemoveRootWindowObserver(this);
+ widget->GetNativeView()->GetFocusManager()->RemoveObserver(this);
view_ = NULL;
app_list::IconCache::GetInstance()->PurgeAllUnused();
@@ -292,17 +294,7 @@ ui::GestureStatus AppListController::PreHandleGestureEvent(
}
////////////////////////////////////////////////////////////////////////////////
-// AppListController, aura::RootWindowObserver implementation:
-void AppListController::OnRootWindowResized(const aura::RootWindow* root,
- const gfx::Size& old_size) {
- if (view_ && is_visible_) {
- views::Widget* launcher_widget =
- Shell::GetInstance()->launcher()->widget();
- view_->UpdateBounds(GetFullScreenBoundsForWidget(launcher_widget),
- GetWorkAreaBoundsForWidget(launcher_widget));
- }
-}
-
+// AppListController, aura::FocusObserver implementation:
void AppListController::OnWindowFocused(aura::Window* window) {
if (view_ && is_visible_) {
aura::Window* applist_container = Shell::GetInstance()->GetContainer(
@@ -317,6 +309,18 @@ void AppListController::OnWindowFocused(aura::Window* window) {
}
////////////////////////////////////////////////////////////////////////////////
+// AppListController, aura::RootWindowObserver implementation:
+void AppListController::OnRootWindowResized(const aura::RootWindow* root,
+ const gfx::Size& old_size) {
+ if (view_ && is_visible_) {
+ views::Widget* launcher_widget =
+ Shell::GetInstance()->launcher()->widget();
+ view_->UpdateBounds(GetFullScreenBoundsForWidget(launcher_widget),
+ GetWorkAreaBoundsForWidget(launcher_widget));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// AppListController, ui::ImplicitAnimationObserver implementation:
void AppListController::OnImplicitAnimationsCompleted() {
diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h
index 3c7e7c2..bf6e863 100644
--- a/ash/wm/app_list_controller.h
+++ b/ash/wm/app_list_controller.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/timer.h"
#include "ui/aura/event_filter.h"
+#include "ui/aura/focus_change_observer.h"
#include "ui/aura/root_window_observer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/views/widget/widget.h"
@@ -27,6 +28,7 @@ namespace internal {
// While the UI is visible, it monitors things such as app list widget's
// activation state and desktop mouse click to auto dismiss the UI.
class AppListController : public aura::EventFilter,
+ public aura::FocusChangeObserver,
public aura::RootWindowObserver,
public ui::ImplicitAnimationObserver,
public views::Widget::Observer,
@@ -86,10 +88,12 @@ class AppListController : public aura::EventFilter,
aura::Window* target,
aura::GestureEvent* event) OVERRIDE;
+ // aura::FocusChangeObserver overrides:
+ virtual void OnWindowFocused(aura::Window* window) OVERRIDE;
+
// aura::RootWindowObserver overrides:
virtual void OnRootWindowResized(const aura::RootWindow* root,
const gfx::Size& old_size) OVERRIDE;
- virtual void OnWindowFocused(aura::Window* window) OVERRIDE;
// ui::ImplicitAnimationObserver overrides:
virtual void OnImplicitAnimationsCompleted() OVERRIDE;
@@ -117,4 +121,3 @@ class AppListController : public aura::EventFilter,
} // namespace ash
#endif // ASH_WM_APP_LIST_CONTROLLER_H_
-
diff --git a/ash/wm/root_window_event_filter_unittest.cc b/ash/wm/root_window_event_filter_unittest.cc
index 5f61056..10fb0442 100644
--- a/ash/wm/root_window_event_filter_unittest.cc
+++ b/ash/wm/root_window_event_filter_unittest.cc
@@ -11,6 +11,7 @@
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/activation_delegate.h"
#include "ui/aura/event.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/shared/input_method_event_filter.h"
#include "ui/aura/shared/root_window_event_filter.h"
@@ -112,7 +113,7 @@ TEST_F(RootWindowEventFilterTest, Focus) {
w121.get());
generator.ClickLeftButton();
- aura::internal::FocusManager* focus_manager = w121->GetFocusManager();
+ aura::FocusManager* focus_manager = w121->GetFocusManager();
EXPECT_EQ(w121.get(), focus_manager->GetFocusedWindow());
// The key press should be sent to the focused sub-window.
@@ -191,7 +192,7 @@ TEST_F(RootWindowEventFilterTest, ActivateOnMouse) {
&wd, -1, gfx::Rect(70, 70, 50, 50), NULL));
d2.SetWindow(w2.get());
- aura::internal::FocusManager* focus_manager = w1->GetFocusManager();
+ aura::FocusManager* focus_manager = w1->GetFocusManager();
d1.Clear();
d2.Clear();
@@ -307,7 +308,7 @@ TEST_F(RootWindowEventFilterTest, ActivateOnTouch) {
&wd, -2, gfx::Rect(70, 70, 50, 50), NULL));
d2.SetWindow(w2.get());
- aura::internal::FocusManager* focus_manager = w1->GetFocusManager();
+ aura::FocusManager* focus_manager = w1->GetFocusManager();
d1.Clear();
d2.Clear();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 8313fa5..91c87b1 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -43,6 +43,7 @@
#include "ui/views/views_delegate.h"
#if defined(USE_AURA)
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#endif
@@ -353,7 +354,7 @@ void OmniboxViewViews::HandleFocusOut() {
if (widget) {
aura::RootWindow* root = widget->GetNativeView()->GetRootWindow();
if (root)
- native_view = root->focused_window();
+ native_view = root->GetFocusManager()->GetFocusedWindow();
}
#endif
model_->OnWillKillFocus(native_view);
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index b77e7e7..3762b0d 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -75,6 +75,8 @@
'event_filter.h',
'event_mac.mm',
'event_mac.h',
+ 'focus_change_observer.h',
+ 'focus_manager.cc',
'focus_manager.h',
'layout_manager.cc',
'layout_manager.h',
diff --git a/ui/aura/desktop/desktop_activation_client.cc b/ui/aura/desktop/desktop_activation_client.cc
index 183a0ee..2ffa331 100644
--- a/ui/aura/desktop/desktop_activation_client.cc
+++ b/ui/aura/desktop/desktop_activation_client.cc
@@ -16,11 +16,11 @@ DesktopActivationClient::DesktopActivationClient(RootWindow* root_window)
: root_window_(root_window),
current_active_(NULL),
updating_activation_(false) {
- root_window->AddRootWindowObserver(this);
+ root_window_->GetFocusManager()->AddObserver(this);
}
DesktopActivationClient::~DesktopActivationClient() {
- root_window_->RemoveRootWindowObserver(this);
+ root_window_->GetFocusManager()->RemoveObserver(this);
}
void DesktopActivationClient::ActivateWindow(Window* window) {
diff --git a/ui/aura/desktop/desktop_activation_client.h b/ui/aura/desktop/desktop_activation_client.h
index 5d2f12c..d18858b 100644
--- a/ui/aura/desktop/desktop_activation_client.h
+++ b/ui/aura/desktop/desktop_activation_client.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/client/activation_client.h"
+#include "ui/aura/focus_change_observer.h"
#include "ui/aura/root_window_observer.h"
namespace aura {
@@ -18,7 +19,7 @@ class RootWindow;
// RootWindow. Used only on the Desktop where there can be multiple RootWindow
// objects.
class AURA_EXPORT DesktopActivationClient : public client::ActivationClient,
- public RootWindowObserver {
+ public FocusChangeObserver {
public:
explicit DesktopActivationClient(RootWindow* root_window);
virtual ~DesktopActivationClient();
@@ -30,7 +31,7 @@ class AURA_EXPORT DesktopActivationClient : public client::ActivationClient,
virtual bool OnWillFocusWindow(Window* window, const Event* event) OVERRIDE;
virtual bool CanActivateWindow(Window* window) const OVERRIDE;
- // RootWindowObserver:
+ // FocusChangeObserver:
virtual void OnWindowFocused(aura::Window* window) OVERRIDE;
protected:
diff --git a/ui/aura/env_observer.h b/ui/aura/env_observer.h
index 9a4541a..351f14b 100644
--- a/ui/aura/env_observer.h
+++ b/ui/aura/env_observer.h
@@ -6,7 +6,6 @@
#define UI_AURA_ENV_OBSERVER_H_
#pragma once
-#include "base/observer_list.h"
#include "ui/aura/aura_export.h"
namespace aura {
diff --git a/ui/aura/event_filter_unittest.cc b/ui/aura/event_filter_unittest.cc
index 196ca18..6b61e9a 100644
--- a/ui/aura/event_filter_unittest.cc
+++ b/ui/aura/event_filter_unittest.cc
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/aura/event.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
diff --git a/ui/aura/focus_change_observer.h b/ui/aura/focus_change_observer.h
new file mode 100644
index 0000000..312f8b3
--- /dev/null
+++ b/ui/aura/focus_change_observer.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef UI_AURA_FOCUS_CHANGE_OBSERVER_H_
+#define UI_AURA_FOCUS_CHANGE_OBSERVER_H_
+#pragma once
+
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+
+class Window;
+
+class AURA_EXPORT FocusChangeObserver {
+ public:
+ // Called when |window| gains focus.
+ virtual void OnWindowFocused(Window* window) = 0;
+
+ protected:
+ virtual ~FocusChangeObserver() {}
+};
+
+} // namespace aura
+
+#endif // UI_AURA_FOCUS_CHANGE_OBSERVER_H_
diff --git a/ui/aura/focus_manager.cc b/ui/aura/focus_manager.cc
new file mode 100644
index 0000000..475c0e3
--- /dev/null
+++ b/ui/aura/focus_manager.cc
@@ -0,0 +1,66 @@
+// 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 "ui/aura/focus_manager.h"
+
+#include "ui/aura/client/activation_client.h"
+#include "ui/aura/focus_change_observer.h"
+#include "ui/aura/window_delegate.h"
+
+namespace aura {
+FocusManager::FocusManager() : focused_window_(NULL) {
+}
+
+FocusManager::~FocusManager() {
+}
+
+void FocusManager::AddObserver(FocusChangeObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void FocusManager::RemoveObserver(FocusChangeObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void FocusManager::SetFocusedWindow(Window* focused_window,
+ const Event* event) {
+ if (focused_window == focused_window_)
+ return;
+ if (focused_window && !focused_window->CanFocus())
+ return;
+ // The NULL-check of |focused_window| is essential here before asking the
+ // activation client, since it is valid to clear the focus by calling
+ // SetFocusedWindow() to NULL.
+
+ if (focused_window) {
+ RootWindow* root = focused_window->GetRootWindow();
+ DCHECK(root);
+ if (client::GetActivationClient(root) &&
+ !client::GetActivationClient(root)->OnWillFocusWindow(
+ focused_window, event)) {
+ return;
+ }
+ }
+
+ Window* old_focused_window = focused_window_;
+ focused_window_ = focused_window;
+ if (old_focused_window && old_focused_window->delegate())
+ old_focused_window->delegate()->OnBlur();
+ if (focused_window_ && focused_window_->delegate())
+ focused_window_->delegate()->OnFocus();
+ if (focused_window_) {
+ FOR_EACH_OBSERVER(FocusChangeObserver, observers_,
+ OnWindowFocused(focused_window));
+ }
+}
+
+Window* FocusManager::GetFocusedWindow() {
+ return focused_window_;
+}
+
+bool FocusManager::IsFocusedWindow(const Window* window) const {
+ return focused_window_ == window;
+}
+
+} // namespace ash
diff --git a/ui/aura/focus_manager.h b/ui/aura/focus_manager.h
index d3ccefc..c2a4290 100644
--- a/ui/aura/focus_manager.h
+++ b/ui/aura/focus_manager.h
@@ -7,37 +7,46 @@
#pragma once
#include "base/basictypes.h"
+#include "base/observer_list.h"
#include "ui/aura/aura_export.h"
namespace aura {
class Event;
+class FocusChangeObserver;
class Window;
-namespace internal {
-
// An interface implemented by the Desktop to expose the focused window and
// allow for it to be changed.
class AURA_EXPORT FocusManager {
public:
+ FocusManager();
+ ~FocusManager();
+
+ void AddObserver(FocusChangeObserver* observer);
+ void RemoveObserver(FocusChangeObserver* observer);
+
// Sets the currently focused window. Before the currently focused window is
// changed, the previous focused window's delegate is sent a blur
// notification, and after it is changed the new focused window is sent a
// focused notification. Nothing happens if |window| and GetFocusedWindow()
// match.
- virtual void SetFocusedWindow(Window* window, const Event* event) = 0;
+ void SetFocusedWindow(Window* window, const Event* event);
// Returns the currently focused window or NULL if there is none.
- virtual Window* GetFocusedWindow() = 0;
+ Window* GetFocusedWindow();
// Returns true if |window| is the focused window.
- virtual bool IsFocusedWindow(const Window* window) const = 0;
+ bool IsFocusedWindow(const Window* window) const;
protected:
- virtual ~FocusManager() {}
+ aura::Window* focused_window_;
+
+ ObserverList<FocusChangeObserver> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(FocusManager);
};
-} // namespace internal
} // namespace aura
#endif // UI_AURA_FOCUS_MANAGER_H_
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index fec4337..b47fc60 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -121,7 +121,6 @@ RootWindow::RootWindow(const gfx::Rect& initial_bounds)
capture_window_(NULL),
mouse_pressed_handler_(NULL),
mouse_moved_handler_(NULL),
- focused_window_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(
gesture_recognizer_(ui::GestureRecognizer::Create(this))),
synthesize_mouse_move_(false),
@@ -272,11 +271,12 @@ bool RootWindow::DispatchKeyEvent(KeyEvent* event) {
if (translated_event.key_code() == ui::VKEY_UNKNOWN)
return false;
client::EventClient* client = client::GetEventClient(GetRootWindow());
- if (client && !client->CanProcessEventsWithinSubtree(focused_window_)) {
- SetFocusedWindow(NULL, NULL);
+ Window* focused_window = focus_manager_->GetFocusedWindow();
+ if (client && !client->CanProcessEventsWithinSubtree(focused_window)) {
+ GetFocusManager()->SetFocusedWindow(NULL, NULL);
return false;
}
- return ProcessKeyEvent(focused_window_, &translated_event);
+ return ProcessKeyEvent(focused_window, &translated_event);
}
bool RootWindow::DispatchScrollEvent(ScrollEvent* event) {
@@ -590,6 +590,7 @@ void RootWindow::OnCompositingAborted(ui::Compositor*) {
////////////////////////////////////////////////////////////////////////////////
// RootWindow, ui::LayerDelegate implementation:
+
void RootWindow::OnDeviceScaleFactorChanged(
float device_scale_factor) {
if (cursor_shown_)
@@ -601,6 +602,21 @@ void RootWindow::OnDeviceScaleFactorChanged(
}
////////////////////////////////////////////////////////////////////////////////
+// RootWindow, overridden from aura::Window:
+
+bool RootWindow::CanFocus() const {
+ return IsVisible();
+}
+
+bool RootWindow::CanReceiveEvents() const {
+ return IsVisible();
+}
+
+FocusManager* RootWindow::GetFocusManager() {
+ return focus_manager_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// RootWindow, private:
void RootWindow::HandleMouseCaptureChanged(Window* old_capture_window) {
@@ -817,7 +833,8 @@ void RootWindow::OnWindowRemovedFromRootWindow(Window* detached) {
void RootWindow::OnWindowHidden(Window* invisible, bool destroyed) {
// Update the focused window state if the invisible window contains
// focused_window.
- if (invisible->Contains(focused_window_)) {
+ Window* focused_window = focus_manager_->GetFocusedWindow();
+ if (invisible->Contains(focused_window)) {
Window* focus_to = invisible->transient_parent();
if (focus_to) {
// Has to be removed from the transient parent before focusing, otherwise
@@ -836,7 +853,7 @@ void RootWindow::OnWindowHidden(Window* invisible, bool destroyed) {
NULL)))) {
focus_to = NULL;
}
- SetFocusedWindow(focus_to, NULL);
+ GetFocusManager()->SetFocusedWindow(focus_to, NULL);
}
// If the ancestor of the capture window is hidden,
// release the capture.
@@ -858,18 +875,6 @@ void RootWindow::OnWindowAddedToRootWindow(Window* attached) {
PostMouseMoveEventAfterWindowChange();
}
-bool RootWindow::CanFocus() const {
- return IsVisible();
-}
-
-bool RootWindow::CanReceiveEvents() const {
- return IsVisible();
-}
-
-internal::FocusManager* RootWindow::GetFocusManager() {
- return this;
-}
-
bool RootWindow::DispatchLongPressGestureEvent(ui::GestureEvent* event) {
return DispatchGestureEvent(static_cast<GestureEvent*>(event));
}
@@ -909,41 +914,6 @@ void RootWindow::OnLayerAnimationAborted(
ui::LayerAnimationSequence* animation) {
}
-void RootWindow::SetFocusedWindow(Window* focused_window,
- const aura::Event* event) {
- if (focused_window == focused_window_)
- return;
- if (focused_window && !focused_window->CanFocus())
- return;
- // The NULL-check of |focused_window| is essential here before asking the
- // activation client, since it is valid to clear the focus by calling
- // SetFocusedWindow() to NULL.
- if (focused_window && client::GetActivationClient(this) &&
- !client::GetActivationClient(this)->OnWillFocusWindow(focused_window,
- event)) {
- return;
- }
-
- Window* old_focused_window = focused_window_;
- focused_window_ = focused_window;
- if (old_focused_window && old_focused_window->delegate())
- old_focused_window->delegate()->OnBlur();
- if (focused_window_ && focused_window_->delegate())
- focused_window_->delegate()->OnFocus();
- if (focused_window_) {
- FOR_EACH_OBSERVER(RootWindowObserver, observers_,
- OnWindowFocused(focused_window_));
- }
-}
-
-Window* RootWindow::GetFocusedWindow() {
- return focused_window_;
-}
-
-bool RootWindow::IsFocusedWindow(const Window* window) const {
- return focused_window_ == window;
-}
-
bool RootWindow::DispatchMouseEventImpl(MouseEvent* event) {
float scale = ui::GetDeviceScaleFactor(layer());
ui::Transform transform = layer()->transform();
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 05348a3..2666c81 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -14,7 +14,6 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "ui/aura/aura_export.h"
-#include "ui/aura/focus_manager.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/events.h"
@@ -38,15 +37,15 @@ class Transform;
namespace aura {
+class FocusManager;
+class GestureEvent;
+class KeyEvent;
+class MouseEvent;
class RootWindow;
class RootWindowHost;
class RootWindowObserver;
-class KeyEvent;
-class MouseEvent;
-class StackingClient;
class ScrollEvent;
class TouchEvent;
-class GestureEvent;
// This class represents a lock on the compositor, that can be used to prevent a
// compositing pass from happening while we're waiting for an asynchronous
@@ -77,7 +76,6 @@ class AURA_EXPORT CompositorLock :
class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
public ui::CompositorObserver,
public Window,
- public internal::FocusManager,
public ui::GestureEventHelper,
public ui::LayerAnimationObserver {
public:
@@ -97,7 +95,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
bool cursor_shown() const { return cursor_shown_; }
Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
Window* capture_window() { return capture_window_; }
- Window* focused_window() { return focused_window_; }
+
+ void set_focus_manager(FocusManager* focus_manager) {
+ focus_manager_ = focus_manager;
+ }
// Initializes the root window.
void Init();
@@ -263,6 +264,11 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Overridden from ui::LayerDelegate:
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+ // Overridden from Window:
+ virtual bool CanFocus() const OVERRIDE;
+ virtual bool CanReceiveEvents() const OVERRIDE;
+ virtual FocusManager* GetFocusManager() OVERRIDE;
+
private:
friend class Window;
friend class CompositorLock;
@@ -290,11 +296,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// |destroyed| is set to true when the window is being destroyed.
void OnWindowHidden(Window* invisible, bool destroyed);
- // Overridden from Window:
- virtual bool CanFocus() const OVERRIDE;
- virtual bool CanReceiveEvents() const OVERRIDE;
- virtual internal::FocusManager* GetFocusManager() OVERRIDE;
-
// Overridden from ui::GestureEventHelper.
virtual ui::GestureEvent* CreateGestureEvent(
ui::EventType type,
@@ -322,12 +323,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
virtual void OnLayerAnimationAborted(
ui::LayerAnimationSequence* animation) OVERRIDE;
- // Overridden from FocusManager:
- virtual void SetFocusedWindow(Window* window,
- const aura::Event* event) OVERRIDE;
- virtual Window* GetFocusedWindow() OVERRIDE;
- virtual bool IsFocusedWindow(const Window* window) const OVERRIDE;
-
// We hold and aggregate mouse drags as a way of throttling resizes when
// HoldMouseMoves() is called. The following methods are used to dispatch held
// and newly incoming mouse events, typically when an event other than a mouse
@@ -388,7 +383,7 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
Window* mouse_pressed_handler_;
Window* mouse_moved_handler_;
- Window* focused_window_;
+ FocusManager* focus_manager_;
// The gesture_recognizer_ for this.
scoped_ptr<ui::GestureRecognizer> gesture_recognizer_;
diff --git a/ui/aura/root_window_observer.h b/ui/aura/root_window_observer.h
index 39c9a4a..813aa0c 100644
--- a/ui/aura/root_window_observer.h
+++ b/ui/aura/root_window_observer.h
@@ -26,9 +26,6 @@ class AURA_EXPORT RootWindowObserver {
// window.
virtual void OnRootWindowHostClosed(const RootWindow* root) {}
- // Invoked when a window is focused.
- virtual void OnWindowFocused(Window* window) {}
-
// Invoked when the keyboard mapping has changed.
virtual void OnKeyboardMappingChanged(const RootWindow* root) {}
diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc
index 904ff5f..f1c456b 100644
--- a/ui/aura/root_window_unittest.cc
+++ b/ui/aura/root_window_unittest.cc
@@ -11,6 +11,7 @@
#include "ui/aura/env.h"
#include "ui/aura/event.h"
#include "ui/aura/event_filter.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_window_delegate.h"
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index c4e094c..12f4657 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -5,18 +5,19 @@
#include "ui/aura/test/aura_test_helper.h"
#include "base/message_loop.h"
+#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
+#include "ui/aura/focus_manager.h"
+#include "ui/aura/monitor_manager.h"
#include "ui/aura/root_window.h"
-#include "ui/compositor/layer_animator.h"
-#include "ui/gfx/screen.h"
-#include "ui/aura/client/aura_constants.h"
#include "ui/aura/single_monitor_manager.h"
-#include "ui/aura/monitor_manager.h"
-#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_activation_client.h"
+#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_stacking_client.h"
#include "ui/aura/ui_controls_aura.h"
#include "ui/base/test/dummy_input_method.h"
+#include "ui/compositor/layer_animator.h"
+#include "ui/gfx/screen.h"
#include "ui/ui_controls/ui_controls.h"
namespace aura {
@@ -47,6 +48,8 @@ void AuraTestHelper::SetUp() {
gfx::Screen::SetInstance(new aura::TestScreen(root_window_.get()));
ui_controls::InstallUIControlsAura(CreateUIControlsAura(root_window_.get()));
+ focus_manager_.reset(new FocusManager);
+ root_window_->set_focus_manager(focus_manager_.get());
stacking_client_.reset(new TestStackingClient(root_window_.get()));
test_activation_client_.reset(
new aura::test::TestActivationClient(root_window_.get()));
@@ -65,6 +68,7 @@ void AuraTestHelper::TearDown() {
test_input_method_.reset();
stacking_client_.reset();
test_activation_client_.reset();
+ focus_manager_.reset();
root_window_.reset();
aura::Env::DeleteInstance();
}
diff --git a/ui/aura/test/aura_test_helper.h b/ui/aura/test/aura_test_helper.h
index 4d2fa46..94f2846 100644
--- a/ui/aura/test/aura_test_helper.h
+++ b/ui/aura/test/aura_test_helper.h
@@ -20,10 +20,11 @@ class InputMethod;
}
namespace aura {
+class FocusManager;
class RootWindow;
namespace test {
-class TestStackingClient;
class TestActivationClient;
+class TestStackingClient;
// A helper class owned by tests that does common initialization required for
// Aura use. This class creates a root window with clients and other objects
@@ -54,6 +55,7 @@ class AuraTestHelper {
scoped_ptr<TestStackingClient> stacking_client_;
scoped_ptr<TestActivationClient> test_activation_client_;
scoped_ptr<ui::InputMethod> test_input_method_;
+ scoped_ptr<FocusManager> focus_manager_;
#if defined(OS_WIN)
ui::ScopedOleInitializer ole_initializer_;
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 1902199..82c442c 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -16,6 +16,7 @@
#include "ui/aura/env.h"
#include "ui/aura/event.h"
#include "ui/aura/event_filter.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window_delegate.h"
@@ -465,7 +466,7 @@ void Window::Blur() {
}
bool Window::HasFocus() const {
- const internal::FocusManager* focus_manager = GetFocusManager();
+ const FocusManager* focus_manager = GetFocusManager();
return focus_manager ? focus_manager->IsFocusedWindow(this) : false;
}
@@ -497,12 +498,12 @@ bool Window::CanReceiveEvents() const {
return parent_ && IsVisible() && parent_->CanReceiveEvents();
}
-internal::FocusManager* Window::GetFocusManager() {
- return const_cast<internal::FocusManager*>(
+FocusManager* Window::GetFocusManager() {
+ return const_cast<FocusManager*>(
static_cast<const Window*>(this)->GetFocusManager());
}
-const internal::FocusManager* Window::GetFocusManager() const {
+const FocusManager* Window::GetFocusManager() const {
return parent_ ? parent_->GetFocusManager() : NULL;
}
diff --git a/ui/aura/window.h b/ui/aura/window.h
index ba2cfb0..06f8812 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -38,15 +38,12 @@ class Transform;
namespace aura {
class EventFilter;
+class FocusManager;
class LayoutManager;
class RootWindow;
class WindowDelegate;
class WindowObserver;
-namespace internal {
-class FocusManager;
-}
-
// Defined in window_property.h (which we do not include)
template<typename T>
struct WindowProperty;
@@ -291,8 +288,8 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Returns the FocusManager for the Window, which may be attached to a parent
// Window. Can return NULL if the Window has no FocusManager.
- virtual internal::FocusManager* GetFocusManager();
- virtual const internal::FocusManager* GetFocusManager() const;
+ virtual FocusManager* GetFocusManager();
+ virtual const FocusManager* GetFocusManager() const;
// Does a capture on the window. This does nothing if the window isn't showing
// (VISIBILITY_SHOWN) or isn't contained in a valid window hierarchy.
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 6e5bcbe..0b9cfbc 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -11,7 +11,6 @@
#include "ui/aura/client/stacking_client.h"
#include "ui/aura/client/visibility_client.h"
#include "ui/aura/event.h"
-#include "ui/aura/focus_manager.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/root_window_observer.h"
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 75de8e5..90b17b9 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -15,6 +15,7 @@
#include "ui/aura/client/window_types.h"
#include "ui/aura/env.h"
#include "ui/aura/event.h"
+#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"