summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 16:33:54 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 16:33:54 +0000
commita99329d8f691d5dbf8e1ea78cc3a91413a9b3df2 (patch)
treeefb63253a060b209d97a87ee86345c71314b8621 /ui
parentcef6c76ff40bf74edbcf8df0a19dc0c08fb7daca (diff)
downloadchromium_src-a99329d8f691d5dbf8e1ea78cc3a91413a9b3df2.zip
chromium_src-a99329d8f691d5dbf8e1ea78cc3a91413a9b3df2.tar.gz
chromium_src-a99329d8f691d5dbf8e1ea78cc3a91413a9b3df2.tar.bz2
Fixes bug in RepostEvent() incorrectly resetting held_move_event_ twice
Problem with current code is if RepostEvent() is invoked during dispatch of a reposted event, we incorrectly clear held_move_event_, resulting in dropping the second reposted event. BUG=306935 TEST=covered by test now R=sadrul@chromium.org Review URL: https://codereview.chromium.org/51663002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231846 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/root_window.cc8
-rw-r--r--ui/aura/root_window_unittest.cc59
2 files changed, 62 insertions, 5 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index ebbec87..e79f8ac 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -1109,15 +1109,13 @@ bool RootWindow::DispatchTouchEventImpl(ui::TouchEvent* event) {
void RootWindow::DispatchHeldEvents() {
if (held_repostable_event_) {
if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) {
- ui::MouseEvent mouse_event(
- static_cast<const ui::MouseEvent&>(*held_repostable_event_.get()));
- held_repostable_event_.reset(); // must be reset before dispatch
- DispatchMouseEventRepost(&mouse_event);
+ scoped_ptr<ui::MouseEvent> mouse_event(
+ static_cast<ui::MouseEvent*>(held_repostable_event_.release()));
+ DispatchMouseEventRepost(mouse_event.get());
} else {
// TODO(rbyers): GESTURE_TAP_DOWN not yet supported: crbug.com/170987.
NOTREACHED();
}
- held_repostable_event_.reset();
}
if (held_move_event_ && held_move_event_->IsMouseEvent()) {
// If a mouse move has been synthesized, the target location is suspect,
diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc
index f2cf59b..1c9742d 100644
--- a/ui/aura/root_window_unittest.cc
+++ b/ui/aura/root_window_unittest.cc
@@ -1183,5 +1183,64 @@ TEST_F(RootWindowTest, ValidRootDuringDestruction) {
EXPECT_TRUE(has_valid_root);
}
+namespace {
+
+// See description above DontResetHeldEvent for details.
+class DontResetHeldEventWindowDelegate : public test::TestWindowDelegate {
+ public:
+ explicit DontResetHeldEventWindowDelegate(aura::Window* root)
+ : root_(root),
+ mouse_event_count_(0) {}
+ virtual ~DontResetHeldEventWindowDelegate() {}
+
+ int mouse_event_count() const { return mouse_event_count_; }
+
+ // TestWindowDelegate:
+ virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
+ if ((event->flags() & ui::EF_SHIFT_DOWN) != 0 &&
+ mouse_event_count_++ == 0) {
+ ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED,
+ gfx::Point(10, 10), gfx::Point(10, 10),
+ ui::EF_SHIFT_DOWN);
+ root_->GetDispatcher()->RepostEvent(mouse_event);
+ }
+ }
+
+ private:
+ Window* root_;
+ int mouse_event_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(DontResetHeldEventWindowDelegate);
+};
+
+} // namespace
+
+// Verifies RootWindow doesn't reset |RootWindow::held_repostable_event_| after
+// dispatching. This is done by using DontResetHeldEventWindowDelegate, which
+// tracks the number of events with ui::EF_SHIFT_DOWN set (all reposted events
+// have EF_SHIFT_DOWN). When the first event is seen RepostEvent() is used to
+// schedule another reposted event.
+TEST_F(RootWindowTest, DontResetHeldEvent) {
+ DontResetHeldEventWindowDelegate delegate(root_window());
+ scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), &delegate));
+ RootWindowHostDelegate* root_window_delegate =
+ static_cast<RootWindowHostDelegate*>(root_window()->GetDispatcher());
+ w1->SetBounds(gfx::Rect(0, 0, 40, 40));
+ ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED,
+ gfx::Point(10, 10), gfx::Point(10, 10),
+ ui::EF_SHIFT_DOWN);
+ root_window()->GetDispatcher()->RepostEvent(pressed);
+ ui::MouseEvent pressed2(ui::ET_MOUSE_PRESSED,
+ gfx::Point(10, 10), gfx::Point(10, 10), 0);
+ // Invoke OnHostMouseEvent() to flush event scheduled by way of RepostEvent().
+ root_window_delegate->OnHostMouseEvent(&pressed2);
+ // Delegate should have seen reposted event (identified by way of
+ // EF_SHIFT_DOWN). Invoke OnHostMouseEvent() to flush the second
+ // RepostedEvent().
+ EXPECT_EQ(1, delegate.mouse_event_count());
+ root_window_delegate->OnHostMouseEvent(&pressed2);
+ EXPECT_EQ(2, delegate.mouse_event_count());
+}
+
} // namespace aura