diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 16:33:54 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 16:33:54 +0000 |
commit | a99329d8f691d5dbf8e1ea78cc3a91413a9b3df2 (patch) | |
tree | efb63253a060b209d97a87ee86345c71314b8621 /ui | |
parent | cef6c76ff40bf74edbcf8df0a19dc0c08fb7daca (diff) | |
download | chromium_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.cc | 8 | ||||
-rw-r--r-- | ui/aura/root_window_unittest.cc | 59 |
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 |