summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/aura/aura.gyp5
-rw-r--r--ui/aura/client/stacking_client.h5
-rw-r--r--ui/aura/desktop.cc134
-rw-r--r--ui/aura/desktop.h1
-rw-r--r--ui/aura/desktop_unittest.cc124
-rw-r--r--ui/aura/test/test_stacking_client.cc15
-rw-r--r--ui/aura/test/test_stacking_client.h6
-rw-r--r--ui/aura/test/test_window_delegate.cc57
-rw-r--r--ui/aura/test/test_window_delegate.h49
-rw-r--r--ui/aura/test/test_windows.cc45
-rw-r--r--ui/aura/test/test_windows.h35
-rw-r--r--ui/aura/toplevel_window_container.cc37
-rw-r--r--ui/aura/toplevel_window_container.h34
-rw-r--r--ui/aura/window.cc18
-rw-r--r--ui/aura/window.h9
-rw-r--r--ui/aura/window_unittest.cc353
-rw-r--r--ui/aura_shell/aura_shell.gyp12
-rw-r--r--ui/aura_shell/default_container_event_filter.cc3
-rw-r--r--ui/aura_shell/desktop_event_filter.cc109
-rw-r--r--ui/aura_shell/desktop_event_filter.h43
-rw-r--r--ui/aura_shell/desktop_event_filter_unittest.cc319
-rw-r--r--ui/aura_shell/launcher/launcher.cc4
-rw-r--r--ui/aura_shell/launcher/launcher.h6
-rw-r--r--ui/aura_shell/run_all_unittests.cc2
-rw-r--r--ui/aura_shell/shell.cc56
-rw-r--r--ui/aura_shell/shell.h10
-rw-r--r--ui/aura_shell/stacking_controller.cc95
-rw-r--r--ui/aura_shell/stacking_controller.h38
-rw-r--r--ui/aura_shell/stacking_controller_unittest.cc34
-rw-r--r--ui/aura_shell/test_suite.cc6
-rw-r--r--ui/aura_shell/test_suite.h6
-rw-r--r--ui/aura_shell/toplevel_layout_manager.h8
-rw-r--r--ui/aura_shell/workspace_controller_unittest.cc6
-rw-r--r--views/widget/native_widget_aura.cc3
34 files changed, 928 insertions, 759 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index 144069c..96712f4 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -44,8 +44,6 @@
'layout_manager.h',
'screen_aura.cc',
'screen_aura.h',
- 'toplevel_window_container.cc',
- 'toplevel_window_container.h',
'window.cc',
'window.h',
'window_delegate.h',
@@ -73,6 +71,8 @@
'test/event_generator.h',
'test/test_stacking_client.cc',
'test/test_stacking_client.h',
+ 'test/test_windows.cc',
+ 'test/test_windows.h',
'test/test_window_delegate.cc',
'test/test_window_delegate.h',
],
@@ -126,7 +126,6 @@
'test/run_all_unittests.cc',
'test/test_suite.cc',
'test/test_suite.h',
- 'desktop_unittest.cc',
'event_filter_unittest.cc',
'window_unittest.cc',
'<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc',
diff --git a/ui/aura/client/stacking_client.h b/ui/aura/client/stacking_client.h
index c56e319..26d137b 100644
--- a/ui/aura/client/stacking_client.h
+++ b/ui/aura/client/stacking_client.h
@@ -22,6 +22,11 @@ class AURA_EXPORT StackingClient {
// of its choosing.
virtual void AddChildToDefaultParent(Window* window) = 0;
+ // Returns true if |window| can be activated or deactivated.
+ // A window manager typically defines some notion of "top level window" that
+ // supports activation/deactivation.
+ virtual bool CanActivateWindow(Window* window) const = 0;
+
// Returns the window that should be activated other than |ignore|.
virtual Window* GetTopmostWindowToActivate(Window* ignore) const = 0;
};
diff --git a/ui/aura/desktop.cc b/ui/aura/desktop.cc
index dd5cf98..d08a062 100644
--- a/ui/aura/desktop.cc
+++ b/ui/aura/desktop.cc
@@ -21,7 +21,6 @@
#include "ui/aura/event_filter.h"
#include "ui/aura/focus_manager.h"
#include "ui/aura/screen_aura.h"
-#include "ui/aura/toplevel_window_container.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
@@ -45,30 +44,6 @@ static const int kDefaultHostWindowY = 200;
static const int kDefaultHostWindowWidth = 1280;
static const int kDefaultHostWindowHeight = 1024;
-// Returns the default cursor for a window component.
-gfx::NativeCursor CursorForWindowComponent(int window_component) {
- switch (window_component) {
- case HTBOTTOM:
- return aura::kCursorSouthResize;
- case HTBOTTOMLEFT:
- return aura::kCursorSouthWestResize;
- case HTBOTTOMRIGHT:
- return aura::kCursorSouthEastResize;
- case HTLEFT:
- return aura::kCursorWestResize;
- case HTRIGHT:
- return aura::kCursorEastResize;
- case HTTOP:
- return aura::kCursorNorthResize;
- case HTTOPLEFT:
- return aura::kCursorNorthWestResize;
- case HTTOPRIGHT:
- return aura::kCursorNorthEastResize;
- default:
- return aura::kCursorNull;
- }
-}
-
bool IsNonClientLocation(Window* target, const gfx::Point& location) {
if (!target->delegate())
return false;
@@ -82,10 +57,14 @@ class DefaultStackingClient : public StackingClient {
virtual ~DefaultStackingClient() {}
private:
+
+ // Overridden from StackingClient:
virtual void AddChildToDefaultParent(Window* window) OVERRIDE {
desktop_->AddChild(window);
}
-
+ virtual bool CanActivateWindow(Window* window) const OVERRIDE {
+ return window->parent() == desktop_;
+ }
virtual Window* GetTopmostWindowToActivate(Window* ignore) const OVERRIDE {
Window::Windows::const_reverse_iterator i;
for (i = desktop_->children().rbegin();
@@ -103,79 +82,6 @@ class DefaultStackingClient : public StackingClient {
DISALLOW_COPY_AND_ASSIGN(DefaultStackingClient);
};
-class DesktopEventFilter : public EventFilter {
- public:
- explicit DesktopEventFilter(Window* owner) : EventFilter(owner) {}
- virtual ~DesktopEventFilter() {}
-
- // Overridden from EventFilter:
- virtual bool PreHandleKeyEvent(Window* target, KeyEvent* event) OVERRIDE {
- return false;
- }
- virtual bool PreHandleMouseEvent(Window* target, MouseEvent* event) OVERRIDE {
- switch (event->type()) {
- case ui::ET_MOUSE_PRESSED:
- ActivateIfNecessary(target, event);
- break;
- case ui::ET_MOUSE_MOVED:
- HandleMouseMoved(target, event);
- break;
- default:
- break;
- }
- return false;
- }
- virtual ui::TouchStatus PreHandleTouchEvent(Window* target,
- TouchEvent* event) OVERRIDE {
- if (event->type() == ui::ET_TOUCH_PRESSED)
- ActivateIfNecessary(target, event);
- return ui::TOUCH_STATUS_UNKNOWN;
- }
-
- private:
- // If necessary, activates |window| and changes focus.
- void ActivateIfNecessary(Window* window, Event* event) {
- // TODO(beng): some windows (e.g. disabled ones, tooltips, etc) may not be
- // focusable.
-
- Window* active_window = Desktop::GetInstance()->active_window();
- Window* toplevel_window = window;
- while (toplevel_window && toplevel_window != active_window &&
- toplevel_window->parent() &&
- !toplevel_window->parent()->AsToplevelWindowContainer()) {
- toplevel_window = toplevel_window->parent();
- }
- if (toplevel_window == active_window) {
- // |window| is a descendant of the active window, no need to activate.
- window->GetFocusManager()->SetFocusedWindow(window);
- return;
- }
- if (!toplevel_window) {
- // |window| is not in a top level window.
- return;
- }
- if (!toplevel_window->delegate() ||
- !toplevel_window->delegate()->ShouldActivate(event))
- return;
-
- Desktop::GetInstance()->SetActiveWindow(toplevel_window, window);
- }
-
- // Updates the cursor if the target provides a custom one, and provides
- // default resize cursors for window edges.
- void HandleMouseMoved(Window* target, MouseEvent* event) {
- gfx::NativeCursor cursor = target->GetCursor(event->location());
- if (event->flags() & ui::EF_IS_NON_CLIENT) {
- int window_component =
- target->delegate()->GetNonClientComponent(event->location());
- cursor = CursorForWindowComponent(window_component);
- }
- Desktop::GetInstance()->SetCursor(cursor);
- }
-
- DISALLOW_COPY_AND_ASSIGN(DesktopEventFilter);
-};
-
typedef std::vector<EventFilter*> EventFilters;
void GetEventFiltersToNotify(Window* target, EventFilters* filters) {
@@ -255,7 +161,6 @@ Desktop::Desktop()
gfx::Screen::SetInstance(screen_);
host_->SetDesktop(this);
last_mouse_location_ = host_->QueryMouseLocation();
- SetEventFilter(new DesktopEventFilter(this));
if (ui::Compositor::compositor_factory()) {
compositor_ = (*ui::Compositor::compositor_factory())(this);
@@ -406,14 +311,17 @@ void Desktop::OnHostResized(const gfx::Size& size) {
}
void Desktop::SetActiveWindow(Window* window, Window* to_focus) {
- // We only allow top level windows to be active.
- if (window && window != window->GetToplevelWindow()) {
- // Ignore requests to activate windows that aren't in a top level window.
+ // The stacking client may impose rules on what window configurations can be
+ // activated or deactivated.
+ if (window && !stacking_client_->CanActivateWindow(window))
return;
- }
-
+ // The window may not be activate-able.
+ if (window && !window->CanActivate())
+ return;
+ // Nothing may actually have changed.
if (active_window_ == window)
return;
+
Window* old_active = active_window_;
active_window_ = window;
// Invoke OnLostActive after we've changed the active window. That way if the
@@ -437,18 +345,14 @@ void Desktop::ActivateTopmostWindow() {
}
void Desktop::Deactivate(Window* window) {
- if (!window)
+ // The stacking client may impose rules on what window configurations can be
+ // activated or deactivated.
+ if (!window || !stacking_client_->CanActivateWindow(window))
+ return;
+ if (active_window_ != window)
return;
- Window* toplevel_ancestor = window->GetToplevelWindow();
- if (!toplevel_ancestor || toplevel_ancestor != window)
- return; // Not a top level window.
-
- if (active_window() != toplevel_ancestor)
- return; // Top level ancestor is already not active.
-
- Window* to_activate =
- stacking_client_->GetTopmostWindowToActivate(toplevel_ancestor);
+ Window* to_activate = stacking_client_->GetTopmostWindowToActivate(window);
if (to_activate)
SetActiveWindow(to_activate, NULL);
}
diff --git a/ui/aura/desktop.h b/ui/aura/desktop.h
index 6089331..5f455ff 100644
--- a/ui/aura/desktop.h
+++ b/ui/aura/desktop.h
@@ -97,6 +97,7 @@ class AURA_EXPORT Desktop : public ui::CompositorDelegate,
// Sets the active window to |window| and the focused window to |to_focus|.
// If |to_focus| is NULL, |window| is focused.
+ // |window| can be NULL.
void SetActiveWindow(Window* window, Window* to_focus);
// Activates the topmost window. Does nothing if the topmost window is already
diff --git a/ui/aura/desktop_unittest.cc b/ui/aura/desktop_unittest.cc
deleted file mode 100644
index d6ac2ed..0000000
--- a/ui/aura/desktop_unittest.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// 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/desktop.h"
-
-#include "ui/aura/event.h"
-#include "ui/aura/test/aura_test_base.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/base/events.h"
-#include "ui/base/hit_test.h"
-#include "ui/gfx/point.h"
-
-namespace aura {
-namespace test {
-
-namespace {
-
-Window* CreateTestWindowWithDelegate(WindowDelegate* delegate,
- const gfx::Rect& bounds,
- Window* parent) {
- Window* window = new Window(delegate);
- window->Init(ui::Layer::LAYER_HAS_TEXTURE);
- window->SetBounds(bounds);
- window->Show();
- window->SetParent(parent);
- return window;
-}
-
-class HitTestWindowDelegate : public TestWindowDelegate {
- public:
- HitTestWindowDelegate()
- : hittest_code_(HTNOWHERE) {
- }
- virtual ~HitTestWindowDelegate() {}
- void set_hittest_code(int hittest_code) { hittest_code_ = hittest_code; }
-
- private:
- // Overridden from TestWindowDelegate:
- virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
- return hittest_code_;
- }
-
- int hittest_code_;
-
- DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate);
-};
-
-} // namespace
-
-class DesktopTest : public AuraTestBase {
- public:
- DesktopTest() {}
- virtual ~DesktopTest() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DesktopTest);
-};
-
-TEST_F(DesktopTest, MouseEventCursors) {
- Desktop* desktop = Desktop::GetInstance();
-
- // Create a window.
- const int kWindowLeft = 123;
- const int kWindowTop = 45;
- HitTestWindowDelegate window_delegate;
- scoped_ptr<Window> window(CreateTestWindowWithDelegate(
- &window_delegate,
- gfx::Rect(kWindowLeft, kWindowTop, 640, 480),
- NULL));
-
- // Create two mouse movement events we can switch between.
- gfx::Point point1(kWindowLeft, kWindowTop);
- Window::ConvertPointToWindow(window->parent(), desktop, &point1);
- MouseEvent move1(ui::ET_MOUSE_MOVED, point1, 0x0);
-
- gfx::Point point2(kWindowLeft + 1, kWindowTop + 1);
- Window::ConvertPointToWindow(window->parent(), desktop, &point2);
- MouseEvent move2(ui::ET_MOUSE_MOVED, point2, 0x0);
-
- // Cursor starts as null.
- EXPECT_EQ(kCursorNull, desktop->last_cursor());
-
- // Resize edges and corners show proper cursors.
- window_delegate.set_hittest_code(HTBOTTOM);
- desktop->DispatchMouseEvent(&move1);
- EXPECT_EQ(kCursorSouthResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTBOTTOMLEFT);
- desktop->DispatchMouseEvent(&move2);
- EXPECT_EQ(kCursorSouthWestResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTBOTTOMRIGHT);
- desktop->DispatchMouseEvent(&move1);
- EXPECT_EQ(kCursorSouthEastResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTLEFT);
- desktop->DispatchMouseEvent(&move2);
- EXPECT_EQ(kCursorWestResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTRIGHT);
- desktop->DispatchMouseEvent(&move1);
- EXPECT_EQ(kCursorEastResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTTOP);
- desktop->DispatchMouseEvent(&move2);
- EXPECT_EQ(kCursorNorthResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTTOPLEFT);
- desktop->DispatchMouseEvent(&move1);
- EXPECT_EQ(kCursorNorthWestResize, desktop->last_cursor());
-
- window_delegate.set_hittest_code(HTTOPRIGHT);
- desktop->DispatchMouseEvent(&move2);
- EXPECT_EQ(kCursorNorthEastResize, desktop->last_cursor());
-
- // Client area uses null cursor.
- window_delegate.set_hittest_code(HTCLIENT);
- desktop->DispatchMouseEvent(&move1);
- EXPECT_EQ(kCursorNull, desktop->last_cursor());
-}
-
-} // namespace test
-} // namespace aura
diff --git a/ui/aura/test/test_stacking_client.cc b/ui/aura/test/test_stacking_client.cc
index 37ce262..3191a84 100644
--- a/ui/aura/test/test_stacking_client.cc
+++ b/ui/aura/test/test_stacking_client.cc
@@ -10,7 +10,7 @@ namespace aura {
namespace test {
TestStackingClient::TestStackingClient()
- : default_container_(new ToplevelWindowContainer) {
+ : default_container_(new Window(NULL)) {
Desktop::GetInstance()->SetStackingClient(this);
default_container_->Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
default_container_->SetBounds(
@@ -26,8 +26,19 @@ void TestStackingClient::AddChildToDefaultParent(Window* window) {
default_container_->AddChild(window);
}
+bool TestStackingClient::CanActivateWindow(Window* window) const {
+ return window->parent() == default_container_;
+}
+
Window* TestStackingClient::GetTopmostWindowToActivate(Window* ignore) const {
- return default_container_->GetTopmostWindowToActivate(ignore);
+ for (aura::Window::Windows::const_reverse_iterator i =
+ default_container_->children().rbegin();
+ i != default_container_->children().rend();
+ ++i) {
+ if (*i != ignore && (*i)->CanActivate())
+ return *i;
+ }
+ return NULL;
}
} // namespace test
diff --git a/ui/aura/test/test_stacking_client.h b/ui/aura/test/test_stacking_client.h
index bf77ff8..3ea0ba5 100644
--- a/ui/aura/test/test_stacking_client.h
+++ b/ui/aura/test/test_stacking_client.h
@@ -10,10 +10,9 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/client/stacking_client.h"
-#include "ui/aura/toplevel_window_container.h"
namespace aura {
-class ToplevelWindowContainer;
+class Window;
namespace test {
@@ -30,9 +29,10 @@ class TestStackingClient : public StackingClient {
private:
// Overridden from StackingClient:
virtual void AddChildToDefaultParent(Window* window) OVERRIDE;
+ virtual bool CanActivateWindow(Window* window) const OVERRIDE;
virtual Window* GetTopmostWindowToActivate(Window* ignore) const OVERRIDE;
- scoped_ptr<ToplevelWindowContainer> default_container_;
+ scoped_ptr<Window> default_container_;
DISALLOW_COPY_AND_ASSIGN(TestStackingClient);
};
diff --git a/ui/aura/test/test_window_delegate.cc b/ui/aura/test/test_window_delegate.cc
index 8957eba..b179fda 100644
--- a/ui/aura/test/test_window_delegate.cc
+++ b/ui/aura/test/test_window_delegate.cc
@@ -4,11 +4,18 @@
#include "ui/aura/test/test_window_delegate.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "ui/aura/event.h"
+#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
+#include "ui/gfx/canvas.h"
namespace aura {
namespace test {
+////////////////////////////////////////////////////////////////////////////////
+// TestWindowDelegate
+
TestWindowDelegate::TestWindowDelegate() {
}
@@ -70,5 +77,55 @@ void TestWindowDelegate::OnWindowDestroyed() {
void TestWindowDelegate::OnWindowVisibilityChanged(bool visible) {
}
+
+////////////////////////////////////////////////////////////////////////////////
+// ColorTestWindowDelegate
+
+ColorTestWindowDelegate::ColorTestWindowDelegate(SkColor color)
+ : color_(color),
+ last_key_code_(ui::VKEY_UNKNOWN) {
+}
+ColorTestWindowDelegate::~ColorTestWindowDelegate() {
+}
+
+bool ColorTestWindowDelegate::OnKeyEvent(KeyEvent* event) {
+ last_key_code_ = event->key_code();
+ return true;
+}
+void ColorTestWindowDelegate::OnWindowDestroyed() {
+ delete this;
+}
+void ColorTestWindowDelegate::OnPaint(gfx::Canvas* canvas) {
+ canvas->GetSkCanvas()->drawColor(color_, SkXfermode::kSrc_Mode);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ActivateWindowDelegate
+
+ActivateWindowDelegate::ActivateWindowDelegate()
+ : activate_(true),
+ activated_count_(0),
+ lost_active_count_(0),
+ should_activate_count_(0) {
+}
+
+ActivateWindowDelegate::ActivateWindowDelegate(bool activate)
+ : activate_(activate),
+ activated_count_(0),
+ lost_active_count_(0),
+ should_activate_count_(0) {
+}
+
+bool ActivateWindowDelegate::ShouldActivate(Event* event) {
+ should_activate_count_++;
+ return activate_;
+}
+void ActivateWindowDelegate::OnActivated() {
+ activated_count_++;
+}
+void ActivateWindowDelegate::OnLostActive() {
+ lost_active_count_++;
+}
+
} // namespace test
} // namespace aura
diff --git a/ui/aura/test/test_window_delegate.h b/ui/aura/test/test_window_delegate.h
index 4150f67..783402b 100644
--- a/ui/aura/test/test_window_delegate.h
+++ b/ui/aura/test/test_window_delegate.h
@@ -7,6 +7,7 @@
#pragma once
#include "base/compiler_specific.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/window_delegate.h"
namespace aura {
@@ -41,6 +42,54 @@ class TestWindowDelegate : public WindowDelegate {
DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
};
+// A simple WindowDelegate implementation for these tests. It owns itself
+// (deletes itself when the Window it is attached to is destroyed).
+class ColorTestWindowDelegate : public TestWindowDelegate {
+ public:
+ explicit ColorTestWindowDelegate(SkColor color);
+ virtual ~ColorTestWindowDelegate();
+
+ ui::KeyboardCode last_key_code() const { return last_key_code_; }
+
+ // Overridden from TestWindowDelegate:
+ virtual bool OnKeyEvent(KeyEvent* event) OVERRIDE;
+ virtual void OnWindowDestroyed() OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+
+ private:
+ SkColor color_;
+ ui::KeyboardCode last_key_code_;
+
+ DISALLOW_COPY_AND_ASSIGN(ColorTestWindowDelegate);
+};
+
+class ActivateWindowDelegate : public TestWindowDelegate {
+ public:
+ ActivateWindowDelegate();
+ explicit ActivateWindowDelegate(bool activate);
+
+ void set_activate(bool v) { activate_ = v; }
+ int activated_count() const { return activated_count_; }
+ int lost_active_count() const { return lost_active_count_; }
+ int should_activate_count() const { return should_activate_count_; }
+ void Clear() {
+ activated_count_ = lost_active_count_ = should_activate_count_ = 0;
+ }
+
+ // Overridden from TestWindowDelegate:
+ virtual bool ShouldActivate(Event* event) OVERRIDE;
+ virtual void OnActivated() OVERRIDE;
+ virtual void OnLostActive() OVERRIDE;
+
+ private:
+ bool activate_;
+ int activated_count_;
+ int lost_active_count_;
+ int should_activate_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(ActivateWindowDelegate);
+};
+
} // namespace test
} // namespace aura
diff --git a/ui/aura/test/test_windows.cc b/ui/aura/test/test_windows.cc
new file mode 100644
index 0000000..5fe85f4
--- /dev/null
+++ b/ui/aura/test/test_windows.cc
@@ -0,0 +1,45 @@
+// 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/test/test_windows.h"
+
+#include "ui/aura/window.h"
+#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/rect.h"
+
+namespace aura {
+namespace test {
+
+Window* CreateTestWindowWithId(int id, Window* parent) {
+ return CreateTestWindowWithDelegate(NULL, id, gfx::Rect(), parent);
+}
+
+Window* CreateTestWindowWithBounds(const gfx::Rect& bounds, Window* parent) {
+ return CreateTestWindowWithDelegate(NULL, 0, bounds, parent);
+}
+
+Window* CreateTestWindow(SkColor color,
+ int id,
+ const gfx::Rect& bounds,
+ Window* parent) {
+ return CreateTestWindowWithDelegate(new ColorTestWindowDelegate(color),
+ id, bounds, parent);
+}
+
+Window* CreateTestWindowWithDelegate(WindowDelegate* delegate,
+ int id,
+ const gfx::Rect& bounds,
+ Window* parent) {
+ Window* window = new Window(delegate);
+ window->set_id(id);
+ window->SetType(aura::WINDOW_TYPE_NORMAL);
+ window->Init(ui::Layer::LAYER_HAS_TEXTURE);
+ window->SetBounds(bounds);
+ window->Show();
+ window->SetParent(parent);
+ return window;
+}
+
+} // namespace test
+} // namespace aura
diff --git a/ui/aura/test/test_windows.h b/ui/aura/test/test_windows.h
new file mode 100644
index 0000000..2edf133
--- /dev/null
+++ b/ui/aura/test/test_windows.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef UI_AURA_TEST_TEST_UTILS_H_
+#define UI_AURA_TEST_TEST_UTILS_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/test/aura_test_base.h"
+
+namespace gfx {
+class Canvas;
+}
+
+namespace aura {
+namespace test {
+
+Window* CreateTestWindowWithId(int id, Window* parent);
+Window* CreateTestWindowWithBounds(const gfx::Rect& bounds, Window* parent);
+Window* CreateTestWindow(SkColor color,
+ int id,
+ const gfx::Rect& bounds,
+ Window* parent);
+Window* CreateTestWindowWithDelegate(WindowDelegate* delegate,
+ int id,
+ const gfx::Rect& bounds,
+ Window* parent);
+
+} // namespace test
+} // namespace aura
+
+#endif // UI_AURA_TEST_TEST_UTILS_H_
diff --git a/ui/aura/toplevel_window_container.cc b/ui/aura/toplevel_window_container.cc
deleted file mode 100644
index 9605d88..0000000
--- a/ui/aura/toplevel_window_container.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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/toplevel_window_container.h"
-
-#include "base/utf_string_conversions.h"
-
-namespace aura {
-
-ToplevelWindowContainer::ToplevelWindowContainer()
- : Window(NULL) {
- set_name("ToplevelWindowContainer");
-}
-
-ToplevelWindowContainer::~ToplevelWindowContainer() {
-}
-
-Window* ToplevelWindowContainer::GetTopmostWindowToActivate(
- Window* ignore) const {
- for (Window::Windows::const_reverse_iterator i = children().rbegin();
- i != children().rend(); ++i) {
- if (*i != ignore && (*i)->CanActivate())
- return *i;
- }
- return NULL;
-}
-
-ToplevelWindowContainer* ToplevelWindowContainer::AsToplevelWindowContainer() {
- return this;
-}
-
-const ToplevelWindowContainer*
- ToplevelWindowContainer::AsToplevelWindowContainer() const {
- return this;
-}
-} // namespace aura
diff --git a/ui/aura/toplevel_window_container.h b/ui/aura/toplevel_window_container.h
deleted file mode 100644
index 67c537a..0000000
--- a/ui/aura/toplevel_window_container.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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.
-
-#ifndef UI_AURA_TOPLEVEL_WINDOW_CONTAINER_H_
-#define UI_AURA_TOPLEVEL_WINDOW_CONTAINER_H_
-#pragma once
-
-#include "ui/aura/window.h"
-#include "ui/aura/aura_export.h"
-
-namespace aura {
-
-// A Window subclass that groups top-level windows.
-class AURA_EXPORT ToplevelWindowContainer : public Window {
- public:
- ToplevelWindowContainer();
- virtual ~ToplevelWindowContainer();
-
- // Returns the topmost window to activate, ignoring |ignore|.
- Window* GetTopmostWindowToActivate(Window* ignore) const;
-
- // Overridden from Window:
- virtual ToplevelWindowContainer* AsToplevelWindowContainer() OVERRIDE;
- virtual const ToplevelWindowContainer*
- AsToplevelWindowContainer() const OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ToplevelWindowContainer);
-};
-
-} // namespace aura
-
-#endif // UI_AURA_TOPLEVEL_WINDOW_CONTAINER_H_
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 49be6e9..d1caa04 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -120,14 +120,6 @@ bool Window::IsActive() const {
return aura::Desktop::GetInstance()->active_window() == this;
}
-ToplevelWindowContainer* Window::AsToplevelWindowContainer() {
- return NULL;
-}
-
-const ToplevelWindowContainer* Window::AsToplevelWindowContainer() const {
- return NULL;
-}
-
void Window::SetTransform(const ui::Transform& transform) {
layer()->SetTransform(transform);
}
@@ -213,7 +205,7 @@ void Window::MoveChildAbove(Window* child, Window* other) {
}
bool Window::CanActivate() const {
- return IsVisible() && delegate_ && delegate_->ShouldActivate(NULL);
+ return IsVisible() && (!delegate_ || delegate_->ShouldActivate(NULL));
}
void Window::AddChild(Window* child) {
@@ -387,14 +379,6 @@ bool Window::HasCapture() {
return desktop && desktop->capture_window() == this;
}
-Window* Window::GetToplevelWindow() {
- Window* window = this;
- while (window && window->parent() &&
- !window->parent()->AsToplevelWindowContainer())
- window = window->parent();
- return window && window->parent() ? window : NULL;
-}
-
void Window::SetProperty(const char* name, void* value) {
void* old = GetProperty(name);
if (value)
diff --git a/ui/aura/window.h b/ui/aura/window.h
index f66c04b..485bcb4 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -110,11 +110,6 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Returns true if this window is active.
bool IsActive() const;
- // RTTI to a container for top-level windows. Returns NULL if this window is
- // not a top level window container.
- virtual ToplevelWindowContainer* AsToplevelWindowContainer();
- virtual const ToplevelWindowContainer* AsToplevelWindowContainer() const;
-
virtual void SetTransform(const ui::Transform& transform);
// Assigns a LayoutManager to size and place child windows.
@@ -256,10 +251,6 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Returns true if this window has a mouse capture.
bool HasCapture();
- // Returns the first ancestor whose parent window returns true from
- // IsToplevelWindowContainer.
- Window* GetToplevelWindow();
-
// Sets the window property |value| for given |name|. Setting NULL or 0
// removes the property. It uses |ui::ViewProp| to store the property.
// Please see the description of |prop_map_| for more details.
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index cd2d964c..e41a391 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -8,14 +8,15 @@
#include "base/compiler_specific.h"
#include "base/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/client/stacking_client.h"
#include "ui/aura/desktop.h"
#include "ui/aura/desktop_observer.h"
#include "ui/aura/event.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_windows.h"
#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/toplevel_window_container.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_observer.h"
#include "ui/base/hit_test.h"
@@ -27,6 +28,8 @@
namespace aura {
namespace test {
+typedef AuraTestBase WindowTest;
+
namespace {
// Used for verifying destruction methods are invoked.
@@ -121,75 +124,6 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
DISALLOW_COPY_AND_ASSIGN(CaptureWindowDelegateImpl);
};
-// A simple WindowDelegate implementation for these tests. It owns itself
-// (deletes itself when the Window it is attached to is destroyed).
-class ColorTestWindowDelegate : public TestWindowDelegate {
- public:
- ColorTestWindowDelegate(SkColor color)
- : color_(color),
- last_key_code_(ui::VKEY_UNKNOWN) {
- }
- virtual ~ColorTestWindowDelegate() {}
-
- ui::KeyboardCode last_key_code() const { return last_key_code_; }
-
- // Overridden from TestWindowDelegate:
- virtual bool OnKeyEvent(KeyEvent* event) OVERRIDE {
- last_key_code_ = event->key_code();
- return true;
- }
- virtual void OnWindowDestroyed() OVERRIDE {
- delete this;
- }
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- canvas->GetSkCanvas()->drawColor(color_, SkXfermode::kSrc_Mode);
- }
-
- private:
- SkColor color_;
- ui::KeyboardCode last_key_code_;
-
- DISALLOW_COPY_AND_ASSIGN(ColorTestWindowDelegate);
-};
-
-class WindowTest : public AuraTestBase {
- public:
- WindowTest() {}
- virtual ~WindowTest() {}
-
- Window* CreateTestWindowWithId(int id, Window* parent) {
- return CreateTestWindowWithDelegate(NULL, id, gfx::Rect(), parent);
- }
-
- Window* CreateTestWindowWithBounds(const gfx::Rect& bounds, Window* parent) {
- return CreateTestWindowWithDelegate(NULL, 0, bounds, parent);
- }
-
- Window* CreateTestWindow(SkColor color,
- int id,
- const gfx::Rect& bounds,
- Window* parent) {
- return CreateTestWindowWithDelegate(new ColorTestWindowDelegate(color),
- id, bounds, parent);
- }
-
- Window* CreateTestWindowWithDelegate(WindowDelegate* delegate,
- int id,
- const gfx::Rect& bounds,
- Window* parent) {
- Window* window = new Window(delegate);
- window->set_id(id);
- window->Init(ui::Layer::LAYER_HAS_TEXTURE);
- window->SetBounds(bounds);
- window->Show();
- window->SetParent(parent);
- return window;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WindowTest);
-};
-
} // namespace
TEST_F(WindowTest, GetChildById) {
@@ -294,66 +228,6 @@ TEST_F(WindowTest, GetTopWindowContainingPoint) {
EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(260, 260)));
}
-TEST_F(WindowTest, Focus) {
- Desktop* desktop = Desktop::GetInstance();
- desktop->SetBounds(gfx::Rect(0, 0, 510, 510));
-
- scoped_ptr<Window> w1(
- CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), NULL));
- scoped_ptr<Window> w11(
- CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
- scoped_ptr<Window> w111(
- CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
- scoped_ptr<Window> w1111(
- CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
- scoped_ptr<Window> w12(
- CreateTestWindow(SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25),
- w1.get()));
- ColorTestWindowDelegate* w121delegate =
- new ColorTestWindowDelegate(SK_ColorYELLOW);
- scoped_ptr<Window> w121(
- CreateTestWindowWithDelegate(w121delegate, 121, gfx::Rect(5, 5, 5, 5),
- w12.get()));
- ColorTestWindowDelegate* w122delegate =
- new ColorTestWindowDelegate(SK_ColorRED);
- scoped_ptr<Window> w122(
- CreateTestWindowWithDelegate(w122delegate, 121, gfx::Rect(10, 5, 5, 5),
- w12.get()));
- scoped_ptr<Window> w13(
- CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get()));
-
- // Click on a sub-window (w121) to focus it.
- gfx::Point click_point = w121->bounds().CenterPoint();
- Window::ConvertPointToWindow(w121->parent(), desktop, &click_point);
- MouseEvent mouse(ui::ET_MOUSE_PRESSED, click_point, ui::EF_LEFT_BUTTON_DOWN);
- desktop->DispatchMouseEvent(&mouse);
- internal::FocusManager* focus_manager = w121->GetFocusManager();
- EXPECT_EQ(w121.get(), focus_manager->GetFocusedWindow());
-
- // The key press should be sent to the focused sub-window.
- KeyEvent keyev(ui::ET_KEY_PRESSED, ui::VKEY_E, 0);
- desktop->DispatchKeyEvent(&keyev);
- EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code());
-
- // Touch on a sub-window (w122) to focus it.
- click_point = w122->bounds().CenterPoint();
- Window::ConvertPointToWindow(w122->parent(), desktop, &click_point);
- TouchEvent touchev(ui::ET_TOUCH_PRESSED, click_point, 0);
- desktop->DispatchTouchEvent(&touchev);
- focus_manager = w122->GetFocusManager();
- EXPECT_EQ(w122.get(), focus_manager->GetFocusedWindow());
-
- // The key press should be sent to the focused sub-window.
- desktop->DispatchKeyEvent(&keyev);
- EXPECT_EQ(ui::VKEY_E, w122delegate->last_key_code());
-
- // Removing the focused window from parent should reset the focused window.
- w12->RemoveChild(w122.get());
- EXPECT_EQ(NULL, w122->GetFocusManager());
- EXPECT_EQ(NULL, w12->GetFocusManager()->GetFocusedWindow());
- EXPECT_FALSE(desktop->DispatchKeyEvent(&keyev));
-}
-
// Various destruction assertions.
TEST_F(WindowTest, DestroyTest) {
DestroyTrackingDelegateImpl parent_delegate;
@@ -589,183 +463,6 @@ TEST_F(WindowTest, MouseEnterExit) {
EXPECT_FALSE(d2.exited());
}
-class ActivateWindowDelegate : public TestWindowDelegate {
- public:
- ActivateWindowDelegate()
- : activate_(true),
- activated_count_(0),
- lost_active_count_(0),
- should_activate_count_(0) {
- }
-
- ActivateWindowDelegate(bool activate)
- : activate_(activate),
- activated_count_(0),
- lost_active_count_(0),
- should_activate_count_(0) {
- }
-
- void set_activate(bool v) { activate_ = v; }
- int activated_count() const { return activated_count_; }
- int lost_active_count() const { return lost_active_count_; }
- int should_activate_count() const { return should_activate_count_; }
- void Clear() {
- activated_count_ = lost_active_count_ = should_activate_count_ = 0;
- }
-
- virtual bool ShouldActivate(Event* event) OVERRIDE {
- should_activate_count_++;
- return activate_;
- }
- virtual void OnActivated() OVERRIDE {
- activated_count_++;
- }
- virtual void OnLostActive() OVERRIDE {
- lost_active_count_++;
- }
-
- private:
- bool activate_;
- int activated_count_;
- int lost_active_count_;
- int should_activate_count_;
-
- DISALLOW_COPY_AND_ASSIGN(ActivateWindowDelegate);
-};
-
-// Various assertion testing for activating windows.
-TEST_F(WindowTest, ActivateOnMouse) {
- Desktop* desktop = Desktop::GetInstance();
-
- ActivateWindowDelegate d1;
- scoped_ptr<Window> w1(
- CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50), NULL));
- ActivateWindowDelegate d2;
- scoped_ptr<Window> w2(
- CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50), NULL));
- internal::FocusManager* focus_manager = w1->GetFocusManager();
-
- d1.Clear();
- d2.Clear();
-
- // Activate window1.
- desktop->SetActiveWindow(w1.get(), NULL);
- EXPECT_EQ(w1.get(), desktop->active_window());
- EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(1, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
- d1.Clear();
-
- // Click on window2.
- gfx::Point press_point = w2->bounds().CenterPoint();
- Window::ConvertPointToWindow(w2->parent(), desktop, &press_point);
- EventGenerator generator(press_point);
- generator.ClickLeftButton();
-
- // Window2 should have become active.
- EXPECT_EQ(w2.get(), desktop->active_window());
- EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(0, d1.activated_count());
- EXPECT_EQ(1, d1.lost_active_count());
- EXPECT_EQ(1, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- d1.Clear();
- d2.Clear();
-
- // Click back on window1, but set it up so w1 doesn't activate on click.
- press_point = w1->bounds().CenterPoint();
- Window::ConvertPointToWindow(w1->parent(), desktop, &press_point);
- d1.set_activate(false);
- generator.ClickLeftButton();
-
- // Window2 should still be active and focused.
- EXPECT_EQ(w2.get(), desktop->active_window());
- EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(0, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
- EXPECT_EQ(0, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- d1.Clear();
- d2.Clear();
-
- // Destroy window2, this should make window1 active.
- d1.set_activate(true);
- w2.reset();
- EXPECT_EQ(0, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- EXPECT_EQ(w1.get(), desktop->active_window());
- EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(1, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
-}
-
-// Essentially the same as ActivateOnMouse, but for touch events.
-TEST_F(WindowTest, ActivateOnTouch) {
- Desktop* desktop = Desktop::GetInstance();
-
- ActivateWindowDelegate d1;
- scoped_ptr<Window> w1(
- CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50), NULL));
- ActivateWindowDelegate d2;
- scoped_ptr<Window> w2(
- CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50), NULL));
- internal::FocusManager* focus_manager = w1->GetFocusManager();
-
- d1.Clear();
- d2.Clear();
-
- // Activate window1.
- desktop->SetActiveWindow(w1.get(), NULL);
- EXPECT_EQ(w1.get(), desktop->active_window());
- EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(1, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
- d1.Clear();
-
- // Touch window2.
- gfx::Point press_point = w2->bounds().CenterPoint();
- Window::ConvertPointToWindow(w2->parent(), desktop, &press_point);
- TouchEvent touchev1(ui::ET_TOUCH_PRESSED, press_point, 0);
- desktop->DispatchTouchEvent(&touchev1);
-
- // Window2 should have become active.
- EXPECT_EQ(w2.get(), desktop->active_window());
- EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(0, d1.activated_count());
- EXPECT_EQ(1, d1.lost_active_count());
- EXPECT_EQ(1, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- d1.Clear();
- d2.Clear();
-
- // Touch window1, but set it up so w1 doesn't activate on touch.
- press_point = w1->bounds().CenterPoint();
- Window::ConvertPointToWindow(w1->parent(), desktop, &press_point);
- d1.set_activate(false);
- TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 0);
- desktop->DispatchTouchEvent(&touchev2);
-
- // Window2 should still be active and focused.
- EXPECT_EQ(w2.get(), desktop->active_window());
- EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(0, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
- EXPECT_EQ(0, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- d1.Clear();
- d2.Clear();
-
- // Destroy window2, this should make window1 active.
- d1.set_activate(true);
- w2.reset();
- EXPECT_EQ(0, d2.activated_count());
- EXPECT_EQ(0, d2.lost_active_count());
- EXPECT_EQ(w1.get(), desktop->active_window());
- EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
- EXPECT_EQ(1, d1.activated_count());
- EXPECT_EQ(0, d1.lost_active_count());
-}
-
namespace {
class ActiveWindowDelegate : public TestWindowDelegate {
@@ -1074,48 +771,6 @@ TEST_F(WindowTest, TransientChildren) {
EXPECT_EQ(w1.get(), parent->children()[1]);
}
-class ToplevelWindowTest : public WindowTest {
- public:
- ToplevelWindowTest() {}
- virtual ~ToplevelWindowTest() {}
-
- virtual void SetUp() OVERRIDE {
- WindowTest::SetUp();
- toplevel_container_.Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
- toplevel_container_.SetParent(aura::Desktop::GetInstance());
- toplevel_container_.SetBounds(
- aura::Desktop::GetInstance()->bounds());
- toplevel_container_.Show();
- }
-
- virtual void TearDown() OVERRIDE {
- toplevel_container_.Hide();
- toplevel_container_.SetParent(NULL);
- WindowTest::TearDown();
- }
-
- Window* CreateTestToplevelWindow(
- WindowDelegate* delegate, const gfx::Rect& bounds) {
- return CreateTestWindowWithDelegate(
- delegate, 0 /* id */, bounds, &toplevel_container_);
- }
-
- ToplevelWindowContainer toplevel_container_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ToplevelWindowTest);
-};
-
-TEST_F(ToplevelWindowTest, TopMostActivate) {
- ActivateWindowDelegate activate;
- ActivateWindowDelegate non_activate(false);
-
- scoped_ptr<Window> w1(CreateTestToplevelWindow(&non_activate, gfx::Rect()));
- scoped_ptr<Window> w2(CreateTestToplevelWindow(&activate, gfx::Rect()));
- scoped_ptr<Window> w3(CreateTestToplevelWindow(&non_activate, gfx::Rect()));
- EXPECT_EQ(w2.get(), toplevel_container_.GetTopmostWindowToActivate(NULL));
-}
-
TEST_F(WindowTest, Property) {
scoped_ptr<Window> w(CreateTestWindowWithId(0, NULL));
const char* key = "test";
diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp
index dd946b9..9a9fb01 100644
--- a/ui/aura_shell/aura_shell.gyp
+++ b/ui/aura_shell/aura_shell.gyp
@@ -39,6 +39,8 @@
'default_container_layout_manager.h',
'desktop_background_view.cc',
'desktop_background_view.h',
+ 'desktop_event_filter.cc',
+ 'desktop_event_filter.h',
'desktop_layout_manager.cc',
'desktop_layout_manager.h',
'launcher/app_launcher_button.cc',
@@ -68,6 +70,8 @@
'shell_window_ids.h',
'show_state_controller.h',
'show_state_controller.cc',
+ 'stacking_controller.cc',
+ 'stacking_controller.h',
'status_area_view.cc',
'status_area_view.h',
'toplevel_frame_view.cc',
@@ -112,16 +116,18 @@
],
'sources': [
'default_container_layout_manager_unittest.cc',
+ 'desktop_event_filter_unittest.cc',
'launcher/launcher_model_unittest.cc',
'launcher/view_model_unittest.cc',
'launcher/view_model_utils_unittest.cc',
+ 'run_all_unittests.cc',
+ 'stacking_controller_unittest.cc',
+ 'test_suite.cc',
+ 'test_suite.h',
'toplevel_layout_manager_unittest.cc',
'toplevel_window_event_filter_unittest.cc',
'workspace_controller_unittest.cc',
'workspace/workspace_manager_unittest.cc',
- 'run_all_unittests.cc',
- 'test_suite.cc',
- 'test_suite.h',
'<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc',
'<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc',
diff --git a/ui/aura_shell/default_container_event_filter.cc b/ui/aura_shell/default_container_event_filter.cc
index 899f46b..725beb8 100644
--- a/ui/aura_shell/default_container_event_filter.cc
+++ b/ui/aura_shell/default_container_event_filter.cc
@@ -7,6 +7,7 @@
#include "ui/aura/event.h"
#include "ui/aura/window.h"
#include "ui/aura_shell/default_container_layout_manager.h"
+#include "ui/aura_shell/stacking_controller.h"
#include "ui/aura_shell/window_frame.h"
#include "ui/base/hit_test.h"
@@ -76,7 +77,7 @@ bool DefaultContainerEventFilter::PreHandleMouseEvent(aura::Window* target,
}
break;
case ui::ET_MOUSE_ENTERED:
- UpdateHoveredWindow(target->GetToplevelWindow());
+ UpdateHoveredWindow(StackingController::GetActivatableWindow(target));
break;
case ui::ET_MOUSE_EXITED:
UpdateHoveredWindow(NULL);
diff --git a/ui/aura_shell/desktop_event_filter.cc b/ui/aura_shell/desktop_event_filter.cc
new file mode 100644
index 0000000..3d17865
--- /dev/null
+++ b/ui/aura_shell/desktop_event_filter.cc
@@ -0,0 +1,109 @@
+// 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/desktop_event_filter.h"
+
+#include "ui/aura/desktop.h"
+#include "ui/aura/event.h"
+#include "ui/aura/focus_manager.h"
+#include "ui/aura/window_delegate.h"
+#include "ui/aura_shell/shell.h"
+#include "ui/aura_shell/stacking_controller.h"
+#include "ui/base/hit_test.h"
+
+namespace aura_shell {
+namespace internal {
+
+// Returns the default cursor for a window component.
+gfx::NativeCursor CursorForWindowComponent(int window_component) {
+ switch (window_component) {
+ case HTBOTTOM:
+ return aura::kCursorSouthResize;
+ case HTBOTTOMLEFT:
+ return aura::kCursorSouthWestResize;
+ case HTBOTTOMRIGHT:
+ return aura::kCursorSouthEastResize;
+ case HTLEFT:
+ return aura::kCursorWestResize;
+ case HTRIGHT:
+ return aura::kCursorEastResize;
+ case HTTOP:
+ return aura::kCursorNorthResize;
+ case HTTOPLEFT:
+ return aura::kCursorNorthWestResize;
+ case HTTOPRIGHT:
+ return aura::kCursorNorthEastResize;
+ default:
+ return aura::kCursorNull;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopEventFilter, public:
+
+DesktopEventFilter::DesktopEventFilter()
+ : EventFilter(aura::Desktop::GetInstance()) {
+}
+
+DesktopEventFilter::~DesktopEventFilter() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopEventFilter, EventFilter implementation:
+
+bool DesktopEventFilter::PreHandleKeyEvent(aura::Window* target,
+ aura::KeyEvent* event) {
+ return false;
+}
+
+bool DesktopEventFilter::PreHandleMouseEvent(aura::Window* target,
+ aura::MouseEvent* event) {
+ switch (event->type()) {
+ case ui::ET_MOUSE_PRESSED:
+ ActivateIfNecessary(target, event);
+ break;
+ case ui::ET_MOUSE_MOVED:
+ HandleMouseMoved(target, event);
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+ui::TouchStatus DesktopEventFilter::PreHandleTouchEvent(
+ aura::Window* target,
+ aura::TouchEvent* event) {
+ if (event->type() == ui::ET_TOUCH_PRESSED)
+ ActivateIfNecessary(target, event);
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopEventFilter, private:
+
+void DesktopEventFilter::ActivateIfNecessary(aura::Window* window,
+ aura::Event* event) {
+ aura::Window* activatable = StackingController::GetActivatableWindow(window);
+ if (activatable == aura::Desktop::GetInstance()->active_window()) {
+ // |window| is a descendant of the active window, no need to activate.
+ window->GetFocusManager()->SetFocusedWindow(window);
+ } else {
+ aura::Desktop::GetInstance()->SetActiveWindow(activatable, window);
+ }
+}
+
+void DesktopEventFilter::HandleMouseMoved(aura::Window* target,
+ aura::MouseEvent* event) {
+ gfx::NativeCursor cursor = target->GetCursor(event->location());
+ if (event->flags() & ui::EF_IS_NON_CLIENT) {
+ int window_component =
+ target->delegate()->GetNonClientComponent(event->location());
+ cursor = CursorForWindowComponent(window_component);
+ }
+ aura::Desktop::GetInstance()->SetCursor(cursor);
+}
+
+} // namespace internal
+} // namespace aura_shell
diff --git a/ui/aura_shell/desktop_event_filter.h b/ui/aura_shell/desktop_event_filter.h
new file mode 100644
index 0000000..1ad0438
--- /dev/null
+++ b/ui/aura_shell/desktop_event_filter.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef UI_AURA_SHELL_DESKTOP_EVENT_FILTER_H_
+#define UI_AURA_SHELL_DESKTOP_EVENT_FILTER_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "ui/aura/event_filter.h"
+#include "ui/aura_shell/aura_shell_export.h"
+
+namespace aura_shell {
+namespace internal {
+
+class AURA_SHELL_EXPORT DesktopEventFilter : public aura::EventFilter {
+ public:
+ DesktopEventFilter();
+ virtual ~DesktopEventFilter();
+
+ // Overridden from EventFilter:
+ virtual bool PreHandleKeyEvent(aura::Window* target,
+ aura::KeyEvent* event) OVERRIDE;
+ virtual bool PreHandleMouseEvent(aura::Window* target,
+ aura::MouseEvent* event) OVERRIDE;
+ virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
+ aura::TouchEvent* event) OVERRIDE;
+
+ private:
+ // If necessary, activates |window| and changes focus.
+ void ActivateIfNecessary(aura::Window* window, aura::Event* event);
+
+ // Updates the cursor if the target provides a custom one, and provides
+ // default resize cursors for window edges.
+ void HandleMouseMoved(aura::Window* target, aura::MouseEvent* event);
+
+ DISALLOW_COPY_AND_ASSIGN(DesktopEventFilter);
+};
+
+} // namespace internal
+} // namespace aura_shell
+
+#endif // UI_AURA_SHELL_DESKTOP_EVENT_FILTER_H_
diff --git a/ui/aura_shell/desktop_event_filter_unittest.cc b/ui/aura_shell/desktop_event_filter_unittest.cc
new file mode 100644
index 0000000..05118da
--- /dev/null
+++ b/ui/aura_shell/desktop_event_filter_unittest.cc
@@ -0,0 +1,319 @@
+// 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/desktop_event_filter.h"
+
+#include "ui/aura/cursor.h"
+#include "ui/aura/desktop.h"
+#include "ui/aura/event.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/test/test_stacking_client.h"
+#include "ui/aura_shell/shell_window_ids.h"
+#include "ui/base/hit_test.h"
+
+namespace aura_shell {
+namespace test {
+
+class DefaultEventFilterTest : public aura::test::AuraTestBase {
+ public:
+ DefaultEventFilterTest() {
+ aura::Desktop::GetInstance()->SetEventFilter(
+ new internal::DesktopEventFilter);
+
+ aura::test::TestStackingClient* stacking_client =
+ static_cast<aura::test::TestStackingClient*>(
+ aura::Desktop::GetInstance()->stacking_client());
+ stacking_client->default_container()->set_id(
+ internal::kShellWindowId_DefaultContainer);
+ }
+ virtual ~DefaultEventFilterTest() {
+ aura::Desktop::GetInstance()->SetEventFilter(NULL);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultEventFilterTest);
+};
+
+class HitTestWindowDelegate : public aura::test::TestWindowDelegate {
+ public:
+ HitTestWindowDelegate()
+ : hittest_code_(HTNOWHERE) {
+ }
+ virtual ~HitTestWindowDelegate() {}
+ void set_hittest_code(int hittest_code) { hittest_code_ = hittest_code; }
+
+ private:
+ // Overridden from TestWindowDelegate:
+ virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
+ return hittest_code_;
+ }
+
+ int hittest_code_;
+
+ DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate);
+};
+
+TEST_F(DefaultEventFilterTest, Focus) {
+ aura::Desktop* desktop = aura::Desktop::GetInstance();
+ desktop->SetBounds(gfx::Rect(0, 0, 510, 510));
+
+ // Supplied ids are negative so as not to collide with shell ids.
+ // TODO(beng): maybe introduce a MAKE_SHELL_ID() macro that generates a safe
+ // id beyond shell id max?
+ scoped_ptr<aura::Window> w1(aura::test::CreateTestWindow(
+ SK_ColorWHITE, -1, gfx::Rect(10, 10, 500, 500), NULL));
+ scoped_ptr<aura::Window> w11(aura::test::CreateTestWindow(
+ SK_ColorGREEN, -11, gfx::Rect(5, 5, 100, 100), w1.get()));
+ scoped_ptr<aura::Window> w111(aura::test::CreateTestWindow(
+ SK_ColorCYAN, -111, gfx::Rect(5, 5, 75, 75), w11.get()));
+ scoped_ptr<aura::Window> w1111(aura::test::CreateTestWindow(
+ SK_ColorRED, -1111, gfx::Rect(5, 5, 50, 50), w111.get()));
+ scoped_ptr<aura::Window> w12(aura::test::CreateTestWindow(
+ SK_ColorMAGENTA, -12, gfx::Rect(10, 420, 25, 25), w1.get()));
+ aura::test::ColorTestWindowDelegate* w121delegate =
+ new aura::test::ColorTestWindowDelegate(SK_ColorYELLOW);
+ scoped_ptr<aura::Window> w121(aura::test::CreateTestWindowWithDelegate(
+ w121delegate, -121, gfx::Rect(5, 5, 5, 5), w12.get()));
+ aura::test::ColorTestWindowDelegate* w122delegate =
+ new aura::test::ColorTestWindowDelegate(SK_ColorRED);
+ scoped_ptr<aura::Window> w122(aura::test::CreateTestWindowWithDelegate(
+ w122delegate, -122, gfx::Rect(10, 5, 5, 5), w12.get()));
+ scoped_ptr<aura::Window> w13(aura::test::CreateTestWindow(
+ SK_ColorGRAY, -13, gfx::Rect(5, 470, 50, 50), w1.get()));
+
+ // Click on a sub-window (w121) to focus it.
+ gfx::Point click_point = w121->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w121->parent(), desktop, &click_point);
+ aura::MouseEvent mouse(ui::ET_MOUSE_PRESSED, click_point,
+ ui::EF_LEFT_BUTTON_DOWN);
+ desktop->DispatchMouseEvent(&mouse);
+ aura::internal::FocusManager* focus_manager = w121->GetFocusManager();
+ EXPECT_EQ(w121.get(), focus_manager->GetFocusedWindow());
+
+ // The key press should be sent to the focused sub-window.
+ aura::KeyEvent keyev(ui::ET_KEY_PRESSED, ui::VKEY_E, 0);
+ desktop->DispatchKeyEvent(&keyev);
+ EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code());
+
+ // Touch on a sub-window (w122) to focus it.
+ click_point = w122->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w122->parent(), desktop, &click_point);
+ aura::TouchEvent touchev(ui::ET_TOUCH_PRESSED, click_point, 0);
+ desktop->DispatchTouchEvent(&touchev);
+ focus_manager = w122->GetFocusManager();
+ EXPECT_EQ(w122.get(), focus_manager->GetFocusedWindow());
+
+ // The key press should be sent to the focused sub-window.
+ desktop->DispatchKeyEvent(&keyev);
+ EXPECT_EQ(ui::VKEY_E, w122delegate->last_key_code());
+
+ // Removing the focused window from parent should reset the focused window.
+ w12->RemoveChild(w122.get());
+ EXPECT_EQ(NULL, w122->GetFocusManager());
+ EXPECT_EQ(NULL, w12->GetFocusManager()->GetFocusedWindow());
+ EXPECT_FALSE(desktop->DispatchKeyEvent(&keyev));
+}
+
+// Various assertion testing for activating windows.
+TEST_F(DefaultEventFilterTest, ActivateOnMouse) {
+ aura::Desktop* desktop = aura::Desktop::GetInstance();
+
+ aura::test::ActivateWindowDelegate d1;
+ scoped_ptr<aura::Window> w1(aura::test::CreateTestWindowWithDelegate(
+ &d1, 1, gfx::Rect(10, 10, 50, 50), NULL));
+ aura::test::ActivateWindowDelegate d2;
+ scoped_ptr<aura::Window> w2(aura::test::CreateTestWindowWithDelegate(
+ &d2, 2, gfx::Rect(70, 70, 50, 50), NULL));
+ aura::internal::FocusManager* focus_manager = w1->GetFocusManager();
+
+ d1.Clear();
+ d2.Clear();
+
+ // Activate window1.
+ desktop->SetActiveWindow(w1.get(), NULL);
+ EXPECT_EQ(w1.get(), desktop->active_window());
+ EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(1, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+ d1.Clear();
+
+ // Click on window2.
+ gfx::Point press_point = w2->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w2->parent(), desktop, &press_point);
+ aura::test::EventGenerator generator(press_point);
+ generator.ClickLeftButton();
+
+ // Window2 should have become active.
+ EXPECT_EQ(w2.get(), desktop->active_window());
+ EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(0, d1.activated_count());
+ EXPECT_EQ(1, d1.lost_active_count());
+ EXPECT_EQ(1, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ d1.Clear();
+ d2.Clear();
+
+ // Click back on window1, but set it up so w1 doesn't activate on click.
+ press_point = w1->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w1->parent(), desktop, &press_point);
+ d1.set_activate(false);
+ generator.ClickLeftButton();
+
+ // Window2 should still be active and focused.
+ EXPECT_EQ(w2.get(), desktop->active_window());
+ EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(0, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+ EXPECT_EQ(0, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ d1.Clear();
+ d2.Clear();
+
+ // Destroy window2, this should make window1 active.
+ d1.set_activate(true);
+ w2.reset();
+ EXPECT_EQ(0, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ EXPECT_EQ(w1.get(), desktop->active_window());
+ EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(1, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+}
+
+// Essentially the same as ActivateOnMouse, but for touch events.
+TEST_F(DefaultEventFilterTest, ActivateOnTouch) {
+ aura::Desktop* desktop = aura::Desktop::GetInstance();
+
+ aura::test::ActivateWindowDelegate d1;
+ scoped_ptr<aura::Window> w1(aura::test::CreateTestWindowWithDelegate(
+ &d1, -1, gfx::Rect(10, 10, 50, 50), NULL));
+ aura::test::ActivateWindowDelegate d2;
+ scoped_ptr<aura::Window> w2(aura::test::CreateTestWindowWithDelegate(
+ &d2, -2, gfx::Rect(70, 70, 50, 50), NULL));
+ aura::internal::FocusManager* focus_manager = w1->GetFocusManager();
+
+ d1.Clear();
+ d2.Clear();
+
+ // Activate window1.
+ desktop->SetActiveWindow(w1.get(), NULL);
+ EXPECT_EQ(w1.get(), desktop->active_window());
+ EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(1, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+ d1.Clear();
+
+ // Touch window2.
+ gfx::Point press_point = w2->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w2->parent(), desktop, &press_point);
+ aura::TouchEvent touchev1(ui::ET_TOUCH_PRESSED, press_point, 0);
+ desktop->DispatchTouchEvent(&touchev1);
+
+ // Window2 should have become active.
+ EXPECT_EQ(w2.get(), desktop->active_window());
+ EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(0, d1.activated_count());
+ EXPECT_EQ(1, d1.lost_active_count());
+ EXPECT_EQ(1, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ d1.Clear();
+ d2.Clear();
+
+ // Touch window1, but set it up so w1 doesn't activate on touch.
+ press_point = w1->bounds().CenterPoint();
+ aura::Window::ConvertPointToWindow(w1->parent(), desktop, &press_point);
+ d1.set_activate(false);
+ aura::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 0);
+ desktop->DispatchTouchEvent(&touchev2);
+
+ // Window2 should still be active and focused.
+ EXPECT_EQ(w2.get(), desktop->active_window());
+ EXPECT_EQ(w2.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(0, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+ EXPECT_EQ(0, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ d1.Clear();
+ d2.Clear();
+
+ // Destroy window2, this should make window1 active.
+ d1.set_activate(true);
+ w2.reset();
+ EXPECT_EQ(0, d2.activated_count());
+ EXPECT_EQ(0, d2.lost_active_count());
+ EXPECT_EQ(w1.get(), desktop->active_window());
+ EXPECT_EQ(w1.get(), focus_manager->GetFocusedWindow());
+ EXPECT_EQ(1, d1.activated_count());
+ EXPECT_EQ(0, d1.lost_active_count());
+}
+
+TEST_F(DefaultEventFilterTest, MouseEventCursors) {
+ aura::Desktop* desktop = aura::Desktop::GetInstance();
+
+ // Create a window.
+ const int kWindowLeft = 123;
+ const int kWindowTop = 45;
+ HitTestWindowDelegate window_delegate;
+ scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
+ &window_delegate,
+ -1,
+ gfx::Rect(kWindowLeft, kWindowTop, 640, 480),
+ NULL));
+
+ // Create two mouse movement events we can switch between.
+ gfx::Point point1(kWindowLeft, kWindowTop);
+ aura::Window::ConvertPointToWindow(window->parent(), desktop, &point1);
+ aura::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, 0x0);
+
+ gfx::Point point2(kWindowLeft + 1, kWindowTop + 1);
+ aura::Window::ConvertPointToWindow(window->parent(), desktop, &point2);
+ aura::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, 0x0);
+
+ // Cursor starts as null.
+ EXPECT_EQ(aura::kCursorNull, desktop->last_cursor());
+
+ // Resize edges and corners show proper cursors.
+ window_delegate.set_hittest_code(HTBOTTOM);
+ desktop->DispatchMouseEvent(&move1);
+ EXPECT_EQ(aura::kCursorSouthResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTBOTTOMLEFT);
+ desktop->DispatchMouseEvent(&move2);
+ EXPECT_EQ(aura::kCursorSouthWestResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTBOTTOMRIGHT);
+ desktop->DispatchMouseEvent(&move1);
+ EXPECT_EQ(aura::kCursorSouthEastResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTLEFT);
+ desktop->DispatchMouseEvent(&move2);
+ EXPECT_EQ(aura::kCursorWestResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTRIGHT);
+ desktop->DispatchMouseEvent(&move1);
+ EXPECT_EQ(aura::kCursorEastResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTTOP);
+ desktop->DispatchMouseEvent(&move2);
+ EXPECT_EQ(aura::kCursorNorthResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTTOPLEFT);
+ desktop->DispatchMouseEvent(&move1);
+ EXPECT_EQ(aura::kCursorNorthWestResize, desktop->last_cursor());
+
+ window_delegate.set_hittest_code(HTTOPRIGHT);
+ desktop->DispatchMouseEvent(&move2);
+ EXPECT_EQ(aura::kCursorNorthEastResize, desktop->last_cursor());
+
+ // Client area uses null cursor.
+ window_delegate.set_hittest_code(HTCLIENT);
+ desktop->DispatchMouseEvent(&move1);
+ EXPECT_EQ(aura::kCursorNull, desktop->last_cursor());
+}
+
+} // namespace test
+} // namespace aura_shell
diff --git a/ui/aura_shell/launcher/launcher.cc b/ui/aura_shell/launcher/launcher.cc
index 8459656..a10e485 100644
--- a/ui/aura_shell/launcher/launcher.cc
+++ b/ui/aura_shell/launcher/launcher.cc
@@ -4,7 +4,7 @@
#include "ui/aura_shell/launcher/launcher.h"
-#include "ui/aura/toplevel_window_container.h"
+#include "ui/aura/window.h"
#include "ui/aura_shell/launcher/launcher_model.h"
#include "ui/aura_shell/launcher/launcher_view.h"
#include "ui/aura_shell/shell.h"
@@ -15,7 +15,7 @@
namespace aura_shell {
-Launcher::Launcher(aura::ToplevelWindowContainer* window_container)
+Launcher::Launcher(aura::Window* window_container)
: widget_(NULL),
window_container_(window_container) {
window_container->AddObserver(this);
diff --git a/ui/aura_shell/launcher/launcher.h b/ui/aura_shell/launcher/launcher.h
index a1c97de..ef1a2ac 100644
--- a/ui/aura_shell/launcher/launcher.h
+++ b/ui/aura_shell/launcher/launcher.h
@@ -14,7 +14,7 @@
#include "ui/aura_shell/aura_shell_export.h"
namespace aura {
-class ToplevelWindowContainer;
+class Window;
}
namespace views {
@@ -27,7 +27,7 @@ class LauncherModel;
class AURA_SHELL_EXPORT Launcher : public aura::WindowObserver {
public:
- explicit Launcher(aura::ToplevelWindowContainer* window_container);
+ explicit Launcher(aura::Window* window_container);
~Launcher();
LauncherModel* model() { return model_.get(); }
@@ -51,7 +51,7 @@ class AURA_SHELL_EXPORT Launcher : public aura::WindowObserver {
// Widget hosting the view.
views::Widget* widget_;
- aura::ToplevelWindowContainer* window_container_;
+ aura::Window* window_container_;
// The set of windows we know about. The boolean indicates whether we've asked
// the delegate if the window should added to the launcher.
diff --git a/ui/aura_shell/run_all_unittests.cc b/ui/aura_shell/run_all_unittests.cc
index 950d43b..9fa9c8a 100644
--- a/ui/aura_shell/run_all_unittests.cc
+++ b/ui/aura_shell/run_all_unittests.cc
@@ -5,5 +5,5 @@
#include "ui/aura_shell/test_suite.h"
int main(int argc, char** argv) {
- return AuraShellTestSuite(argc, argv).Run();
+ return aura_shell::test::AuraShellTestSuite(argc, argv).Run();
}
diff --git a/ui/aura_shell/shell.cc b/ui/aura_shell/shell.cc
index 58d3d78f..a9d9c81 100644
--- a/ui/aura_shell/shell.cc
+++ b/ui/aura_shell/shell.cc
@@ -8,17 +8,18 @@
#include "base/command_line.h"
#include "ui/aura/aura_switches.h"
#include "ui/aura/desktop.h"
-#include "ui/aura/toplevel_window_container.h"
#include "ui/aura/window.h"
#include "ui/aura/window_types.h"
#include "ui/aura_shell/default_container_event_filter.h"
#include "ui/aura_shell/default_container_layout_manager.h"
+#include "ui/aura_shell/desktop_event_filter.h"
#include "ui/aura_shell/desktop_layout_manager.h"
#include "ui/aura_shell/launcher/launcher.h"
#include "ui/aura_shell/shelf_layout_controller.h"
#include "ui/aura_shell/shell_delegate.h"
#include "ui/aura_shell/shell_factory.h"
#include "ui/aura_shell/shell_window_ids.h"
+#include "ui/aura_shell/stacking_controller.h"
#include "ui/aura_shell/toplevel_layout_manager.h"
#include "ui/aura_shell/toplevel_window_event_filter.h"
#include "ui/aura_shell/workspace_controller.h"
@@ -42,13 +43,13 @@ void CreateSpecialContainers(aura::Window::Windows* containers) {
internal::kShellWindowId_DesktopBackgroundContainer);
containers->push_back(background_container);
- aura::Window* default_container = new aura::ToplevelWindowContainer;
+ aura::Window* default_container = new aura::Window(NULL);
default_container->SetEventFilter(
new ToplevelWindowEventFilter(default_container));
default_container->set_id(internal::kShellWindowId_DefaultContainer);
containers->push_back(default_container);
- aura::Window* always_on_top_container = new aura::ToplevelWindowContainer;
+ aura::Window* always_on_top_container = new aura::Window(NULL);
always_on_top_container->SetEventFilter(
new ToplevelWindowEventFilter(always_on_top_container));
always_on_top_container->set_id(
@@ -83,7 +84,10 @@ Shell* Shell::instance_ = NULL;
Shell::Shell()
: ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
- aura::Desktop::GetInstance()->SetStackingClient(this);
+ aura::Desktop::GetInstance()->SetEventFilter(
+ new internal::DesktopEventFilter);
+ aura::Desktop::GetInstance()->SetStackingClient(
+ new internal::StackingController);
}
Shell::~Shell() {
@@ -101,6 +105,12 @@ Shell* Shell::GetInstance() {
return instance_;
}
+// static
+void Shell::DeleteInstanceForTesting() {
+ delete instance_;
+ instance_ = NULL;
+}
+
void Shell::Init() {
aura::Desktop* desktop_window = aura::Desktop::GetInstance();
desktop_window->SetCursor(aura::kCursorPointer);
@@ -119,10 +129,9 @@ void Shell::Init() {
desktop_window->SetLayoutManager(desktop_layout);
desktop_layout->set_background_widget(internal::CreateDesktopBackground());
- aura::ToplevelWindowContainer* toplevel_container =
- GetContainer(internal::kShellWindowId_DefaultContainer)->
- AsToplevelWindowContainer();
- launcher_.reset(new Launcher(toplevel_container));
+ aura::Window* default_container =
+ GetContainer(internal::kShellWindowId_DefaultContainer);
+ launcher_.reset(new Launcher(default_container));
shelf_layout_controller_.reset(new internal::ShelfLayoutController(
launcher_->widget(), internal::CreateStatusArea()));
@@ -133,7 +142,7 @@ void Shell::Init() {
} else {
internal::ToplevelLayoutManager* toplevel_layout_manager =
new internal::ToplevelLayoutManager();
- toplevel_container->SetLayoutManager(toplevel_layout_manager);
+ default_container->SetLayoutManager(toplevel_layout_manager);
toplevel_layout_manager->set_shelf(shelf_layout_controller_.get());
}
@@ -176,33 +185,4 @@ void Shell::EnableWorkspaceManager() {
workspace_controller_->workspace_manager()));
}
-////////////////////////////////////////////////////////////////////////////////
-// Shell, aura::StackingClient implementation:
-
-void Shell::AddChildToDefaultParent(aura::Window* window) {
- aura::Window* parent = NULL;
- switch (window->type()) {
- case aura::WINDOW_TYPE_NORMAL:
- case aura::WINDOW_TYPE_POPUP:
- parent = GetContainer(internal::kShellWindowId_DefaultContainer);
- break;
- case aura::WINDOW_TYPE_MENU:
- case aura::WINDOW_TYPE_TOOLTIP:
- parent = GetContainer(internal::kShellWindowId_MenusAndTooltipsContainer);
- break;
- default:
- NOTREACHED() << "Window " << window->id()
- << " has unhandled type " << window->type();
- break;
- }
- parent->AddChild(window);
-}
-
-aura::Window* Shell::GetTopmostWindowToActivate(aura::Window* ignore) const {
- const aura::ToplevelWindowContainer* container =
- GetContainer(internal::kShellWindowId_DefaultContainer)->
- AsToplevelWindowContainer();
- return container->GetTopmostWindowToActivate(ignore);
-}
-
} // namespace aura_shell
diff --git a/ui/aura_shell/shell.h b/ui/aura_shell/shell.h
index 7021425..5abe2b0 100644
--- a/ui/aura_shell/shell.h
+++ b/ui/aura_shell/shell.h
@@ -14,7 +14,6 @@
#include "base/task.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
-#include "ui/aura/client/stacking_client.h"
#include "ui/aura_shell/aura_shell_export.h"
namespace aura {
@@ -36,7 +35,7 @@ class WorkspaceController;
// Shell is a singleton object that presents the Shell API and implements the
// Desktop's delegate interface.
-class AURA_SHELL_EXPORT Shell : public aura::StackingClient {
+class AURA_SHELL_EXPORT Shell {
public:
// Upon creation, the Shell sets itself as the Desktop's delegate, which takes
// ownership of the Shell.
@@ -44,6 +43,7 @@ class AURA_SHELL_EXPORT Shell : public aura::StackingClient {
virtual ~Shell();
static Shell* GetInstance();
+ static void DeleteInstanceForTesting();
void Init();
@@ -65,11 +65,6 @@ class AURA_SHELL_EXPORT Shell : public aura::StackingClient {
// Enables WorkspaceManager.
void EnableWorkspaceManager();
- // Overridden from aura::StackingClient:
- virtual void AddChildToDefaultParent(aura::Window* window) OVERRIDE;
- virtual aura::Window* GetTopmostWindowToActivate(
- aura::Window* ignore) const OVERRIDE;
-
static Shell* instance_;
std::vector<WindowAndBoundsPair> to_restore_;
@@ -81,7 +76,6 @@ class AURA_SHELL_EXPORT Shell : public aura::StackingClient {
scoped_ptr<Launcher> launcher_;
scoped_ptr<internal::WorkspaceController> workspace_controller_;
-
scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_;
DISALLOW_COPY_AND_ASSIGN(Shell);
diff --git a/ui/aura_shell/stacking_controller.cc b/ui/aura_shell/stacking_controller.cc
new file mode 100644
index 0000000..1371c20
--- /dev/null
+++ b/ui/aura_shell/stacking_controller.cc
@@ -0,0 +1,95 @@
+// 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/stacking_controller.h"
+
+#include "ui/aura/desktop.h"
+#include "ui/aura/window.h"
+#include "ui/aura_shell/shell.h"
+#include "ui/aura_shell/shell_window_ids.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;
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// StackingController, public:
+
+StackingController::StackingController() {
+ aura::Desktop::GetInstance()->SetStackingClient(this);
+}
+
+StackingController::~StackingController() {
+}
+
+// static
+aura::Window* StackingController::GetActivatableWindow(aura::Window* window) {
+ aura::Window* parent = window->parent();
+ aura::Window* child = window;
+ while (parent) {
+ if (SupportsChildActivation(parent))
+ return child;
+ parent = parent->parent();
+ child = child->parent();
+ }
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// StackingController, aura::StackingClient implementation:
+
+void StackingController::AddChildToDefaultParent(aura::Window* window) {
+ aura::Window* parent = NULL;
+ switch (window->type()) {
+ case aura::WINDOW_TYPE_NORMAL:
+ case aura::WINDOW_TYPE_POPUP:
+ parent = GetContainer(internal::kShellWindowId_DefaultContainer);
+ break;
+ case aura::WINDOW_TYPE_MENU:
+ case aura::WINDOW_TYPE_TOOLTIP:
+ parent = GetContainer(internal::kShellWindowId_MenusAndTooltipsContainer);
+ break;
+ default:
+ NOTREACHED() << "Window " << window->id()
+ << " has unhandled type " << window->type();
+ break;
+ }
+ parent->AddChild(window);
+}
+
+bool StackingController::CanActivateWindow(aura::Window* window) const {
+ return window && SupportsChildActivation(window->parent());
+}
+
+aura::Window* StackingController::GetTopmostWindowToActivate(
+ aura::Window* ignore) const {
+ const aura::Window* container = GetContainer(kShellWindowId_DefaultContainer);
+ for (aura::Window::Windows::const_reverse_iterator i =
+ container->children().rbegin();
+ i != container->children().rend();
+ ++i) {
+ if (*i != ignore && (*i)->CanActivate())
+ return *i;
+ }
+ return NULL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// StackingController, private:
+
+} // namespace internal
+} // namespace aura_shell
diff --git a/ui/aura_shell/stacking_controller.h b/ui/aura_shell/stacking_controller.h
new file mode 100644
index 0000000..2091f1f
--- /dev/null
+++ b/ui/aura_shell/stacking_controller.h
@@ -0,0 +1,38 @@
+// 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.
+
+#ifndef UI_AURA_SHELL_STACKING_CONTROLLER_H_
+#define UI_AURA_SHELL_STACKING_CONTROLLER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/client/stacking_client.h"
+
+namespace aura_shell {
+namespace internal {
+
+class StackingController : public aura::StackingClient {
+ public:
+ StackingController();
+ virtual ~StackingController();
+
+ // Returns true if |window| exists within a container that supports
+ // activation.
+ static aura::Window* GetActivatableWindow(aura::Window* window);
+
+ // Overridden from aura::StackingClient:
+ virtual void AddChildToDefaultParent(aura::Window* window) OVERRIDE;
+ virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE;
+ virtual aura::Window* GetTopmostWindowToActivate(
+ aura::Window* ignore) const OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StackingController);
+};
+
+} // namespace internal
+} // namespace aura_shell
+
+#endif // UI_AURA_SHELL_STACKING_CONTROLLER_H_
diff --git a/ui/aura_shell/stacking_controller_unittest.cc b/ui/aura_shell/stacking_controller_unittest.cc
new file mode 100644
index 0000000..a7cd2c9
--- /dev/null
+++ b/ui/aura_shell/stacking_controller_unittest.cc
@@ -0,0 +1,34 @@
+// 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/stacking_controller.h"
+
+#include "ui/aura/desktop.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura_shell/shell.h"
+
+namespace aura_shell {
+namespace test {
+
+typedef aura::test::AuraTestBase StackingControllerTest;
+
+TEST_F(StackingControllerTest, GetTopmostWindowToActivate) {
+ Shell::GetInstance();
+ aura::test::ActivateWindowDelegate activate;
+ aura::test::ActivateWindowDelegate non_activate(false);
+
+ scoped_ptr<aura::Window> w1(aura::test::CreateTestWindowWithDelegate(
+ &non_activate, 1, gfx::Rect(), NULL));
+ scoped_ptr<aura::Window> w2(aura::test::CreateTestWindowWithDelegate(
+ &activate, 2, gfx::Rect(), NULL));
+ scoped_ptr<aura::Window> w3(aura::test::CreateTestWindowWithDelegate(
+ &non_activate, 3, gfx::Rect(), NULL));
+ EXPECT_EQ(w2.get(), aura::Desktop::GetInstance()->stacking_client()->
+ GetTopmostWindowToActivate(NULL));
+}
+
+} // namespace test
+} // namespace aura_shell
diff --git a/ui/aura_shell/test_suite.cc b/ui/aura_shell/test_suite.cc
index 557bd95..fcd3a8f 100644
--- a/ui/aura_shell/test_suite.cc
+++ b/ui/aura_shell/test_suite.cc
@@ -13,6 +13,9 @@
#include "ui/gfx/gfx_paths.h"
#include "ui/gfx/test/gfx_test_utils.h"
+namespace aura_shell {
+namespace test {
+
AuraShellTestSuite::AuraShellTestSuite(int argc, char** argv)
: TestSuite(argc, argv) {}
@@ -35,3 +38,6 @@ void AuraShellTestSuite::Shutdown() {
base::TestSuite::Shutdown();
}
+
+} // namespace test
+} // namespace aura_shell
diff --git a/ui/aura_shell/test_suite.h b/ui/aura_shell/test_suite.h
index 72e946c..fac7daf 100644
--- a/ui/aura_shell/test_suite.h
+++ b/ui/aura_shell/test_suite.h
@@ -9,6 +9,9 @@
#include "base/compiler_specific.h"
#include "base/test/test_suite.h"
+namespace aura_shell {
+namespace test {
+
class AuraShellTestSuite : public base::TestSuite {
public:
AuraShellTestSuite(int argc, char** argv);
@@ -19,4 +22,7 @@ class AuraShellTestSuite : public base::TestSuite {
virtual void Shutdown() OVERRIDE;
};
+} // namespace test
+} // namespace aura_shell
+
#endif // UI_AURA_SHELL_TEST_SUITE_H_
diff --git a/ui/aura_shell/toplevel_layout_manager.h b/ui/aura_shell/toplevel_layout_manager.h
index 0593e8d..d8774fe 100644
--- a/ui/aura_shell/toplevel_layout_manager.h
+++ b/ui/aura_shell/toplevel_layout_manager.h
@@ -19,10 +19,10 @@ namespace internal {
class ShelfLayoutController;
-// ToplevelLayoutManager is the LayoutManager installed on the
-// ToplevelWindowContainer. It is used if the WorkspaceManager is not
-// enabled. ToplevelLayoutManager listens for changes to kShowStateKey and
-// resizes the window appropriately.
+// ToplevelLayoutManager is the LayoutManager installed on a container that
+// hosts what the shell considers to be top-level windows. It is used if the
+// WorkspaceManager is not enabled. ToplevelLayoutManager listens for changes to
+// kShowStateKey and resizes the window appropriately.
class AURA_SHELL_EXPORT ToplevelLayoutManager : public aura::LayoutManager,
public aura::WindowObserver {
public:
diff --git a/ui/aura_shell/workspace_controller_unittest.cc b/ui/aura_shell/workspace_controller_unittest.cc
index 6f3241b..7128a40 100644
--- a/ui/aura_shell/workspace_controller_unittest.cc
+++ b/ui/aura_shell/workspace_controller_unittest.cc
@@ -35,6 +35,7 @@ class WorkspaceControllerTest : public aura::test::AuraTestBase {
aura::Window* window = new aura::Window(NULL);
window->Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
contents_view()->AddChild(window);
+ window->Show();
return window;
}
@@ -61,7 +62,6 @@ TEST_F(WorkspaceControllerTest, Overview) {
// and ws2 which contains window w2.
Workspace* ws1 = workspace_manager()->CreateWorkspace();
scoped_ptr<Window> w1(CreateTestWindow());
-
EXPECT_TRUE(ws1->AddWindowAfter(w1.get(), NULL));
Workspace* ws2 = workspace_manager()->CreateWorkspace();
@@ -81,7 +81,7 @@ TEST_F(WorkspaceControllerTest, Overview) {
// Switching overview mode doesn't change the active workspace.
EXPECT_EQ(ws2, workspace_manager()->GetActiveWorkspace());
- // Activaing window w1 switches the active window and
+ // Activating window w1 switches the active window and
// the mode back to normal mode.
w1->Activate();
EXPECT_EQ(ws1, workspace_manager()->GetActiveWorkspace());
@@ -91,7 +91,7 @@ TEST_F(WorkspaceControllerTest, Overview) {
ws1->RemoveWindow(w1.get());
delete ws1;
w1.reset();
- EXPECT_EQ(NULL, workspace_manager()->GetActiveWorkspace());
+ EXPECT_EQ(ws2, workspace_manager()->GetActiveWorkspace());
EXPECT_EQ("0,0 500x300", contents_view()->bounds().ToString());
ws2->RemoveWindow(w2.get());
delete ws2;
diff --git a/views/widget/native_widget_aura.cc b/views/widget/native_widget_aura.cc
index 7326fe4..8da5452 100644
--- a/views/widget/native_widget_aura.cc
+++ b/views/widget/native_widget_aura.cc
@@ -680,9 +680,6 @@ NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
// static
NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
gfx::NativeView native_view) {
- if (!native_view)
- return NULL;
-
aura::Window* window = native_view;
NativeWidgetPrivate* top_level_native_widget = NULL;
while (window) {