Index: ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc |
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 9cd9fd4a3cf5c601c6ba8e0442e8fd4369e77269..09e36dcae7586f279c222530862e7412a1968138 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 |
@@ -8,6 +8,7 @@ |
// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. |
#undef RootWindow |
+#include "base/bind.h" |
#include "base/message_loop/message_loop.h" |
#include "base/message_loop/message_pump_x11.h" |
#include "base/run_loop.h" |
@@ -57,7 +58,9 @@ X11WholeScreenMoveLoop::X11WholeScreenMoveLoop( |
: delegate_(delegate), |
in_move_loop_(false), |
should_reset_mouse_flags_(false), |
- grab_input_window_(None) { |
+ grab_input_window_(None), |
+ weak_factory_(this) { |
+ last_xmotion_.type = LASTEvent; |
} |
X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} |
@@ -65,6 +68,15 @@ X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} |
//////////////////////////////////////////////////////////////////////////////// |
// DesktopWindowTreeHostLinux, MessagePumpDispatcher implementation: |
+void X11WholeScreenMoveLoop::DispatchMouseMovement() { |
+ if (!weak_factory_.HasWeakPtrs()) |
+ return; |
+ weak_factory_.InvalidateWeakPtrs(); |
+ DCHECK_EQ(MotionNotify, last_xmotion_.type); |
+ delegate_->OnMouseMovement(&last_xmotion_); |
+ last_xmotion_.type = LASTEvent; |
+} |
+ |
uint32_t X11WholeScreenMoveLoop::Dispatch(const base::NativeEvent& event) { |
XEvent* xev = event; |
@@ -79,13 +91,23 @@ uint32_t X11WholeScreenMoveLoop::Dispatch(const base::NativeEvent& event) { |
drag_widget_->SetBounds(gfx::Rect(location, drag_image_.size())); |
drag_widget_->StackAtTop(); |
} |
- delegate_->OnMouseMovement(&xev->xmotion); |
+ last_xmotion_ = xev->xmotion; |
+ if (!weak_factory_.HasWeakPtrs()) { |
+ // Post a task to dispatch mouse movement event when control returns to |
+ // the message loop. This allows smoother dragging since the events are |
+ // dispatched without waiting for the drag widget updates. |
+ base::MessageLoopForUI::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, |
+ weak_factory_.GetWeakPtr())); |
+ } |
break; |
} |
case ButtonRelease: { |
if (xev->xbutton.button == Button1) { |
// Assume that drags are being done with the left mouse button. Only |
// break the drag if the left mouse button was released. |
+ DispatchMouseMovement(); |
delegate_->OnMouseReleased(); |
} |
break; |
@@ -163,6 +185,10 @@ void X11WholeScreenMoveLoop::EndMoveLoop() { |
if (!in_move_loop_) |
return; |
+ // Prevent DispatchMouseMovement from dispatching any posted motion event. |
+ weak_factory_.InvalidateWeakPtrs(); |
+ last_xmotion_.type = LASTEvent; |
+ |
// We undo our emulated mouse click from RunMoveLoop(); |
if (should_reset_mouse_flags_) { |
aura::Env::GetInstance()->set_mouse_button_flags(0); |