summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-22 23:35:56 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-22 23:35:56 +0000
commit4b87bc2e3c13bd572a2b1b9a08ea2644120e6d6c (patch)
treed1dd9f473c130f4e51a9cda7e8b49cb42c8f13bf /ui
parent4ad932db8c764a861f9c5a578599271f179a9020 (diff)
downloadchromium_src-4b87bc2e3c13bd572a2b1b9a08ea2644120e6d6c.zip
chromium_src-4b87bc2e3c13bd572a2b1b9a08ea2644120e6d6c.tar.gz
chromium_src-4b87bc2e3c13bd572a2b1b9a08ea2644120e6d6c.tar.bz2
Revert 128328 - Remove stops_event_propagation from Window, since it's broken.
Changes it to be implemented by the Aura client, via a new interface EventClient. The client can determine whether or not a given window and its subtree can receive events. I also cleaned up the way screen locking is entered/exited via the delegate, and some stuff in ash/shell. http://crbug.com/119347 TEST=none Review URL: https://chromiumcodereview.appspot.com/9788001 TBR=ben@chromium.org Review URL: https://chromiumcodereview.appspot.com/9808044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128338 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/aura.gyp2
-rw-r--r--ui/aura/client/event_client.cc27
-rw-r--r--ui/aura/client/event_client.h36
-rw-r--r--ui/aura/root_window.cc7
-rw-r--r--ui/aura/root_window_unittest.cc153
-rw-r--r--ui/aura/window.cc53
-rw-r--r--ui/aura/window.h24
-rw-r--r--ui/aura/window_unittest.cc56
-rw-r--r--ui/oak/oak_aura_window_display.cc4
9 files changed, 110 insertions, 252 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index e0dafba..89aea94 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -38,8 +38,6 @@
'client/drag_drop_client.h',
'client/drag_drop_delegate.cc',
'client/drag_drop_delegate.h',
- 'client/event_client.cc',
- 'client/event_client.h',
'client/stacking_client.cc',
'client/stacking_client.h',
'client/tooltip_client.cc',
diff --git a/ui/aura/client/event_client.cc b/ui/aura/client/event_client.cc
deleted file mode 100644
index dfb3410..0000000
--- a/ui/aura/client/event_client.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/aura/client/event_client.h"
-
-#include "ui/aura/root_window.h"
-#include "ui/aura/window_property.h"
-
-DECLARE_WINDOW_PROPERTY_TYPE(aura::client::EventClient*)
-
-namespace aura {
-namespace client {
-
-DEFINE_WINDOW_PROPERTY_KEY(EventClient*, kRootWindowEventClientKey, NULL);
-
-void SetEventClient(RootWindow* root_window, EventClient* client) {
- root_window->SetProperty(kRootWindowEventClientKey, client);
-}
-
-EventClient* GetEventClient(const RootWindow* root_window) {
- return root_window ?
- root_window->GetProperty(kRootWindowEventClientKey) : NULL;
-}
-
-} // namespace client
-} // namespace aura
diff --git a/ui/aura/client/event_client.h b/ui/aura/client/event_client.h
deleted file mode 100644
index caf3a2b..0000000
--- a/ui/aura/client/event_client.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_AURA_CLIENT_EVENT_CLIENT_H_
-#define UI_AURA_CLIENT_EVENT_CLIENT_H_
-#pragma once
-
-#include "ui/aura/aura_export.h"
-#include "ui/aura/window.h"
-
-namespace aura {
-
-class Event;
-class RootWindow;
-
-namespace client {
-
-// An interface implemented by an object that alters event processing.
-class AURA_EXPORT EventClient {
- public:
- // Returns true if events can be processed by |window| or any of its children.
- virtual bool CanProcessEventsWithinSubtree(const Window* window) const = 0;
-
- protected:
- virtual ~EventClient() {}
-};
-
-// Sets/Gets the event client on the RootWindow.
-AURA_EXPORT void SetEventClient(RootWindow* root_window, EventClient* client);
-AURA_EXPORT EventClient* GetEventClient(const RootWindow* root_window);
-
-} // namespace clients
-} // namespace aura
-
-#endif // UI_AURA_CLIENT_EVENT_CLIENT_H_
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 65c0fb1..12ee747 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -12,7 +12,6 @@
#include "base/message_loop.h"
#include "ui/aura/aura_switches.h"
#include "ui/aura/client/activation_client.h"
-#include "ui/aura/client/event_client.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window_host.h"
#include "ui/aura/root_window_observer.h"
@@ -195,12 +194,6 @@ bool RootWindow::DispatchMouseEvent(MouseEvent* event) {
bool RootWindow::DispatchKeyEvent(KeyEvent* event) {
DispatchHeldMouseMove();
KeyEvent translated_event(*event);
-
- client::EventClient* client = client::GetEventClient(GetRootWindow());
- if (client && !client->CanProcessEventsWithinSubtree(focused_window_)) {
- SetFocusedWindow(NULL, NULL);
- return false;
- }
return ProcessKeyEvent(focused_window_, &translated_event);
}
diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc
index 778ed39..3b336f0 100644
--- a/ui/aura/root_window_unittest.cc
+++ b/ui/aura/root_window_unittest.cc
@@ -5,16 +5,12 @@
#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"
@@ -167,153 +163,4 @@ 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);
-};
-
-class TestEventFilter : public aura::EventFilter {
- public:
- TestEventFilter() {
- Reset();
- }
- virtual ~TestEventFilter() {}
-
- void Reset() {
- mouse_event_count_ = 0;
- }
-
- int mouse_event_count() const { return mouse_event_count_; }
-
- private:
- virtual bool PreHandleKeyEvent(Window* target, KeyEvent* event) OVERRIDE {
- return true;
- }
- virtual bool PreHandleMouseEvent(Window* target, MouseEvent* event) OVERRIDE {
- ++mouse_event_count_;
- return true;
- }
- virtual ui::TouchStatus PreHandleTouchEvent(Window* target,
- TouchEvent* event) OVERRIDE {
- return ui::TOUCH_STATUS_UNKNOWN;
- }
- virtual ui::GestureStatus PreHandleGestureEvent(
- Window* target,
- GestureEvent* event) OVERRIDE {
- return ui::GESTURE_STATUS_UNKNOWN;
- }
-
- int mouse_event_count_;
-
- DISALLOW_COPY_AND_ASSIGN(TestEventFilter);
-};
-
-} // namespace
-
-TEST_F(RootWindowTest, CanProcessEventsWithinSubtree) {
- TestEventClient client(root_window());
- test::TestWindowDelegate d;
-
- TestEventFilter* nonlock_ef = new TestEventFilter;
- TestEventFilter* lock_ef = new TestEventFilter;
- 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->mouse_event_count());
-
- // 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->mouse_event_count());
- }
-
- // Prevent w3 from being deleted by the hierarchy since its delegate is owned
- // by this scope.
- w3->parent()->RemoveChild(w3.get());
-}
-
-
} // namespace aura
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index dfa6881..8f08a4b 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -9,7 +9,6 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/string_util.h"
-#include "ui/aura/client/event_client.h"
#include "ui/aura/client/stacking_client.h"
#include "ui/aura/client/visibility_client.h"
#include "ui/aura/env.h"
@@ -54,6 +53,7 @@ Window::Window(WindowDelegate* delegate)
id_(-1),
transparent_(false),
user_data_(NULL),
+ stops_event_propagation_(false),
ignore_events_(false),
hit_test_bounds_override_outer_(0),
hit_test_bounds_override_inner_(0) {
@@ -449,24 +449,12 @@ bool Window::HasFocus() const {
bool Window::CanFocus() const {
if (!IsVisible() || !parent_ || (delegate_ && !delegate_->CanFocus()))
return false;
-
- // The client may forbid certain windows from receiving focus at a given point
- // in time.
- client::EventClient* client = client::GetEventClient(GetRootWindow());
- if (client && !client->CanProcessEventsWithinSubtree(this))
- return false;
-
- return parent_->CanFocus();
+ return !IsBehindStopEventsWindow() && parent_->CanFocus();
}
bool Window::CanReceiveEvents() const {
- // The client may forbid certain windows from receiving events at a given
- // point in time.
- client::EventClient* client = client::GetEventClient(GetRootWindow());
- if (client && !client->CanProcessEventsWithinSubtree(this))
- return false;
-
- return parent_ && IsVisible() && parent_->CanReceiveEvents();
+ return parent_ && IsVisible() && !IsBehindStopEventsWindow() &&
+ parent_->CanReceiveEvents();
}
internal::FocusManager* Window::GetFocusManager() {
@@ -502,6 +490,15 @@ bool Window::HasCapture() {
return root_window && root_window->capture_window() == this;
}
+bool Window::StopsEventPropagation() const {
+ if (!stops_event_propagation_ || children_.empty())
+ return false;
+ aura::Window::Windows::const_iterator it =
+ std::find_if(children_.begin(), children_.end(),
+ std::mem_fun(&aura::Window::IsVisible));
+ return it != children_.end();
+}
+
void Window::SuppressPaint() {
layer_->SuppressPaint();
}
@@ -656,16 +653,6 @@ Window* Window::GetWindowForPoint(const gfx::Point& local_point,
rend = children_.rend();
it != rend; ++it) {
Window* child = *it;
-
- if (for_event_handling) {
- // The client may not allow events to be processed by certain subtrees.
- client::EventClient* client = client::GetEventClient(GetRootWindow());
- if (client && !client->CanProcessEventsWithinSubtree(child))
- continue;
- }
-
- // We don't process events for invisible windows or those that have asked
- // to ignore events.
if (!child->IsVisible() || (for_event_handling && child->ignore_events_))
continue;
@@ -676,6 +663,9 @@ Window* Window::GetWindowForPoint(const gfx::Point& local_point,
for_event_handling);
if (match)
return match;
+
+ if (for_event_handling && child->StopsEventPropagation())
+ break;
}
return delegate_ ? this : NULL;
@@ -810,4 +800,15 @@ void Window::UpdateLayerName(const std::string& name) {
#endif
}
+bool Window::IsBehindStopEventsWindow() const {
+ Windows::const_iterator i = std::find(parent_->children().begin(),
+ parent_->children().end(),
+ this);
+ for (++i; i != parent_->children().end(); ++i) {
+ if ((*i)->StopsEventPropagation())
+ return true;
+ }
+ return false;
+}
+
} // namespace aura
diff --git a/ui/aura/window.h b/ui/aura/window.h
index e728760..9c2703b 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -218,6 +218,15 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
void AddObserver(WindowObserver* observer);
void RemoveObserver(WindowObserver* observer);
+ // When set to true, this Window will stop propagation of all events targeted
+ // at Windows below it in the z-order, but only if this Window has children.
+ // This is used to implement lock-screen type functionality where we do not
+ // want events to be sent to running logged-in windows when the lock screen is
+ // displayed.
+ void set_stops_event_propagation(bool stops_event_propagation) {
+ stops_event_propagation_ = stops_event_propagation;
+ }
+
void set_ignore_events(bool ignore_events) { ignore_events_ = ignore_events; }
// Sets the window to grab hits for an area extending |outer| pixels outside
@@ -285,6 +294,10 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Returns true if this window has a mouse capture.
bool HasCapture();
+ // Returns true if this window is currently stopping event
+ // propagation for any windows behind it in the z-order.
+ bool StopsEventPropagation() const;
+
// Suppresses painting window content by disgarding damaged rect and ignoring
// new paint requests.
void SuppressPaint();
@@ -345,7 +358,8 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// If |return_tightest| is true, returns the tightest-containing (i.e.
// furthest down the hierarchy) Window containing the point; otherwise,
// returns the loosest. If |for_event_handling| is true, then hit-test masks
- // are honored; otherwise, only bounds checks are performed.
+ // and StopsEventPropagation() are honored; otherwise, only bounds checks are
+ // performed.
Window* GetWindowForPoint(const gfx::Point& local_point,
bool return_tightest,
bool for_event_handling);
@@ -378,6 +392,10 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Updates the layer name with a name based on the window's name and id.
void UpdateLayerName(const std::string& name);
+ // Returns true if this window is behind a window that stops event
+ // propagation.
+ bool IsBehindStopEventsWindow() const;
+
client::WindowType type_;
WindowDelegate* delegate_;
@@ -419,6 +437,10 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
void* user_data_;
+ // When true, events are not sent to windows behind this one in the z-order,
+ // provided this window has children. See set_stops_event_propagation().
+ bool stops_event_propagation_;
+
// Makes the window pass all events through to any windows behind it.
bool ignore_events_;
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 7f7fd75..bac8e51 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -355,6 +355,10 @@ TEST_F(WindowTest, GetTopWindowContainingPoint) {
scoped_ptr<Window> w311(
CreateTestWindow(SK_ColorBLUE, 311, gfx::Rect(0, 0, 10, 10), w31.get()));
+ // The stop-event-propagation flag shouldn't have any effect on the behavior
+ // of this method.
+ w3->set_stops_event_propagation(true);
+
EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(0, 0)));
EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(5, 5)));
EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(10, 10)));
@@ -804,6 +808,58 @@ TEST_F(WindowTest, Visibility) {
EXPECT_TRUE(w3->IsVisible());
}
+// When set_consume_events() is called with |true| for a Window, that Window
+// should make sure that none behind it in the z-order see events if it has
+// children. If it does not have children, event targeting works as usual.
+TEST_F(WindowTest, StopsEventPropagation) {
+ TestWindowDelegate d11;
+ TestWindowDelegate d111;
+ TestWindowDelegate d121;
+ scoped_ptr<Window> w1(CreateTestWindowWithDelegate(NULL, 1,
+ gfx::Rect(0, 0, 500, 500), NULL));
+ scoped_ptr<Window> w11(CreateTestWindowWithDelegate(&d11, 11,
+ gfx::Rect(0, 0, 500, 500), w1.get()));
+ scoped_ptr<Window> w111(CreateTestWindowWithDelegate(&d111, 111,
+ gfx::Rect(50, 50, 450, 450), w11.get()));
+ scoped_ptr<Window> w12(CreateTestWindowWithDelegate(NULL, 12,
+ gfx::Rect(0, 0, 500, 500), w1.get()));
+ scoped_ptr<Window> w121(CreateTestWindowWithDelegate(&d121, 121,
+ gfx::Rect(150, 150, 50, 50), NULL));
+
+ w12->set_stops_event_propagation(true);
+ EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
+
+ EXPECT_TRUE(w111->CanFocus());
+ EXPECT_TRUE(w111->CanReceiveEvents());
+ w111->Focus();
+ EXPECT_EQ(w111.get(), w1->GetFocusManager()->GetFocusedWindow());
+
+ w12->AddChild(w121.get());
+
+ EXPECT_EQ(NULL, w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
+ EXPECT_EQ(w121.get(), w1->GetEventHandlerForPoint(gfx::Point(175, 175)));
+
+ // It should be possible to focus w121 since it is at or above the
+ // consumes_events_ window.
+ EXPECT_TRUE(w121->CanFocus());
+ EXPECT_TRUE(w121->CanReceiveEvents());
+ w121->Focus();
+ EXPECT_EQ(w121.get(), w1->GetFocusManager()->GetFocusedWindow());
+
+ // An attempt to focus 111 should be ignored and w121 should retain focus,
+ // since a consumes_events_ window with a child is in the z-index above w111.
+ EXPECT_FALSE(w111->CanReceiveEvents());
+ w111->Focus();
+ EXPECT_EQ(w121.get(), w1->GetFocusManager()->GetFocusedWindow());
+
+ // Hiding w121 should make 111 focusable.
+ w121->Hide();
+ EXPECT_TRUE(w111->CanFocus());
+ EXPECT_TRUE(w111->CanReceiveEvents());
+ w111->Focus();
+ EXPECT_EQ(w111.get(), w1->GetFocusManager()->GetFocusedWindow());
+}
+
TEST_F(WindowTest, IgnoreEventsTest) {
TestWindowDelegate d11;
TestWindowDelegate d12;
diff --git a/ui/oak/oak_aura_window_display.cc b/ui/oak/oak_aura_window_display.cc
index fce9406..214a005 100644
--- a/ui/oak/oak_aura_window_display.cc
+++ b/ui/oak/oak_aura_window_display.cc
@@ -32,6 +32,7 @@ ROW_ROOTWINDOW,
ROW_TRANSIENTCHILDREN,
ROW_TRANSIENTPARENT,
ROW_USERDATA,
+ROW_STOPSEVENTPROPAGATION,
ROW_IGNOREEVENTS,
ROW_CANFOCUS,
ROW_HITTESTBOUNDSOVERRIDE,
@@ -136,6 +137,9 @@ string16 OakAuraWindowDisplay::GetText(int row, int column_id) {
window_->transient_parent());
case ROW_USERDATA:
return PropertyWithVoidStar("User Data: ", window_->user_data());
+ case ROW_STOPSEVENTPROPAGATION:
+ return PropertyWithBool("Stops event propagation: ",
+ window_->StopsEventPropagation());
case ROW_IGNOREEVENTS:
return PropertyWithBool("Can receive events: ",
window_->CanReceiveEvents());