Commit 3f27e0af authored by sadrul@chromium.org's avatar sadrul@chromium.org

linux-aura: Fix some dragging behaviour.

Do a proper X11 grab on capture. This fixes a number of issues, including
dragging a tab out of a tabstrip, and then dragging it back in.

BUG=318020
R=erg@chromium.org

Review URL: https://codereview.chromium.org/110223004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241160 0039d316-1c4b-4281-b951-d872f2087c98
parent 58fbf7a9
......@@ -404,6 +404,8 @@
'widget/desktop_aura/x11_desktop_handler.h',
'widget/desktop_aura/x11_desktop_window_move_client.cc',
'widget/desktop_aura/x11_desktop_window_move_client.h',
'widget/desktop_aura/x11_scoped_capture.cc',
'widget/desktop_aura/x11_scoped_capture.h',
'widget/desktop_aura/x11_whole_screen_move_loop.cc',
'widget/desktop_aura/x11_whole_screen_move_loop.h',
'widget/desktop_aura/x11_whole_screen_move_loop_delegate.h',
......
......@@ -47,6 +47,7 @@
#include "ui/views/widget/desktop_aura/desktop_root_window_host_observer_x11.h"
#include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
#include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h"
#include "ui/views/widget/desktop_aura/x11_scoped_capture.h"
#include "ui/views/widget/desktop_aura/x11_window_event_filter.h"
namespace views {
......@@ -292,6 +293,7 @@ void DesktopRootWindowHostX11::CloseNow() {
if (xwindow_ == None)
return;
x11_capture_.reset();
native_widget_delegate_->OnNativeWidgetDestroying();
// If we have children, close them. Use a copy for iteration because they'll
......@@ -466,6 +468,7 @@ void DesktopRootWindowHostX11::Activate() {
void DesktopRootWindowHostX11::Deactivate() {
// Deactivating a window means activating nothing.
x11_capture_.reset();
X11DesktopHandler::get()->ActivateWindow(None);
}
......@@ -485,6 +488,7 @@ void DesktopRootWindowHostX11::Maximize() {
}
void DesktopRootWindowHostX11::Minimize() {
x11_capture_.reset();
XIconifyWindow(xdisplay_, xwindow_, 0);
}
......@@ -694,8 +698,10 @@ void DesktopRootWindowHostX11::OnNativeWidgetFocus() {
}
void DesktopRootWindowHostX11::OnNativeWidgetBlur() {
if (xwindow_)
if (xwindow_) {
x11_capture_.reset();
native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur();
}
}
bool DesktopRootWindowHostX11::IsAnimatingClosed() const {
......@@ -813,17 +819,11 @@ void DesktopRootWindowHostX11::SetCapture() {
g_current_capture->OnCaptureReleased();
g_current_capture = this;
// TODO(erg): In addition to the above, NativeWidgetGtk performs a full X
// pointer grab when our NativeWidget is of type Menu. However, things work
// without it. Clicking inside a chrome window causes a release capture, and
// clicking outside causes an activation change. Since previous attempts at
// using XPointerGrab() to implement this have locked my X server, I'm going
// to skip this for now.
x11_capture_.reset(new X11ScopedCapture(xwindow_));
}
void DesktopRootWindowHostX11::ReleaseCapture() {
if (g_current_capture)
if (g_current_capture == this)
g_current_capture->OnCaptureReleased();
}
......@@ -1102,6 +1102,7 @@ bool DesktopRootWindowHostX11::HasWMSpecProperty(const char* property) const {
}
void DesktopRootWindowHostX11::OnCaptureReleased() {
x11_capture_.reset();
g_current_capture = NULL;
delegate_->OnHostLostWindowCapture();
native_widget_delegate_->OnMouseCaptureLost();
......
......@@ -31,6 +31,7 @@ class DesktopDragDropClientAuraX11;
class DesktopDispatcherClient;
class DesktopRootWindowHostObserverX11;
class X11DesktopWindowMoveClient;
class X11ScopedCapture;
class X11WindowEventFilter;
class VIEWS_EXPORT DesktopRootWindowHostX11 :
......@@ -281,6 +282,8 @@ private:
// destroyed.
static std::list<XID>* open_windows_;
scoped_ptr<X11ScopedCapture> x11_capture_;
string16 window_title_;
DISALLOW_COPY_AND_ASSIGN(DesktopRootWindowHostX11);
......
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/widget/desktop_aura/x11_scoped_capture.h"
#include <X11/X.h>
#include <X11/Xlib.h>
#include "ui/gfx/x/x11_types.h"
namespace views {
X11ScopedCapture::X11ScopedCapture(XID window)
: captured_(false) {
// TODO(sad): Use XI2 API instead.
unsigned int event_mask = PointerMotionMask | ButtonReleaseMask |
ButtonPressMask;
int status = XGrabPointer(gfx::GetXDisplay(), window, True, event_mask,
GrabModeAsync, GrabModeAsync, None, None,
CurrentTime);
captured_ = status == GrabSuccess;
}
X11ScopedCapture::~X11ScopedCapture() {
if (captured_) {
XUngrabPointer(gfx::GetXDisplay(), CurrentTime);
}
}
} // namespace views
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_X11_SCOPED_CAPTURE_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_X11_SCOPED_CAPTURE_H_
#include "base/basictypes.h"
typedef unsigned long XID;
namespace views {
// Grabs X11 input on a window., i.e. all subsequent mouse events are dispatched
// to the window, while the capture is active.
class X11ScopedCapture {
public:
explicit X11ScopedCapture(XID window);
virtual ~X11ScopedCapture();
private:
bool captured_;
DISALLOW_COPY_AND_ASSIGN(X11ScopedCapture);
};
} // namespace views
#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_X11_SCOPED_CAPTURE_H_
......@@ -50,6 +50,7 @@ X11WholeScreenMoveLoop::X11WholeScreenMoveLoop(
X11WholeScreenMoveLoopDelegate* delegate)
: delegate_(delegate),
in_move_loop_(false),
should_reset_mouse_flags_(false),
grab_input_window_(None) {
}
......@@ -113,7 +114,11 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source,
// We are handling a mouse drag outside of the aura::RootWindow system. We
// must manually make aura think that the mouse button is pressed so that we
// don't draw extraneous tooltips.
aura::Env::GetInstance()->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON);
aura::Env* env = aura::Env::GetInstance();
if (!env->IsMouseButtonDown()) {
env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON);
should_reset_mouse_flags_ = true;
}
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
......@@ -133,7 +138,10 @@ void X11WholeScreenMoveLoop::EndMoveLoop() {
return;
// We undo our emulated mouse click from RunMoveLoop();
aura::Env::GetInstance()->set_mouse_button_flags(0);
if (should_reset_mouse_flags_) {
aura::Env::GetInstance()->set_mouse_button_flags(0);
should_reset_mouse_flags_ = false;
}
// TODO(erg): Is this ungrab the cause of having to click to give input focus
// on drawn out windows? Not ungrabbing here screws the X server until I kill
......
......@@ -62,6 +62,8 @@ class X11WholeScreenMoveLoop : public base::MessageLoop::Dispatcher {
// Are we running a nested message loop from RunMoveLoop()?
bool in_move_loop_;
bool should_reset_mouse_flags_;
// An invisible InputOnly window . We create this window so we can track the
// cursor wherever it goes on screen during a drag, since normal windows
// don't receive pointer motion events outside of their bounds.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment