summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-20 12:59:45 +0000
committervarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-20 12:59:45 +0000
commitc30087a9ff585bb38f6287856a0d86725d052d03 (patch)
tree4873397810654fe08dde5aca604e43ee18be1147
parentb4d7eb8fc343b744d36ebc984b8c61a9f25f6975 (diff)
downloadchromium_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.cc38
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;