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

Side by Side Diff: ui/views/widget/x11_desktop_window_move_client.cc

Issue 11369220: Move the desktop aura classes into a desktop subdir to make the gyp simpler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/x11_desktop_window_move_client.h"
6
7 #include <X11/Xlib.h>
8 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
9 #undef RootWindow
10
11 #include "base/debug/stack_trace.h"
12 #include "base/message_loop.h"
13 #include "base/message_pump_aurax11.h"
14 #include "base/run_loop.h"
15 #include "ui/aura/env.h"
16 #include "ui/aura/root_window.h"
17 #include "ui/base/events/event.h"
18 #include "ui/base/x/x11_util.h"
19 #include "ui/gfx/screen.h"
20
21 namespace views {
22
23 X11DesktopWindowMoveClient::X11DesktopWindowMoveClient()
24 : in_move_loop_(false),
25 grab_input_window_(None),
26 root_window_(NULL) {
27 }
28
29 X11DesktopWindowMoveClient::~X11DesktopWindowMoveClient() {}
30
31 ////////////////////////////////////////////////////////////////////////////////
32 // DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation:
33
34 bool X11DesktopWindowMoveClient::Dispatch(const base::NativeEvent& event) {
35 XEvent* xev = event;
36
37 // Note: the escape key is handled in the tab drag controller, which has
38 // keyboard focus even though we took pointer grab.
39 switch (xev->type) {
40 case MotionNotify: {
41 gfx::Point cursor_point(xev->xmotion.x_root, xev->xmotion.y_root);
42 gfx::Point system_loc = cursor_point - window_offset_;
43 root_window_->SetHostBounds(gfx::Rect(
44 system_loc, root_window_->GetHostSize()));
45 break;
46 }
47 case ButtonPress:
48 case ButtonRelease: {
49 EndMoveLoop();
50 break;
51 }
52 }
53
54 return true;
55 }
56
57 ////////////////////////////////////////////////////////////////////////////////
58 // DesktopRootWindowHostLinux, aura::client::WindowMoveClient implementation:
59
60 aura::client::WindowMoveResult X11DesktopWindowMoveClient::RunMoveLoop(
61 aura::Window* source,
62 const gfx::Vector2d& drag_offset) {
63 DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
64 in_move_loop_ = true;
65 window_offset_ = drag_offset;
66
67 root_window_ = source->GetRootWindow();
68
69 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
70
71 // Creates an invisible, InputOnly toplevel window. This window will receive
72 // all mouse movement for drags. It turns out that normal windows doing a
73 // grab doesn't redirect pointer motion events if the pointer isn't over the
74 // grabbing window. But InputOnly windows are able to grab everything. This
75 // is what GTK+ does, and I found a patch to KDE that did something similar.
76 unsigned long attribute_mask = CWEventMask | CWOverrideRedirect;
77 XSetWindowAttributes swa;
78 memset(&swa, 0, sizeof(swa));
79 swa.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
80 StructureNotifyMask;
81 swa.override_redirect = True;
82 grab_input_window_ = XCreateWindow(
83 display,
84 DefaultRootWindow(display),
85 -100, -100, 10, 10,
86 0, 0, InputOnly, CopyFromParent,
87 attribute_mask, &swa);
88 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(
89 this, grab_input_window_);
90
91 // Wait for the window to be mapped. If we don't, XGrabPointer fails.
92 XMapRaised(display, grab_input_window_);
93 base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(
94 grab_input_window_);
95
96 XGrabServer(display);
97 XUngrabPointer(display, CurrentTime);
98 int ret = XGrabPointer(
99 display,
100 grab_input_window_,
101 False,
102 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
103 GrabModeAsync,
104 GrabModeAsync,
105 None,
106 None,
107 CurrentTime);
108 XUngrabServer(display);
109 if (ret != GrabSuccess) {
110 DLOG(ERROR) << "Grabbing new tab for dragging failed: "
111 << ui::GetX11ErrorString(display, ret);
112 return aura::client::MOVE_CANCELED;
113 }
114
115 MessageLoopForUI* loop = MessageLoopForUI::current();
116 MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
117 base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
118 quit_closure_ = run_loop.QuitClosure();
119 run_loop.Run();
120 return aura::client::MOVE_SUCCESSFUL;
121 }
122
123 void X11DesktopWindowMoveClient::EndMoveLoop() {
124 if (!in_move_loop_)
125 return;
126
127 // TODO(erg): Is this ungrab the cause of having to click to give input focus
128 // on drawn out windows? Not ungrabbing here screws the X server until I kill
129 // the chrome process.
130
131 // Ungrab before we let go of the window.
132 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
133 XUngrabPointer(display, CurrentTime);
134
135 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(
136 grab_input_window_);
137 root_window_ = NULL;
138 XDestroyWindow(display, grab_input_window_);
139
140 in_move_loop_ = false;
141 quit_closure_.Run();
142 }
143
144 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/x11_desktop_window_move_client.h ('k') | ui/views/widget/x11_window_event_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698