Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: ui/views/widget/desktop_aura/x11_desktop_window_move_client_managed.cc

Issue 2410773002: Linux Aura: Use managed tab dragging when possible (Reland)
Patch Set: use POST_DISPATCH_NONE Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client_managed.h"
6
7 #include <X11/extensions/XInput2.h>
8 #include <X11/Xlib.h>
9
10 #include "base/run_loop.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_tree_host.h"
13 #include "ui/base/x/x11_util.h"
14 #include "ui/events/event_utils.h"
15 #include "ui/events/platform/platform_event_source.h"
16 #include "ui/events/platform/scoped_event_dispatcher.h"
17 #include "ui/views/widget/desktop_aura/x11_pointer_grab.h"
18
19 namespace views {
20
21 namespace {
22
23 bool IsButtonReleaseEvent(XEvent* xev) {
24 if (xev->type == ButtonRelease)
25 return xev->xbutton.button == Button1;
26 if (xev->type == GenericEvent) {
27 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
28 if (xievent->evtype == XI_RawButtonRelease)
29 return ui::EventButtonFromNative(xev) == Button1;
30 }
31 return false;
32 }
33
34 void SelectButtonReleaseEvents(bool select) {
35 unsigned char mask[XIMaskLen(XI_LASTEVENT)];
36 memset(mask, 0, sizeof(mask));
37 if (select)
38 XISetMask(mask, XI_RawButtonRelease);
39 XIEventMask evmask;
40 evmask.deviceid = XIAllMasterDevices;
41 evmask.mask_len = sizeof(mask);
42 evmask.mask = mask;
43 XDisplay* display = gfx::GetXDisplay();
44 XISelectEvents(display, DefaultRootWindow(display), &evmask, 1);
45 }
46
47 } // anonymous namespace
48
49 X11DesktopWindowMoveClientManaged::X11DesktopWindowMoveClientManaged()
50 : weak_factory_(this) {}
51 X11DesktopWindowMoveClientManaged::~X11DesktopWindowMoveClientManaged() {}
52
53 bool X11DesktopWindowMoveClientManaged::CanDispatchEvent(
54 const ui::PlatformEvent& event) {
55 return in_move_loop_;
56 }
57
58 uint32_t X11DesktopWindowMoveClientManaged::DispatchEvent(
59 const ui::PlatformEvent& event) {
60 DCHECK(base::MessageLoopForUI::IsCurrent());
61
62 XEvent* xev = event;
63
64 // This method processes all events while the move loop is active.
65 if (!in_move_loop_)
66 return ui::POST_DISPATCH_PERFORM_DEFAULT;
67
68 if (IsButtonReleaseEvent(xev)) {
69 EndMoveLoop();
70 return ui::POST_DISPATCH_NONE;
71 }
72 return ui::POST_DISPATCH_PERFORM_DEFAULT;
73 }
74
75 aura::client::WindowMoveResult X11DesktopWindowMoveClientManaged::RunMoveLoop(
76 aura::Window* window,
77 const gfx::Vector2d& drag_offset,
78 aura::client::WindowMoveSource move_source) {
79 auto screen_location = window->GetBoundsInScreen().origin() + drag_offset;
80 window_ = window->GetHost()->GetAcceleratedWidget();
81
82 SelectButtonReleaseEvents(true);
83
84 window->ReleaseCapture();
85 UngrabPointer();
86 MoveResizeManagedWindow(window_, screen_location, ui::NetWmMoveResize::MOVE);
87
88 std::unique_ptr<ui::ScopedEventDispatcher> old_dispatcher =
89 std::move(nested_dispatcher_);
90 nested_dispatcher_ =
91 ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
92
93 base::WeakPtr<X11DesktopWindowMoveClientManaged> alive(
94 weak_factory_.GetWeakPtr());
95
96 in_move_loop_ = true;
97 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
98 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
99 base::RunLoop run_loop;
100 quit_closure_ = run_loop.QuitClosure();
101 run_loop.Run();
102
103 if (!alive)
104 return aura::client::MOVE_CANCELED;
105
106 nested_dispatcher_ = std::move(old_dispatcher);
107 return aura::client::MOVE_SUCCESSFUL;
108 }
109
110 void X11DesktopWindowMoveClientManaged::EndMoveLoop() {
111 if (!in_move_loop_)
112 return;
113
114 MoveResizeManagedWindow(window_, gfx::Point(), ui::NetWmMoveResize::CANCEL);
115 SelectButtonReleaseEvents(false);
116
117 quit_closure_.Run();
118 }
119
120 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698