summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 06:37:09 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 06:37:09 +0000
commit1aad332c7d47b1adc56708130d36dc1f513b67ae (patch)
tree9103e4927e301881f73e5798d4cac8f2f4986afd /ash
parent382a064036206876b25fdd9052fe073721bebbb5 (diff)
downloadchromium_src-1aad332c7d47b1adc56708130d36dc1f513b67ae.zip
chromium_src-1aad332c7d47b1adc56708130d36dc1f513b67ae.tar.gz
chromium_src-1aad332c7d47b1adc56708130d36dc1f513b67ae.tar.bz2
Add EnvEventFilter to filter events before root window process event
Factor out CursorManager from RootWindowEventFilter Review URL: https://chromiumcodereview.appspot.com/10444107 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140714 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/accelerators/accelerator_filter_unittest.cc1
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/drag_drop/drag_drop_controller.cc15
-rw-r--r--ash/drag_drop/drag_drop_controller_unittest.cc1
-rw-r--r--ash/shell.cc83
-rw-r--r--ash/shell.h28
-rw-r--r--ash/system/tray/system_tray_bubble.cc4
-rw-r--r--ash/tooltips/tooltip_controller.cc4
-rw-r--r--ash/tooltips/tooltip_controller_unittest.cc6
-rw-r--r--ash/wm/app_list_controller.cc4
-rw-r--r--ash/wm/default_window_resizer.cc13
-rw-r--r--ash/wm/power_button_controller.cc12
-rw-r--r--ash/wm/power_button_controller_unittest.cc15
-rw-r--r--ash/wm/shelf_layout_manager.cc4
-rw-r--r--ash/wm/system_gesture_event_filter_unittest.cc2
-rw-r--r--ash/wm/system_modal_container_layout_manager.cc4
-rw-r--r--ash/wm/window_cycle_controller.cc4
-rw-r--r--ash/wm/window_manager_unittest.cc (renamed from ash/wm/root_window_event_filter_unittest.cc)65
-rw-r--r--ash/wm/workspace/frame_maximize_button.cc4
-rw-r--r--ash/wm/workspace/multi_window_resize_controller.cc4
-rw-r--r--ash/wm/workspace/workspace_window_resizer.cc11
21 files changed, 153 insertions, 133 deletions
diff --git a/ash/accelerators/accelerator_filter_unittest.cc b/ash/accelerators/accelerator_filter_unittest.cc
index 86a50fa..3240f4d 100644
--- a/ash/accelerators/accelerator_filter_unittest.cc
+++ b/ash/accelerators/accelerator_filter_unittest.cc
@@ -12,7 +12,6 @@
#include "ash/wm/window_util.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/aura/shared/root_window_event_filter.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_windows.h"
diff --git a/ash/ash.gyp b/ash/ash.gyp
index dbfbe2a..d829a59 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -395,7 +395,6 @@
'wm/image_grid_unittest.cc',
'wm/panel_layout_manager_unittest.cc',
'wm/power_button_controller_unittest.cc',
- 'wm/root_window_event_filter_unittest.cc',
'wm/screen_dimmer_unittest.cc',
'wm/shadow_controller_unittest.cc',
'wm/shelf_layout_manager_unittest.cc',
@@ -407,6 +406,7 @@
'wm/visibility_controller_unittest.cc',
'wm/window_animations_unittest.cc',
'wm/window_cycle_controller_unittest.cc',
+ 'wm/window_manager_unittest.cc',
'wm/window_modality_controller_unittest.cc',
'wm/workspace_controller_test_helper.cc',
'wm/workspace_controller_test_helper.h',
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 366d980..51779a5 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -8,6 +8,7 @@
#include "ash/shell.h"
#include "base/message_loop.h"
#include "ui/aura/client/drag_drop_delegate.h"
+#include "ui/aura/cursor_manager.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
@@ -41,11 +42,11 @@ DragDropController::DragDropController()
drag_window_(NULL),
drag_drop_in_progress_(false),
should_block_during_drag_drop_(true) {
- Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetInstance()->AddEnvEventFilter(this);
}
DragDropController::~DragDropController() {
- Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
Cleanup();
if (drag_image_.get())
drag_image_.reset();
@@ -55,6 +56,7 @@ int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data,
const gfx::Point& root_location,
int operation) {
DCHECK(!drag_drop_in_progress_);
+ // TODO(oshima): Add CaptureClient client API.
aura::Window* capture_window =
Shell::GetPrimaryRootWindow()->capture_window();
if (capture_window)
@@ -122,10 +124,7 @@ void DragDropController::DragUpdate(aura::Window* target,
cursor = ui::kCursorAlias;
else if (op & ui::DragDropTypes::DRAG_MOVE)
cursor = ui::kCursorMove;
- if (drag_window_->GetRootWindow())
- drag_window_->GetRootWindow()->SetCursor(cursor);
- else
- Shell::GetPrimaryRootWindow()->SetCursor(cursor);
+ aura::Env::GetInstance()->cursor_manager()->SetCursor(cursor);
}
}
@@ -138,7 +137,7 @@ void DragDropController::DragUpdate(aura::Window* target,
void DragDropController::Drop(aura::Window* target,
const aura::LocatedEvent& event) {
- Shell::GetPrimaryRootWindow()->SetCursor(ui::kCursorPointer);
+ aura::Env::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer);
aura::client::DragDropDelegate* delegate = NULL;
// We must guarantee that a target gets a OnDragEntered before Drop. WebKit
@@ -167,7 +166,7 @@ void DragDropController::Drop(aura::Window* target,
}
void DragDropController::DragCancel() {
- Shell::GetPrimaryRootWindow()->SetCursor(ui::kCursorPointer);
+ aura::Env::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer);
// |drag_window_| can be NULL if we have just started the drag and have not
// received any DragUpdates, or, if the |drag_window_| gets destroyed during
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 33283db..890a3a2 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -10,7 +10,6 @@
#include "base/utf_string_conversions.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
-#include "ui/aura/shared/root_window_event_filter.h"
#include "ui/aura/test/event_generator.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
diff --git a/ash/shell.cc b/ash/shell.cc
index ccfa5c4..6857519 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -69,13 +69,14 @@
#include "grit/ui_resources.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/user_action_client.h"
+#include "ui/aura/cursor_manager.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"
+#include "ui/aura/shared/compound_event_filter.h"
#include "ui/aura/shared/input_method_event_filter.h"
-#include "ui/aura/shared/root_window_event_filter.h"
#include "ui/aura/ui_controls_aura.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
@@ -562,7 +563,7 @@ internal::WorkspaceController* Shell::TestApi::workspace_controller() {
Shell::Shell(ShellDelegate* delegate)
: root_window_(aura::MonitorManager::CreateRootWindowForPrimaryMonitor()),
screen_(new ScreenAsh(root_window_.get())),
- root_filter_(NULL),
+ env_filter_(NULL),
delegate_(delegate),
#if defined(OS_CHROMEOS)
output_configurator_(new chromeos::OutputConfigurator()),
@@ -584,26 +585,27 @@ Shell::Shell(ShellDelegate* delegate)
Shell::~Shell() {
views::FocusManagerFactory::Install(NULL);
+ aura::Env::GetInstance()->cursor_manager()->set_delegate(NULL);
// Please keep in same order as in Init() because it's easy to miss one.
- RemoveRootWindowEventFilter(key_rewriter_filter_.get());
- RemoveRootWindowEventFilter(partial_screenshot_filter_.get());
- RemoveRootWindowEventFilter(input_method_filter_.get());
- RemoveRootWindowEventFilter(window_modality_controller_.get());
- RemoveRootWindowEventFilter(system_gesture_filter_.get());
- RemoveRootWindowEventFilter(slow_animation_filter_.get());
+ RemoveEnvEventFilter(key_rewriter_filter_.get());
+ RemoveEnvEventFilter(partial_screenshot_filter_.get());
+ RemoveEnvEventFilter(input_method_filter_.get());
+ RemoveEnvEventFilter(window_modality_controller_.get());
+ RemoveEnvEventFilter(system_gesture_filter_.get());
+ RemoveEnvEventFilter(slow_animation_filter_.get());
#if !defined(OS_MACOSX)
- RemoveRootWindowEventFilter(accelerator_filter_.get());
+ RemoveEnvEventFilter(accelerator_filter_.get());
#endif
if (touch_observer_hud_.get())
- RemoveRootWindowEventFilter(touch_observer_hud_.get());
+ RemoveEnvEventFilter(touch_observer_hud_.get());
// Close background widget now so that the focus manager of the
// widget gets deleted in the final message loop run.
root_window_layout_->SetBackgroundWidget(NULL);
// TooltipController is deleted with the Shell so removing its references.
- RemoveRootWindowEventFilter(tooltip_controller_.get());
+ RemoveEnvEventFilter(tooltip_controller_.get());
aura::client::SetTooltipClient(GetPrimaryRootWindow(), NULL);
// Make sure we delete WorkspaceController before launcher is
@@ -708,13 +710,18 @@ void Shell::Init() {
// Launcher, and WallPaper could be created by the factory.
views::FocusManagerFactory::Install(new AshFocusManagerFactory);
+ env_filter_ = new aura::shared::CompoundEventFilter;
+ // Pass ownership of the filter to the Env.
+ aura::Env::GetInstance()->SetEventFilter(env_filter_);
+
+ aura::Env::GetInstance()->cursor_manager()->set_delegate(this);
+
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);
aura::client::SetDispatcherClient(root_window,
@@ -722,41 +729,39 @@ void Shell::Init() {
accelerator_controller_.reset(new AcceleratorController);
#endif
shell_context_menu_.reset(new internal::ShellContextMenu);
- // Pass ownership of the filter to the root window.
- root_window->SetEventFilter(root_filter_);
// KeyRewriterEventFilter must be the first one.
- DCHECK(!GetRootWindowEventFilterCount());
+ DCHECK(!GetEnvEventFilterCount());
key_rewriter_filter_.reset(new internal::KeyRewriterEventFilter);
- AddRootWindowEventFilter(key_rewriter_filter_.get());
+ AddEnvEventFilter(key_rewriter_filter_.get());
// PartialScreenshotEventFilter must be the second one to capture key
// events when the taking partial screenshot UI is there.
- DCHECK_EQ(1U, GetRootWindowEventFilterCount());
+ DCHECK_EQ(1U, GetEnvEventFilterCount());
partial_screenshot_filter_.reset(new internal::PartialScreenshotEventFilter);
- AddRootWindowEventFilter(partial_screenshot_filter_.get());
+ AddEnvEventFilter(partial_screenshot_filter_.get());
AddShellObserver(partial_screenshot_filter_.get());
// InputMethodEventFilter must be the third one. It has to be added before
// AcceleratorFilter.
- DCHECK_EQ(2U, GetRootWindowEventFilterCount());
+ DCHECK_EQ(2U, GetEnvEventFilterCount());
input_method_filter_.reset(new aura::shared::InputMethodEventFilter());
input_method_filter_->SetInputMethodPropertyInRootWindow(root_window);
- AddRootWindowEventFilter(input_method_filter_.get());
+ AddEnvEventFilter(input_method_filter_.get());
#if !defined(OS_MACOSX)
accelerator_filter_.reset(new internal::AcceleratorFilter);
- AddRootWindowEventFilter(accelerator_filter_.get());
+ AddEnvEventFilter(accelerator_filter_.get());
#endif
system_gesture_filter_.reset(new internal::SystemGestureEventFilter);
- AddRootWindowEventFilter(system_gesture_filter_.get());
+ AddEnvEventFilter(system_gesture_filter_.get());
slow_animation_filter_.reset(new internal::SlowAnimationEventFilter);
- AddRootWindowEventFilter(slow_animation_filter_.get());
+ AddEnvEventFilter(slow_animation_filter_.get());
root_window->SetCursor(ui::kCursorPointer);
if (initially_hide_cursor_)
- root_window->ShowCursor(false);
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(false);
activation_controller_.reset(
new internal::ActivationController(focus_manager_.get()));
@@ -768,7 +773,7 @@ void Shell::Init() {
if (command_line->HasSwitch(switches::kAshTouchHud)) {
touch_observer_hud_.reset(new internal::TouchObserverHUD);
- AddRootWindowEventFilter(touch_observer_hud_.get());
+ AddEnvEventFilter(touch_observer_hud_.get());
}
stacking_controller_.reset(new internal::StackingController);
@@ -829,7 +834,7 @@ void Shell::Init() {
user_wallpaper_delegate_->SetLoggedInUserWallpaper();
window_modality_controller_.reset(new internal::WindowModalityController);
- AddRootWindowEventFilter(window_modality_controller_.get());
+ AddEnvEventFilter(window_modality_controller_.get());
visibility_controller_.reset(new internal::VisibilityController);
aura::client::SetVisibilityClient(root_window, visibility_controller_.get());
@@ -841,7 +846,7 @@ void Shell::Init() {
new internal::TooltipController(drag_drop_controller_.get()));
aura::client::SetTooltipClient(root_window, tooltip_controller_.get());
- AddRootWindowEventFilter(tooltip_controller_.get());
+ AddEnvEventFilter(tooltip_controller_.get());
magnification_controller_.reset(new internal::MagnificationController);
high_contrast_controller_.reset(new HighContrastController);
@@ -862,19 +867,16 @@ const aura::Window* Shell::GetContainer(int container_id) const {
return GetPrimaryRootWindow()->GetChildById(container_id);
}
-void Shell::AddRootWindowEventFilter(aura::EventFilter* filter) {
- static_cast<aura::shared::RootWindowEventFilter*>(
- GetPrimaryRootWindow()->event_filter())->AddFilter(filter);
+void Shell::AddEnvEventFilter(aura::EventFilter* filter) {
+ env_filter_->AddFilter(filter);
}
-void Shell::RemoveRootWindowEventFilter(aura::EventFilter* filter) {
- static_cast<aura::shared::RootWindowEventFilter*>(
- GetPrimaryRootWindow()->event_filter())->RemoveFilter(filter);
+void Shell::RemoveEnvEventFilter(aura::EventFilter* filter) {
+ env_filter_->RemoveFilter(filter);
}
-size_t Shell::GetRootWindowEventFilterCount() const {
- return static_cast<aura::shared::RootWindowEventFilter*>(
- GetPrimaryRootWindow()->event_filter())->GetFilterCount();
+size_t Shell::GetEnvEventFilterCount() const {
+ return env_filter_->GetFilterCount();
}
void Shell::ShowBackgroundMenu(views::Widget* widget,
@@ -1071,4 +1073,13 @@ void Shell::DisableWorkspaceGridLayout() {
workspace_controller_->workspace_manager()->set_grid_size(0);
}
+void Shell::SetCursor(gfx::NativeCursor cursor) {
+ // TODO(oshima): set cursor to all root windows.
+ GetPrimaryRootWindow()->SetCursor(cursor);
+}
+
+void Shell::ShowCursor(bool visible) {
+ GetPrimaryRootWindow()->ShowCursor(visible);
+}
+
} // namespace ash
diff --git a/ash/shell.h b/ash/shell.h
index ef4cb34..d73d85c 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -17,6 +17,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
+#include "ui/aura/cursor_delegate.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/size.h"
@@ -32,8 +33,8 @@ namespace client {
class UserActionClient;
}
namespace shared {
+class CompoundEventFilter;
class InputMethodEventFilter;
-class RootWindowEventFilter;
}
}
namespace chromeos {
@@ -107,7 +108,7 @@ class WorkspaceController;
//
// Upon creation, the Shell sets itself as the RootWindow's delegate, which
// takes ownership of the Shell.
-class ASH_EXPORT Shell {
+class ASH_EXPORT Shell : aura::CursorDelegate {
public:
enum Direction {
FORWARD,
@@ -168,10 +169,10 @@ class ASH_EXPORT Shell {
aura::Window* GetContainer(int container_id);
const aura::Window* GetContainer(int container_id) const;
- // Adds or removes |filter| from the RootWindowEventFilter.
- void AddRootWindowEventFilter(aura::EventFilter* filter);
- void RemoveRootWindowEventFilter(aura::EventFilter* filter);
- size_t GetRootWindowEventFilterCount() const;
+ // Adds or removes |filter| from the aura::Env's CompoundEventFilter.
+ void AddEnvEventFilter(aura::EventFilter* filter);
+ void RemoveEnvEventFilter(aura::EventFilter* filter);
+ size_t GetEnvEventFilterCount() const;
// Shows the background menu over |widget|.
void ShowBackgroundMenu(views::Widget* widget, const gfx::Point& location);
@@ -229,8 +230,8 @@ class ASH_EXPORT Shell {
}
#endif // !defined(OS_MACOSX)
- aura::shared::RootWindowEventFilter* root_filter() {
- return root_filter_;
+ aura::shared::CompoundEventFilter* env_filter() {
+ return env_filter_;
}
internal::TooltipController* tooltip_controller() {
return tooltip_controller_.get();
@@ -332,8 +333,8 @@ class ASH_EXPORT Shell {
#endif // defined(OS_CHROMEOS)
private:
- FRIEND_TEST_ALL_PREFIXES(RootWindowEventFilterTest, MouseEventCursors);
- FRIEND_TEST_ALL_PREFIXES(RootWindowEventFilterTest, TransformActivate);
+ FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, MouseEventCursors);
+ FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, TransformActivate);
typedef std::pair<aura::Window*, gfx::Rect> WindowAndBoundsPair;
@@ -348,6 +349,10 @@ class ASH_EXPORT Shell {
// Disables the workspace grid layout.
void DisableWorkspaceGridLayout();
+ // aura::CursorManager::Delegate overrides:
+ virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE;
+ virtual void ShowCursor(bool visible) OVERRIDE;
+
static Shell* instance_;
// If set before the Shell is initialized, the mouse cursor will be hidden
@@ -360,7 +365,8 @@ class ASH_EXPORT Shell {
// Active root window. Never become NULL.
aura::RootWindow* active_root_window_;
- aura::shared::RootWindowEventFilter* root_filter_; // not owned
+ // The CompoundEventFilter owned by aura::Env object.
+ aura::shared::CompoundEventFilter* env_filter_;
std::vector<WindowAndBoundsPair> to_restore_;
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc
index 04718d3..a15bd59 100644
--- a/ash/system/tray/system_tray_bubble.cc
+++ b/ash/system/tray/system_tray_bubble.cc
@@ -416,12 +416,12 @@ SystemTrayBubble::SystemTrayBubble(
anchor_type_(ANCHOR_TYPE_TRAY),
autoclose_delay_(0) {
if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION)
- Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetInstance()->AddEnvEventFilter(this);
}
SystemTrayBubble::~SystemTrayBubble() {
if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION)
- Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
DestroyItemViews();
// Reset the host pointer in bubble_view_ in case its destruction is deferred.
diff --git a/ash/tooltips/tooltip_controller.cc b/ash/tooltips/tooltip_controller.cc
index bb0f55e..368603d 100644
--- a/ash/tooltips/tooltip_controller.cc
+++ b/ash/tooltips/tooltip_controller.cc
@@ -13,6 +13,8 @@
#include "base/string_split.h"
#include "base/time.h"
#include "ui/aura/client/drag_drop_client.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
@@ -375,7 +377,7 @@ void TooltipController::TooltipTimerFired() {
void TooltipController::UpdateIfRequired() {
if (!tooltips_enabled_ || mouse_pressed_ || IsDragDropInProgress() ||
- !Shell::GetPrimaryRootWindow()->cursor_shown()) {
+ !aura::Env::GetInstance()->cursor_manager()->cursor_visible()) {
tooltip_->Hide();
return;
}
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc
index 5cb972d5..1665f1a 100644
--- a/ash/tooltips/tooltip_controller_unittest.cc
+++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -7,6 +7,8 @@
#include "ash/tooltips/tooltip_controller.h"
#include "base/utf_string_conversions.h"
#include "ui/aura/client/tooltip_client.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/window.h"
@@ -244,12 +246,12 @@ TEST_F(TooltipControllerTest, HideTooltipWhenCursorHidden) {
EXPECT_TRUE(IsTooltipVisible());
// Hide the cursor and check again.
- Shell::GetPrimaryRootWindow()->ShowCursor(false);
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(false);
FireTooltipTimer();
EXPECT_FALSE(IsTooltipVisible());
// Show the cursor and re-check.
- Shell::GetPrimaryRootWindow()->ShowCursor(true);
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(true);
FireTooltipTimer();
EXPECT_TRUE(IsTooltipVisible());
}
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index fb6159b..a8c227b 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -151,7 +151,7 @@ void AppListController::SetView(app_list::AppListView* view) {
view_ = view;
views::Widget* widget = view_->GetWidget();
widget->AddObserver(this);
- Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetInstance()->AddEnvEventFilter(this);
widget->GetNativeView()->GetRootWindow()->AddRootWindowObserver(this);
widget->GetNativeView()->GetFocusManager()->AddObserver(this);
widget->SetOpacity(0);
@@ -170,7 +170,7 @@ void AppListController::ResetView() {
views::Widget* widget = view_->GetWidget();
widget->RemoveObserver(this);
GetLayer(widget)->GetAnimator()->RemoveObserver(this);
- Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
widget->GetNativeView()->GetRootWindow()->RemoveRootWindowObserver(this);
widget->GetNativeView()->GetFocusManager()->RemoveObserver(this);
view_ = NULL;
diff --git a/ash/wm/default_window_resizer.cc b/ash/wm/default_window_resizer.cc
index b71db4c..8b57115 100644
--- a/ash/wm/default_window_resizer.cc
+++ b/ash/wm/default_window_resizer.cc
@@ -6,8 +6,9 @@
#include "ash/shell.h"
#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
-#include "ui/aura/shared/root_window_event_filter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
@@ -19,8 +20,7 @@
namespace ash {
DefaultWindowResizer::~DefaultWindowResizer() {
- if (root_filter_)
- root_filter_->UnlockCursor();
+ aura::Env::GetInstance()->cursor_manager()->UnlockCursor();
}
// static
@@ -74,12 +74,9 @@ void DefaultWindowResizer::RevertDrag() {
DefaultWindowResizer::DefaultWindowResizer(const Details& details)
: details_(details),
- did_move_or_resize_(false),
- root_filter_(NULL) {
+ did_move_or_resize_(false) {
DCHECK(details_.is_resizable);
- root_filter_ = Shell::GetInstance()->root_filter();
- if (root_filter_)
- root_filter_->LockCursor();
+ aura::Env::GetInstance()->cursor_manager()->LockCursor();
}
} // namespace aura
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index a3f1493..8b7deb7 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -11,8 +11,10 @@
#include "base/logging.h"
#include "base/time.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
-#include "ui/aura/shared/root_window_event_filter.h"
+#include "ui/aura/shared/compound_event_filter.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_element.h"
@@ -307,9 +309,9 @@ void PowerButtonController::OnAppTerminating() {
// can really hope for is that we'll have time to clear the screen.
if (!shutting_down_) {
shutting_down_ = true;
- ash::Shell::GetInstance()->root_filter()->
+ ash::Shell::GetInstance()->env_filter()->
set_update_cursor_visibility(false);
- Shell::GetPrimaryRootWindow()->ShowCursor(false);
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(false);
ShowBackgroundLayer();
StartAnimation(ALL_CONTAINERS, ANIMATION_HIDE);
}
@@ -532,8 +534,8 @@ void PowerButtonController::StartShutdownAnimationAndRequestShutdown() {
DCHECK(!shutting_down_);
shutting_down_ = true;
- ash::Shell::GetInstance()->root_filter()->set_update_cursor_visibility(false);
- Shell::GetPrimaryRootWindow()->ShowCursor(false);
+ ash::Shell::GetInstance()->env_filter()->set_update_cursor_visibility(false);
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(false);
ShowBackgroundLayer();
if (login_status_ != user::LOGGED_IN_NONE) {
diff --git a/ash/wm/power_button_controller_unittest.cc b/ash/wm/power_button_controller_unittest.cc
index e908d30..14f0232 100644
--- a/ash/wm/power_button_controller_unittest.cc
+++ b/ash/wm/power_button_controller_unittest.cc
@@ -8,12 +8,19 @@
#include "ash/test/ash_test_base.h"
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
namespace ash {
namespace test {
+namespace {
+bool cursor_visible() {
+ return aura::Env::GetInstance()->cursor_manager()->cursor_visible();
+}
+}
// Fake implementation of PowerButtonControllerDelegate that just logs requests
// to lock the screen and shut down the device.
@@ -114,7 +121,7 @@ TEST_F(PowerButtonControllerTest, LegacyLockAndShutDown) {
test_api_->ContainerGroupIsAnimated(
PowerButtonController::ALL_CONTAINERS,
PowerButtonController::ANIMATION_FAST_CLOSE));
- EXPECT_FALSE(Shell::GetPrimaryRootWindow()->cursor_shown());
+ EXPECT_FALSE(cursor_visible());
EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
test_api_->trigger_real_shutdown_timeout();
EXPECT_EQ(1, delegate_->num_shutdown_requests());
@@ -481,7 +488,7 @@ TEST_F(PowerButtonControllerTest, ShutdownWithoutButton) {
PowerButtonController::ALL_CONTAINERS,
PowerButtonController::ANIMATION_HIDE));
EXPECT_TRUE(test_api_->BackgroundLayerIsVisible());
- EXPECT_FALSE(Shell::GetPrimaryRootWindow()->cursor_shown());
+ EXPECT_FALSE(cursor_visible());
}
// Test that we display the fast-close animation and shut down when we get an
@@ -498,7 +505,7 @@ TEST_F(PowerButtonControllerTest, RequestShutdownFromLoginScreen) {
PowerButtonController::SCREEN_LOCKER_AND_RELATED_CONTAINERS,
PowerButtonController::ANIMATION_FAST_CLOSE));
EXPECT_TRUE(test_api_->BackgroundLayerIsVisible());
- EXPECT_FALSE(Shell::GetPrimaryRootWindow()->cursor_shown());
+ EXPECT_FALSE(cursor_visible());
EXPECT_EQ(0, delegate_->num_shutdown_requests());
EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
@@ -519,7 +526,7 @@ TEST_F(PowerButtonControllerTest, RequestShutdownFromLockScreen) {
PowerButtonController::SCREEN_LOCKER_AND_RELATED_CONTAINERS,
PowerButtonController::ANIMATION_FAST_CLOSE));
EXPECT_TRUE(test_api_->BackgroundLayerIsVisible());
- EXPECT_FALSE(Shell::GetPrimaryRootWindow()->cursor_shown());
+ EXPECT_FALSE(cursor_visible());
EXPECT_EQ(0, delegate_->num_shutdown_requests());
EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc
index 1634557..3f2e857 100644
--- a/ash/wm/shelf_layout_manager.cc
+++ b/ash/wm/shelf_layout_manager.cc
@@ -78,11 +78,11 @@ ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
ShelfLayoutManager* shelf)
: shelf_(shelf),
in_mouse_drag_(false) {
- Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetInstance()->AddEnvEventFilter(this);
}
ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
- Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
}
bool ShelfLayoutManager::AutoHideEventFilter::PreHandleKeyEvent(
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index c22b168..5070b14 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -119,7 +119,7 @@ TEST_F(SystemGestureEventFilterTest, TapOutsideRootWindow) {
// Without the event filter, the touch shouldn't be consumed by the
// system event handler.
- Shell::GetInstance()->RemoveRootWindowEventFilter(
+ Shell::GetInstance()->RemoveEnvEventFilter(
shell_test.system_gesture_event_filter());
aura::GestureEvent* event2 = new aura::GestureEvent(
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc
index ae5dd63..d07a5c7 100644
--- a/ash/wm/system_modal_container_layout_manager.cc
+++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -191,7 +191,7 @@ void SystemModalContainerLayoutManager::CreateModalScreen() {
modal_screen_->SetContentsView(new ScreenView);
modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);
- Shell::GetInstance()->AddRootWindowEventFilter(modality_filter_.get());
+ Shell::GetInstance()->AddEnvEventFilter(modality_filter_.get());
}
ui::ScopedLayerAnimationSettings settings(
@@ -202,7 +202,7 @@ void SystemModalContainerLayoutManager::CreateModalScreen() {
}
void SystemModalContainerLayoutManager::DestroyModalScreen() {
- Shell::GetInstance()->RemoveRootWindowEventFilter(modality_filter_.get());
+ Shell::GetInstance()->RemoveEnvEventFilter(modality_filter_.get());
ui::ScopedLayerAnimationSettings settings(
modal_screen_->GetNativeView()->layer()->GetAnimator());
modal_screen_->Close();
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc
index 771ea2b..a79ed88 100644
--- a/ash/wm/window_cycle_controller.cc
+++ b/ash/wm/window_cycle_controller.cc
@@ -159,14 +159,14 @@ void WindowCycleController::StopCycling() {
windows_.reset();
// Remove our key event filter.
if (event_filter_.get()) {
- Shell::GetInstance()->RemoveRootWindowEventFilter(event_filter_.get());
+ Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get());
event_filter_.reset();
}
}
void WindowCycleController::InstallEventFilter() {
event_filter_.reset(new WindowCycleEventFilter());
- Shell::GetInstance()->AddRootWindowEventFilter(event_filter_.get());
+ Shell::GetInstance()->AddEnvEventFilter(event_filter_.get());
}
} // namespace ash
diff --git a/ash/wm/root_window_event_filter_unittest.cc b/ash/wm/window_manager_unittest.cc
index 10fb0442..60a9617 100644
--- a/ash/wm/root_window_event_filter_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -10,11 +10,13 @@
#include "ash/wm/window_util.h"
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/activation_delegate.h"
+#include "ui/aura/cursor_manager.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/shared/compound_event_filter.h"
#include "ui/aura/shared/input_method_event_filter.h"
-#include "ui/aura/shared/root_window_event_filter.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_event_filter.h"
@@ -24,9 +26,6 @@
#include "ui/base/hit_test.h"
#include "ui/gfx/screen.h"
-// TODO(erg,beng): This file is misnamed; it really acts as an integration test
-// between most of the ash::Shell() objects, not just RootWindowEventFitler.
-
namespace {
base::TimeDelta getTime() {
@@ -37,7 +36,7 @@ base::TimeDelta getTime() {
namespace ash {
-typedef test::AshTestBase RootWindowEventFilterTest;
+typedef test::AshTestBase WindowManagerTest;
class NonFocusableDelegate : public aura::test::TestWindowDelegate {
public:
@@ -70,11 +69,11 @@ class HitTestWindowDelegate : public aura::test::TestWindowDelegate {
DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate);
};
-TEST_F(RootWindowEventFilterTest, Focus) {
+TEST_F(WindowManagerTest, Focus) {
// The IME event filter interferes with the basic key event propagation we
// attempt to do here, so we remove it.
Shell::TestApi shell_test(Shell::GetInstance());
- Shell::GetInstance()->RemoveRootWindowEventFilter(
+ Shell::GetInstance()->RemoveEnvEventFilter(
shell_test.input_method_event_filter());
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
@@ -179,7 +178,7 @@ TEST_F(RootWindowEventFilterTest, Focus) {
}
// Various assertion testing for activating windows.
-TEST_F(RootWindowEventFilterTest, ActivateOnMouse) {
+TEST_F(WindowManagerTest, ActivateOnMouse) {
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
test::TestActivationDelegate d1;
@@ -295,7 +294,7 @@ TEST_F(RootWindowEventFilterTest, ActivateOnMouse) {
}
// Essentially the same as ActivateOnMouse, but for touch events.
-TEST_F(RootWindowEventFilterTest, ActivateOnTouch) {
+TEST_F(WindowManagerTest, ActivateOnTouch) {
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
test::TestActivationDelegate d1;
@@ -365,7 +364,7 @@ TEST_F(RootWindowEventFilterTest, ActivateOnTouch) {
EXPECT_EQ(0, d1.lost_active_count());
}
-TEST_F(RootWindowEventFilterTest, MouseEventCursors) {
+TEST_F(WindowManagerTest, MouseEventCursors) {
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
// Disable ash grid so that test can place a window at
// specific location.
@@ -441,7 +440,7 @@ TEST_F(RootWindowEventFilterTest, MouseEventCursors) {
#else
#define MAYBE_TransformActivate TransformActivate
#endif
-TEST_F(RootWindowEventFilterTest, MAYBE_TransformActivate) {
+TEST_F(WindowManagerTest, MAYBE_TransformActivate) {
// Disable ash grid so that test can place a window at
// specific location.
ash::Shell::GetInstance()->DisableWorkspaceGridLayout();
@@ -490,11 +489,11 @@ TEST_F(RootWindowEventFilterTest, MAYBE_TransformActivate) {
EXPECT_EQ(w1.get(), w1->GetFocusManager()->GetFocusedWindow());
}
-TEST_F(RootWindowEventFilterTest, AdditionalFilters) {
+TEST_F(WindowManagerTest, AdditionalFilters) {
// The IME event filter interferes with the basic key event propagation we
// attempt to do here, so we remove it.
Shell::TestApi shell_test(Shell::GetInstance());
- Shell::GetInstance()->RemoveRootWindowEventFilter(
+ Shell::GetInstance()->RemoveEnvEventFilter(
shell_test.input_method_event_filter());
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
@@ -509,11 +508,10 @@ TEST_F(RootWindowEventFilterTest, AdditionalFilters) {
scoped_ptr<aura::test::TestEventFilter> f2(new aura::test::TestEventFilter);
// Adds them to root window event filter.
- aura::shared::RootWindowEventFilter* root_window_filter =
- static_cast<aura::shared::RootWindowEventFilter*>(
- root_window->event_filter());
- root_window_filter->AddFilter(f1.get());
- root_window_filter->AddFilter(f2.get());
+ aura::shared::CompoundEventFilter* env_filter =
+ Shell::GetInstance()->env_filter();
+ env_filter->AddFilter(f1.get());
+ env_filter->AddFilter(f2.get());
// Dispatches mouse and keyboard events.
aura::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
@@ -551,7 +549,7 @@ TEST_F(RootWindowEventFilterTest, AdditionalFilters) {
f2->ResetCounts();
// Remove f1 from additonal filters list.
- root_window_filter->RemoveFilter(f1.get());
+ env_filter->RemoveFilter(f1.get());
// Dispatches events.
root_window->DispatchKeyEvent(&key_event);
@@ -563,20 +561,21 @@ TEST_F(RootWindowEventFilterTest, AdditionalFilters) {
EXPECT_EQ(1, f2->key_event_count());
EXPECT_EQ(1, f2->mouse_event_count());
- root_window_filter->RemoveFilter(f2.get());
+ env_filter->RemoveFilter(f2.get());
}
// We should show and hide the cursor in response to mouse and touch events as
// requested.
-TEST_F(RootWindowEventFilterTest, UpdateCursorVisibility) {
+TEST_F(WindowManagerTest, UpdateCursorVisibility) {
aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
root_window->SetBounds(gfx::Rect(0, 0, 500, 500));
scoped_ptr<aura::Window> window(aura::test::CreateTestWindow(
SK_ColorWHITE, -1, gfx::Rect(0, 0, 500, 500), NULL));
- aura::shared::RootWindowEventFilter* root_window_filter =
- static_cast<aura::shared::RootWindowEventFilter*>(
- root_window->event_filter());
+ aura::shared::CompoundEventFilter* env_filter =
+ Shell::GetInstance()->env_filter();
+ aura::CursorManager* cursor_manager =
+ aura::Env::GetInstance()->cursor_manager();
aura::MouseEvent mouse_moved(
ui::ET_MOUSE_MOVED, gfx::Point(0, 0), gfx::Point(0, 0), 0x0);
@@ -585,21 +584,21 @@ TEST_F(RootWindowEventFilterTest, UpdateCursorVisibility) {
aura::TouchEvent touch_pressed2(
ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 1, getTime());
- root_window_filter->set_update_cursor_visibility(true);
+ env_filter->set_update_cursor_visibility(true);
root_window->DispatchMouseEvent(&mouse_moved);
- EXPECT_TRUE(root_window->cursor_shown());
+ EXPECT_TRUE(cursor_manager->cursor_visible());
root_window->DispatchTouchEvent(&touch_pressed1);
- EXPECT_FALSE(root_window->cursor_shown());
+ EXPECT_FALSE(cursor_manager->cursor_visible());
root_window->DispatchMouseEvent(&mouse_moved);
- EXPECT_TRUE(root_window->cursor_shown());
+ EXPECT_TRUE(cursor_manager->cursor_visible());
- root_window_filter->set_update_cursor_visibility(false);
- root_window->ShowCursor(false);
+ env_filter->set_update_cursor_visibility(false);
+ cursor_manager->ShowCursor(false);
root_window->DispatchMouseEvent(&mouse_moved);
- EXPECT_FALSE(root_window->cursor_shown());
- root_window->ShowCursor(true);
+ EXPECT_FALSE(cursor_manager->cursor_visible());
+ cursor_manager->ShowCursor(true);
root_window->DispatchTouchEvent(&touch_pressed2);
- EXPECT_TRUE(root_window->cursor_shown());
+ EXPECT_TRUE(cursor_manager->cursor_visible());
}
} // namespace ash
diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc
index ec986ed..06afc02 100644
--- a/ash/wm/workspace/frame_maximize_button.cc
+++ b/ash/wm/workspace/frame_maximize_button.cc
@@ -62,11 +62,11 @@ class FrameMaximizeButton::EscapeEventFilter : public aura::EventFilter {
FrameMaximizeButton::EscapeEventFilter::EscapeEventFilter(
FrameMaximizeButton* button)
: button_(button) {
- Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetInstance()->AddEnvEventFilter(this);
}
FrameMaximizeButton::EscapeEventFilter::~EscapeEventFilter() {
- Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
}
bool FrameMaximizeButton::EscapeEventFilter::PreHandleKeyEvent(
diff --git a/ash/wm/workspace/multi_window_resize_controller.cc b/ash/wm/workspace/multi_window_resize_controller.cc
index 9219027..4b3ee2d 100644
--- a/ash/wm/workspace/multi_window_resize_controller.cc
+++ b/ash/wm/workspace/multi_window_resize_controller.cc
@@ -12,7 +12,7 @@
#include "grit/ui_resources.h"
#include "ui/aura/event_filter.h"
#include "ui/aura/root_window.h"
-#include "ui/aura/shared/root_window_event_filter.h"
+#include "ui/aura/shared/compound_event_filter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
@@ -98,7 +98,7 @@ class MultiWindowResizeController::ResizeView : public views::View {
virtual gfx::NativeCursor GetCursor(
const views::MouseEvent& event) OVERRIDE {
int component = (direction_ == LEFT_RIGHT) ? HTRIGHT : HTBOTTOM;
- return aura::shared::RootWindowEventFilter::CursorForWindowComponent(
+ return aura::shared::CompoundEventFilter::CursorForWindowComponent(
component);
}
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 4982457..9065d8d 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -12,7 +12,8 @@
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/wm/workspace/snap_sizer.h"
-#include "ui/aura/shared/root_window_event_filter.h"
+#include "ui/aura/cursor_manager.h"
+#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
@@ -44,8 +45,7 @@ const int WorkspaceWindowResizer::kMinOnscreenSize = 20;
const int WorkspaceWindowResizer::kMinOnscreenHeight = 32;
WorkspaceWindowResizer::~WorkspaceWindowResizer() {
- if (root_filter_)
- root_filter_->UnlockCursor();
+ aura::Env::GetInstance()->cursor_manager()->UnlockCursor();
}
// static
@@ -148,15 +148,12 @@ WorkspaceWindowResizer::WorkspaceWindowResizer(
: details_(details),
attached_windows_(attached_windows),
did_move_or_resize_(false),
- root_filter_(NULL),
total_min_(0),
total_initial_size_(0),
snap_type_(SNAP_NONE),
num_mouse_moves_since_bounds_change_(0) {
DCHECK(details_.is_resizable);
- root_filter_ = Shell::GetInstance()->root_filter();
- if (root_filter_)
- root_filter_->LockCursor();
+ aura::Env::GetInstance()->cursor_manager()->LockCursor();
// Only support attaching to the right/bottom.
DCHECK(attached_windows_.empty() ||