diff options
author | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 12:59:45 +0000 |
---|---|---|
committer | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 12:59:45 +0000 |
commit | c30087a9ff585bb38f6287856a0d86725d052d03 (patch) | |
tree | 4873397810654fe08dde5aca604e43ee18be1147 | |
parent | b4d7eb8fc343b744d36ebc984b8c61a9f25f6975 (diff) | |
download | chromium_src-c30087a9ff585bb38f6287856a0d86725d052d03.zip chromium_src-c30087a9ff585bb38f6287856a0d86725d052d03.tar.gz chromium_src-c30087a9ff585bb38f6287856a0d86725d052d03.tar.bz2 |
Avoids releasing pointer grab prematurely
BUG=338247
TEST=
1.Launch chrome://settings..ctrl+D,save the Bookmark in Bookmark Bar.
2.Open 3 to 4 new Tabs via ctrl+T,in chrome://settings page Drag the Bookmark from the Bookmark Bar.
3.Hover the Dragged Bookmark over the second New-Tab and Release the Bookmark over the New-Tab.
4.Hover the Dragged Bookmark over the third New-Tab (the tab gets activated) and Release the Bookmark over the New-Tab.
5.Close browser - should not crash.
Review URL: https://codereview.chromium.org/140663013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252201 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc index 2b65c2a..9f15291 100644 --- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc +++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc @@ -94,20 +94,30 @@ uint32_t X11WholeScreenMoveLoop::Dispatch(const base::NativeEvent& event) { bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, gfx::NativeCursor cursor) { // Start a capture on the host, so that it continues to receive events during - // the drag. - ScopedCapturer capturer(source->GetDispatcher()->host()); - - DCHECK(!in_move_loop_); // Can only handle one nested loop at a time. - in_move_loop_ = true; - - XDisplay* display = gfx::GetXDisplay(); - - grab_input_window_ = CreateDragInputWindow(display); - if (!drag_image_.isNull()) - CreateDragImageWindow(); - base::MessagePumpX11::Current()->AddDispatcherForWindow( - this, grab_input_window_); - + // the drag. This may be second time we are capturing the mouse events - the + // first being when a mouse is first pressed. That first capture needs to be + // released before the call to GrabPointerWithCursor below, otherwise it may + // get released while we still need the pointer grab, which is why we restrict + // the scope here. + { + ScopedCapturer capturer(source->GetDispatcher()->host()); + + DCHECK(!in_move_loop_); // Can only handle one nested loop at a time. + in_move_loop_ = true; + + XDisplay* display = gfx::GetXDisplay(); + + grab_input_window_ = CreateDragInputWindow(display); + if (!drag_image_.isNull()) + CreateDragImageWindow(); + base::MessagePumpX11::Current()->AddDispatcherForWindow( + this, grab_input_window_); + // Releasing ScopedCapturer ensures that any other instance of + // X11ScopedCapture will not prematurely release grab that will be acquired + // below. + } + // TODO(varkha): Consider integrating GrabPointerWithCursor with + // ScopedCapturer to avoid possibility of logically keeping multiple grabs. if (!GrabPointerWithCursor(cursor)) return false; |