Chromium Code Reviews| 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 e465174db814c72bdaa0f88dbd3bebd67aff6418..6cddd6146624bc45e6a966c0f78392224ae57bb1 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 |
| @@ -4,6 +4,7 @@ |
| #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h" |
| +#include <X11/extensions/XInput2.h> |
| #include <X11/Xlib.h> |
| // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. |
| #undef RootWindow |
| @@ -18,11 +19,13 @@ |
| #include "ui/aura/window_tree_host.h" |
| #include "ui/base/x/x11_util.h" |
| #include "ui/events/event.h" |
| +#include "ui/events/event_utils.h" |
| #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| #include "ui/events/platform/x11/x11_event_source.h" |
| #include "ui/gfx/point_conversions.h" |
| #include "ui/gfx/screen.h" |
| #include "ui/views/controls/image_view.h" |
| +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
| #include "ui/views/widget/widget.h" |
| namespace views { |
| @@ -79,16 +82,19 @@ void X11WholeScreenMoveLoop::DispatchMouseMovement() { |
| // DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation: |
| bool X11WholeScreenMoveLoop::CanDispatchEvent(const ui::PlatformEvent& event) { |
| - return event->xany.window == grab_input_window_; |
| + return in_move_loop_; |
| } |
| uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) { |
| + if (!in_move_loop_) |
| + return ui::POST_DISPATCH_PERFORM_DEFAULT; |
| XEvent* xev = event; |
| // Note: the escape key is handled in the tab drag controller, which has |
| // keyboard focus even though we took pointer grab. |
| switch (xev->type) { |
| case MotionNotify: { |
| + LOG(INFO) << "MotionNotify in " << grab_input_window_; |
| if (drag_widget_.get()) { |
| gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| gfx::Point location = gfx::ToFlooredPoint( |
| @@ -106,27 +112,61 @@ uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) { |
| base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, |
| weak_factory_.GetWeakPtr())); |
| } |
| - break; |
| + return ui::POST_DISPATCH_NONE; |
| } |
| case ButtonRelease: { |
| if (xev->xbutton.button == Button1) { |
| + LOG(INFO) << "Release in " << grab_input_window_; |
| // 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; |
| + return ui::POST_DISPATCH_NONE; |
| } |
| case KeyPress: { |
| if (ui::KeyboardCodeFromXKeyEvent(xev) == ui::VKEY_ESCAPE) { |
| canceled_ = true; |
| EndMoveLoop(); |
| + return ui::POST_DISPATCH_NONE; |
| } |
| break; |
| } |
| + case GenericEvent: { |
| + ui::EventType type = ui::EventTypeFromNative(xev); |
| + switch (type) { |
| + case ui::ET_MOUSE_MOVED: |
| + case ui::ET_MOUSE_DRAGGED: |
| + case ui::ET_MOUSE_RELEASED: { |
| + LOG(INFO) << "XI event " << type << " in " << grab_input_window_; |
| + XEvent xevent = {0}; |
| + if (type == ui::ET_MOUSE_RELEASED) { |
| + xevent.type = ButtonRelease; |
| + xevent.xbutton.button = ui::EventButtonFromNative(xev); |
| + } else { |
| + xevent.type = MotionNotify; |
| + } |
| + xevent.xany.display = xev->xgeneric.display; |
| + xevent.xany.window = grab_input_window_; |
| + // The fields used below are in the same place for all of events |
| + // above. Using xmotion from XEvent's unions to avoid repeating |
| + // the code. |
| + xevent.xmotion.root = DefaultRootWindow(xev->xgeneric.display); |
| + xevent.xmotion.time = ui::EventTimeFromNative(xev).InMilliseconds(); |
| + gfx::Point point(ui::EventSystemLocationFromNative(xev)); |
| + xevent.xmotion.x_root = point.x(); |
| + xevent.xmotion.y_root = point.y(); |
| + DispatchEvent(&xevent); |
|
sadrul
2014/04/25 17:19:50
It would be really great if we didn't have to recr
varkha
2014/04/25 18:00:35
We talked about this offline. I think it would be
|
| + return ui::POST_DISPATCH_NONE; |
| + } |
| + default: |
| + break; |
| + } |
| + } |
| } |
| - return ui::POST_DISPATCH_STOP_PROPAGATION; |
| + return (event->xany.window == grab_input_window_) ? |
| + ui::POST_DISPATCH_NONE : ui::POST_DISPATCH_PERFORM_DEFAULT; |
| } |
| bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, |
| @@ -154,7 +194,10 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, |
| return false; |
| } |
| - ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
| + scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = |
| + nested_dispatcher_.Pass(); |
| + nested_dispatcher_ = |
| + ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this); |
| if (!drag_image_.isNull() && CheckIfIconValid()) |
| CreateDragImageWindow(); |
| @@ -174,6 +217,7 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, |
| base::RunLoop run_loop; |
| quit_closure_ = run_loop.QuitClosure(); |
| run_loop.Run(); |
| + nested_dispatcher_ = old_dispatcher.Pass(); |
| return !canceled_; |
| } |
| @@ -209,10 +253,13 @@ void X11WholeScreenMoveLoop::EndMoveLoop() { |
| XUngrabPointer(display, CurrentTime); |
| XUngrabKeyboard(display, CurrentTime); |
| - ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
| + LOG(INFO) << "Ungrab"; |
| drag_widget_.reset(); |
| delegate_->OnMoveLoopEnded(); |
| XDestroyWindow(display, grab_input_window_); |
| + grab_input_window_ = None; |
| + // Restore the previous dispatcher. |
| + nested_dispatcher_.reset(); |
| in_move_loop_ = false; |
| quit_closure_.Run(); |
| @@ -232,6 +279,8 @@ bool X11WholeScreenMoveLoop::GrabPointerAndKeyboard(gfx::NativeCursor cursor) { |
| XGrabServer(display); |
| XUngrabPointer(display, CurrentTime); |
| + LOG(INFO) << "Ungrab"; |
| + |
| int ret = XGrabPointer( |
| display, |
| grab_input_window_, |
| @@ -259,6 +308,7 @@ bool X11WholeScreenMoveLoop::GrabPointerAndKeyboard(gfx::NativeCursor cursor) { |
| << ui::GetX11ErrorString(display, ret); |
| } |
| } |
| + LOG(INFO) << "Grab " << grab_input_window_; |
| XUngrabServer(display); |
| return ret == GrabSuccess; |