summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-21 21:13:19 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-21 21:13:19 +0000
commit2d0bd352bba817a6311cc58ed09083741f262841 (patch)
treeeffe12bf12c3f7cdeb5d1fe7ba88ce2ffee7f7ae
parent2e11765ef682220b05d2cd16e5b92d09dde86de0 (diff)
downloadchromium_src-2d0bd352bba817a6311cc58ed09083741f262841.zip
chromium_src-2d0bd352bba817a6311cc58ed09083741f262841.tar.gz
chromium_src-2d0bd352bba817a6311cc58ed09083741f262841.tar.bz2
Add support for MouseEnter/MouseExit event types to be sent to aura::Windows.
BUG=none TEST=see unittest Review URL: http://codereview.chromium.org/7983039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102168 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/aura/event.cc8
-rw-r--r--ui/aura/event.h5
-rw-r--r--ui/aura/root_window.cc40
-rw-r--r--ui/aura/root_window.h5
-rw-r--r--ui/aura/window_unittest.cc60
5 files changed, 114 insertions, 4 deletions
diff --git a/ui/aura/event.cc b/ui/aura/event.cc
index ee79fce..6846f2e 100644
--- a/ui/aura/event.cc
+++ b/ui/aura/event.cc
@@ -49,6 +49,14 @@ MouseEvent::MouseEvent(const MouseEvent& model, Window* source, Window* target)
: LocatedEvent(model, source, target) {
}
+MouseEvent::MouseEvent(const MouseEvent& model,
+ Window* source,
+ Window* target,
+ ui::EventType type)
+ : LocatedEvent(model, source, target) {
+ set_type(type);
+}
+
MouseEvent::MouseEvent(ui::EventType type,
const gfx::Point& location,
int flags)
diff --git a/ui/aura/event.h b/ui/aura/event.h
index ed3a938..3560805 100644
--- a/ui/aura/event.h
+++ b/ui/aura/event.h
@@ -38,6 +38,7 @@ class AURA_EXPORT Event {
Event(ui::EventType type, int flags);
Event(NativeEvent native_event, ui::EventType type, int flags);
Event(const Event& copy);
+ void set_type(ui::EventType type) { type_ = type; }
private:
void operator=(const Event&);
@@ -83,6 +84,10 @@ class AURA_EXPORT MouseEvent : public LocatedEvent {
// If source / target windows are provided, the model location will be
// converted from |source| coordinate system to |target| coordinate system.
MouseEvent(const MouseEvent& model, Window* source, Window* target);
+ MouseEvent(const MouseEvent& model,
+ Window* source,
+ Window* target,
+ ui::EventType type);
// Used for synthetic events in testing.
MouseEvent(ui::EventType type, const gfx::Point& location, int flags);
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index f4b0c29..a528636 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -17,6 +17,7 @@ namespace internal {
RootWindow::RootWindow()
: Window(NULL),
mouse_pressed_handler_(NULL),
+ mouse_moved_handler_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(focus_manager_(new FocusManager(this))),
capture_window_(NULL) {
set_name(ASCIIToUTF16("RootWindow"));
@@ -30,10 +31,20 @@ bool RootWindow::HandleMouseEvent(const MouseEvent& event) {
mouse_pressed_handler_ ? mouse_pressed_handler_ : capture_window_;
if (!target)
target = GetEventHandlerForPoint(event.location());
- if (event.type() == ui::ET_MOUSE_PRESSED && !mouse_pressed_handler_)
- mouse_pressed_handler_ = target;
- if (event.type() == ui::ET_MOUSE_RELEASED)
- mouse_pressed_handler_ = NULL;
+ switch (event.type()) {
+ case ui::ET_MOUSE_MOVED:
+ HandleMouseMoved(event, target);
+ break;
+ case ui::ET_MOUSE_PRESSED:
+ if (!mouse_pressed_handler_)
+ mouse_pressed_handler_ = target;
+ break;
+ case ui::ET_MOUSE_RELEASED:
+ mouse_pressed_handler_ = NULL;
+ break;
+ default:
+ break;
+ }
if (target && target->delegate()) {
MouseEvent translated_event(event, this, target);
return target->OnMouseEvent(&translated_event);
@@ -85,6 +96,8 @@ void RootWindow::WindowDestroying(Window* window) {
// don't sent it release/capture lost events.
if (mouse_pressed_handler_ == window)
mouse_pressed_handler_ = NULL;
+ if (mouse_moved_handler_ == window)
+ mouse_moved_handler_ = NULL;
if (capture_window_ == window)
capture_window_ = NULL;
}
@@ -97,5 +110,24 @@ internal::RootWindow* RootWindow::GetRoot() {
return this;
}
+void RootWindow::HandleMouseMoved(const MouseEvent& event, Window* target) {
+ if (target == mouse_moved_handler_)
+ return;
+
+ // Send an exited event.
+ if (mouse_moved_handler_ && mouse_moved_handler_->delegate()) {
+ MouseEvent translated_event(event, this, mouse_moved_handler_,
+ ui::ET_MOUSE_EXITED);
+ mouse_moved_handler_->OnMouseEvent(&translated_event);
+ }
+ mouse_moved_handler_ = target;
+ // Send an entered event.
+ if (mouse_moved_handler_ && mouse_moved_handler_->delegate()) {
+ MouseEvent translated_event(event, this, mouse_moved_handler_,
+ ui::ET_MOUSE_ENTERED);
+ mouse_moved_handler_->OnMouseEvent(&translated_event);
+ }
+}
+
} // namespace internal
} // namespace aura
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 5d3de84..b3bf0e0 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -50,7 +50,12 @@ class RootWindow : public Window {
virtual internal::RootWindow* GetRoot() OVERRIDE;
private:
+ // Called whenever the mouse moves, tracks the current |mouse_moved_handler_|,
+ // sending exited and entered events as its value changes.
+ void HandleMouseMoved(const MouseEvent& event, Window* target);
+
Window* mouse_pressed_handler_;
+ Window* mouse_moved_handler_;
scoped_ptr<FocusManager> focus_manager_;
Window* capture_window_;
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 59d5dd1..6109145 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -385,5 +385,65 @@ TEST_F(WindowTest, ReleaseCaptureOnDestroy) {
EXPECT_EQ(NULL, root->capture_window());
}
+class MouseEnterExitWindowDelegate : public WindowDelegateImpl {
+ public:
+ MouseEnterExitWindowDelegate() : entered_(false), exited_(false) {}
+
+ virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE {
+ switch (event->type()) {
+ case ui::ET_MOUSE_ENTERED:
+ entered_ = true;
+ break;
+ case ui::ET_MOUSE_EXITED:
+ exited_ = true;
+ break;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ bool entered() const { return entered_; }
+ bool exited() const { return exited_; }
+
+ private:
+ bool entered_;
+ bool exited_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseEnterExitWindowDelegate);
+};
+
+
+// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
+// mouse transitions from window to window.
+TEST_F(WindowTest, MouseEnterExit) {
+ Desktop* desktop = Desktop::GetInstance();
+
+ MouseEnterExitWindowDelegate d1;
+ scoped_ptr<Window> w1(
+ CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50), NULL));
+ MouseEnterExitWindowDelegate d2;
+ scoped_ptr<Window> w2(
+ CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50), NULL));
+
+ gfx::Point move_point = w1->bounds().CenterPoint();
+ Window::ConvertPointToWindow(w1->parent(), desktop->window(), &move_point);
+ desktop->OnMouseEvent(MouseEvent(ui::ET_MOUSE_MOVED, move_point, 0));
+
+ EXPECT_TRUE(d1.entered());
+ EXPECT_FALSE(d1.exited());
+ EXPECT_FALSE(d2.entered());
+ EXPECT_FALSE(d2.exited());
+
+ move_point = w2->bounds().CenterPoint();
+ Window::ConvertPointToWindow(w2->parent(), desktop->window(), &move_point);
+ desktop->OnMouseEvent(MouseEvent(ui::ET_MOUSE_MOVED, move_point, 0));
+
+ EXPECT_TRUE(d1.entered());
+ EXPECT_TRUE(d1.exited());
+ EXPECT_TRUE(d2.entered());
+ EXPECT_FALSE(d2.exited());
+}
+
} // namespace internal
} // namespace aura