diff options
Diffstat (limited to 'ui/aura/root_window_unittest.cc')
-rw-r--r-- | ui/aura/root_window_unittest.cc | 137 |
1 files changed, 131 insertions, 6 deletions
diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc index ab7e986..31eef5b 100644 --- a/ui/aura/root_window_unittest.cc +++ b/ui/aura/root_window_unittest.cc @@ -5,13 +5,16 @@ #include "ui/aura/root_window.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/client/event_client.h" #include "ui/aura/env.h" #include "ui/aura/event.h" #include "ui/aura/event_filter.h" #include "ui/aura/test/aura_test_base.h" +#include "ui/aura/test/event_generator.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_windows.h" #include "ui/base/hit_test.h" +#include "ui/base/keycodes/keyboard_codes.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" @@ -59,12 +62,18 @@ class NonClientDelegate : public test::TestWindowDelegate { // A simple EventFilter that keeps track of the number of key events that it's // seen. -class TestEventFilter : public EventFilter { +class EventCountFilter : public EventFilter { public: - TestEventFilter() : num_key_events_(0) {} - virtual ~TestEventFilter() {} + EventCountFilter() : num_key_events_(0), num_mouse_events_(0) {} + virtual ~EventCountFilter() {} int num_key_events() const { return num_key_events_; } + int num_mouse_events() const { return num_mouse_events_; } + + void Reset() { + num_key_events_ = 0; + num_mouse_events_ = 0; + } // EventFilter overrides: virtual bool PreHandleKeyEvent(Window* target, KeyEvent* event) OVERRIDE { @@ -72,7 +81,8 @@ class TestEventFilter : public EventFilter { return true; } virtual bool PreHandleMouseEvent(Window* target, MouseEvent* event) OVERRIDE { - return false; + num_mouse_events_++; + return true; } virtual ui::TouchStatus PreHandleTouchEvent( Window* target, TouchEvent* event) OVERRIDE { @@ -87,7 +97,10 @@ class TestEventFilter : public EventFilter { // How many key events have been received? int num_key_events_; - DISALLOW_COPY_AND_ASSIGN(TestEventFilter); + // How many mouse events have been received? + int num_mouse_events_; + + DISALLOW_COPY_AND_ASSIGN(EventCountFilter); }; } // namespace @@ -199,8 +212,120 @@ TEST_F(RootWindowTest, TranslatedEvent) { EXPECT_EQ("100,100", translated_event.root_location().ToString()); } +namespace { + +class TestEventClient : public client::EventClient { + public: + static const int kNonLockWindowId = 100; + static const int kLockWindowId = 200; + + explicit TestEventClient(RootWindow* root_window) + : root_window_(root_window), + lock_(false) { + client::SetEventClient(root_window_, this); + Window* lock_window = + test::CreateTestWindowWithBounds(root_window_->bounds(), root_window_); + lock_window->set_id(kLockWindowId); + Window* non_lock_window = + test::CreateTestWindowWithBounds(root_window_->bounds(), root_window_); + non_lock_window->set_id(kNonLockWindowId); + } + virtual ~TestEventClient() { + client::SetEventClient(root_window_, NULL); + } + + // Starts/stops locking. Locking prevents windows other than those inside + // the lock container from receiving events, getting focus etc. + void Lock() { + lock_ = true; + } + void Unlock() { + lock_ = false; + } + + Window* GetLockWindow() { + return const_cast<Window*>( + static_cast<const TestEventClient*>(this)->GetLockWindow()); + } + const Window* GetLockWindow() const { + return root_window_->GetChildById(kLockWindowId); + } + Window* GetNonLockWindow() { + return root_window_->GetChildById(kNonLockWindowId); + } + + private: + // Overridden from client::EventClient: + virtual bool CanProcessEventsWithinSubtree( + const Window* window) const OVERRIDE { + return lock_ ? GetLockWindow()->Contains(window) : true; + } + + RootWindow* root_window_; + bool lock_; + + DISALLOW_COPY_AND_ASSIGN(TestEventClient); +}; + +} // namespace + +TEST_F(RootWindowTest, CanProcessEventsWithinSubtree) { + TestEventClient client(root_window()); + test::TestWindowDelegate d; + + EventCountFilter* nonlock_ef = new EventCountFilter; + EventCountFilter* lock_ef = new EventCountFilter; + client.GetNonLockWindow()->SetEventFilter(nonlock_ef); + client.GetLockWindow()->SetEventFilter(lock_ef); + + Window* w1 = test::CreateTestWindowWithBounds(gfx::Rect(10, 10, 20, 20), + client.GetNonLockWindow()); + w1->set_id(1); + Window* w2 = test::CreateTestWindowWithBounds(gfx::Rect(30, 30, 20, 20), + client.GetNonLockWindow()); + w2->set_id(2); + scoped_ptr<Window> w3( + test::CreateTestWindowWithDelegate(&d, 3, gfx::Rect(20, 20, 20, 20), + client.GetLockWindow())); + + w1->Focus(); + EXPECT_TRUE(w1->GetFocusManager()->IsFocusedWindow(w1)); + + client.Lock(); + + // Since we're locked, the attempt to focus w2 will be ignored. + w2->Focus(); + EXPECT_TRUE(w1->GetFocusManager()->IsFocusedWindow(w1)); + EXPECT_FALSE(w1->GetFocusManager()->IsFocusedWindow(w2)); + + { + // Attempting to send a key event to w1 (not in the lock container) should + // cause focus to be reset. + test::EventGenerator generator(root_window()); + generator.PressKey(ui::VKEY_SPACE, 0); + EXPECT_EQ(NULL, w1->GetFocusManager()->GetFocusedWindow()); + } + + { + // Events sent to a window not in the lock container will not be processed. + // i.e. never sent to the non-lock container's event filter. + test::EventGenerator generator(root_window(), w1); + generator.PressLeftButton(); + EXPECT_EQ(0, nonlock_ef->num_mouse_events()); + + // Events sent to a window in the lock container will be processed. + test::EventGenerator generator3(root_window(), w3.get()); + generator3.PressLeftButton(); + EXPECT_EQ(1, lock_ef->num_mouse_events()); + } + + // Prevent w3 from being deleted by the hierarchy since its delegate is owned + // by this scope. + w3->parent()->RemoveChild(w3.get()); +} + TEST_F(RootWindowTest, IgnoreUnknownKeys) { - TestEventFilter* filter = new TestEventFilter; + EventCountFilter* filter = new EventCountFilter; root_window()->SetEventFilter(filter); // passes ownership KeyEvent unknown_event(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, 0); |