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

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

Issue 455553003: Do not release capture when starting a move loop on Desktop Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h" 5 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "ui/aura/client/capture_client.h"
12 #include "ui/aura/env.h" 13 #include "ui/aura/env.h"
13 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
14 #include "ui/aura/window_event_dispatcher.h" 15 #include "ui/aura/window_event_dispatcher.h"
15 #include "ui/aura/window_tree_host.h" 16 #include "ui/aura/window_tree_host.h"
16 #include "ui/base/x/x11_util.h" 17 #include "ui/base/x/x11_util.h"
17 #include "ui/events/event.h" 18 #include "ui/events/event.h"
18 #include "ui/events/event_utils.h" 19 #include "ui/events/event_utils.h"
19 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 20 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
20 #include "ui/events/platform/scoped_event_dispatcher.h" 21 #include "ui/events/platform/scoped_event_dispatcher.h"
21 #include "ui/events/platform/x11/x11_event_source.h" 22 #include "ui/events/platform/x11/x11_event_source.h"
22 #include "ui/gfx/point_conversions.h"
23 23
24 namespace views { 24 namespace views {
25 25
26 namespace {
27
28 class ScopedCapturer {
29 public:
30 explicit ScopedCapturer(aura::WindowTreeHost* host)
31 : host_(host) {
32 host_->SetCapture();
33 }
34
35 ~ScopedCapturer() {
36 host_->ReleaseCapture();
37 }
38
39 private:
40 aura::WindowTreeHost* host_;
41
42 DISALLOW_COPY_AND_ASSIGN(ScopedCapturer);
43 };
44
45 } // namespace
46
47 X11WholeScreenMoveLoop::X11WholeScreenMoveLoop(X11MoveLoopDelegate* delegate) 26 X11WholeScreenMoveLoop::X11WholeScreenMoveLoop(X11MoveLoopDelegate* delegate)
48 : delegate_(delegate), 27 : delegate_(delegate),
49 in_move_loop_(false), 28 in_move_loop_(false),
29 initial_cursor_(ui::kCursorNull),
50 should_reset_mouse_flags_(false), 30 should_reset_mouse_flags_(false),
51 grab_input_window_(None), 31 grab_input_window_(None),
32 grabbed_pointer_(false),
52 canceled_(false), 33 canceled_(false),
53 has_grab_(false),
54 weak_factory_(this) { 34 weak_factory_(this) {
55 last_xmotion_.type = LASTEvent; 35 last_xmotion_.type = LASTEvent;
56 } 36 }
57 37
58 X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} 38 X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {}
59 39
60 void X11WholeScreenMoveLoop::DispatchMouseMovement() { 40 void X11WholeScreenMoveLoop::DispatchMouseMovement() {
61 if (!weak_factory_.HasWeakPtrs()) 41 if (!weak_factory_.HasWeakPtrs())
62 return; 42 return;
63 weak_factory_.InvalidateWeakPtrs(); 43 weak_factory_.InvalidateWeakPtrs();
64 DCHECK_EQ(MotionNotify, last_xmotion_.type); 44 DCHECK_EQ(MotionNotify, last_xmotion_.type);
65 delegate_->OnMouseMovement(&last_xmotion_); 45 delegate_->OnMouseMovement(&last_xmotion_);
66 last_xmotion_.type = LASTEvent; 46 last_xmotion_.type = LASTEvent;
67 } 47 }
68 48
69 //////////////////////////////////////////////////////////////////////////////// 49 ////////////////////////////////////////////////////////////////////////////////
70 // DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation: 50 // DesktopWindowTreeHostLinux, ui::PlatformEventDispatcher implementation:
71 51
72 bool X11WholeScreenMoveLoop::CanDispatchEvent(const ui::PlatformEvent& event) { 52 bool X11WholeScreenMoveLoop::CanDispatchEvent(const ui::PlatformEvent& event) {
73 return in_move_loop_; 53 return in_move_loop_;
74 } 54 }
75 55
76 uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) { 56 uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) {
77 // This method processes all events for the grab_input_window_ as well as 57 // This method processes all events while the move loop is active.
78 // mouse events for all windows while the move loop is active - even before
79 // the grab is granted by X. This allows mouse notification events that were
80 // sent after the capture was requested but before the capture was granted
81 // to be dispatched. It is especially important to process the mouse release
82 // event that should have stopped the drag even if that mouse release happened
83 // before the grab was granted.
84 if (!in_move_loop_) 58 if (!in_move_loop_)
85 return ui::POST_DISPATCH_PERFORM_DEFAULT; 59 return ui::POST_DISPATCH_PERFORM_DEFAULT;
60
86 XEvent* xev = event; 61 XEvent* xev = event;
87
88 // Note: the escape key is handled in the tab drag controller, which has
89 // keyboard focus even though we took pointer grab.
90 switch (xev->type) { 62 switch (xev->type) {
91 case MotionNotify: { 63 case MotionNotify: {
92 last_xmotion_ = xev->xmotion; 64 last_xmotion_ = xev->xmotion;
93 if (!weak_factory_.HasWeakPtrs()) { 65 if (!weak_factory_.HasWeakPtrs()) {
94 // Post a task to dispatch mouse movement event when control returns to 66 // Post a task to dispatch mouse movement event when control returns to
95 // the message loop. This allows smoother dragging since the events are 67 // the message loop. This allows smoother dragging since the events are
96 // dispatched without waiting for the drag widget updates. 68 // dispatched without waiting for the drag widget updates.
97 base::MessageLoopForUI::current()->PostTask( 69 base::MessageLoopForUI::current()->PostTask(
98 FROM_HERE, 70 FROM_HERE,
99 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement, 71 base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement,
100 weak_factory_.GetWeakPtr())); 72 weak_factory_.GetWeakPtr()));
101 } 73 }
102 return ui::POST_DISPATCH_NONE; 74 return ui::POST_DISPATCH_NONE;
103 } 75 }
104 case ButtonRelease: { 76 case ButtonRelease: {
105 if (xev->xbutton.button == Button1) { 77 if (xev->xbutton.button == Button1) {
106 // Assume that drags are being done with the left mouse button. Only 78 // Assume that drags are being done with the left mouse button. Only
107 // break the drag if the left mouse button was released. 79 // break the drag if the left mouse button was released.
108 DispatchMouseMovement(); 80 DispatchMouseMovement();
109 delegate_->OnMouseReleased(); 81 delegate_->OnMouseReleased();
82
83 if (!grabbed_pointer_) {
84 // If the source widget had capture prior to the move loop starting,
85 // it may be relying on views::Widget getting the mouse release and
86 // releasing capture in Widget::OnMouseEvent().
87 return ui::POST_DISPATCH_PERFORM_DEFAULT;
pkotwicz 2014/08/10 18:58:49 I want to look into whether we can stop the propag
88 }
110 } 89 }
111 return ui::POST_DISPATCH_NONE; 90 return ui::POST_DISPATCH_NONE;
112 } 91 }
113 case KeyPress: { 92 case KeyPress: {
114 if (ui::KeyboardCodeFromXKeyEvent(xev) == ui::VKEY_ESCAPE) { 93 if (ui::KeyboardCodeFromXKeyEvent(xev) == ui::VKEY_ESCAPE) {
115 canceled_ = true; 94 canceled_ = true;
116 EndMoveLoop(); 95 EndMoveLoop();
117 return ui::POST_DISPATCH_NONE; 96 return ui::POST_DISPATCH_NONE;
118 } 97 }
119 break; 98 break;
120 } 99 }
121 case FocusOut: {
122 if (xev->xfocus.mode != NotifyGrab)
123 has_grab_ = false;
124 break;
125 }
126 case GenericEvent: { 100 case GenericEvent: {
127 ui::EventType type = ui::EventTypeFromNative(xev); 101 ui::EventType type = ui::EventTypeFromNative(xev);
128 switch (type) { 102 switch (type) {
129 case ui::ET_MOUSE_MOVED: 103 case ui::ET_MOUSE_MOVED:
130 case ui::ET_MOUSE_DRAGGED: 104 case ui::ET_MOUSE_DRAGGED:
131 case ui::ET_MOUSE_RELEASED: { 105 case ui::ET_MOUSE_RELEASED: {
132 XEvent xevent = {0}; 106 XEvent xevent = {0};
133 if (type == ui::ET_MOUSE_RELEASED) { 107 if (type == ui::ET_MOUSE_RELEASED) {
134 xevent.type = ButtonRelease; 108 xevent.type = ButtonRelease;
135 xevent.xbutton.button = ui::EventButtonFromNative(xev); 109 xevent.xbutton.button = ui::EventButtonFromNative(xev);
136 } else { 110 } else {
137 xevent.type = MotionNotify; 111 xevent.type = MotionNotify;
138 } 112 }
139 xevent.xany.display = xev->xgeneric.display; 113 xevent.xany.display = xev->xgeneric.display;
140 xevent.xany.window = grab_input_window_; 114 xevent.xany.window = grab_input_window_;
141 // The fields used below are in the same place for all of events 115 // The fields used below are in the same place for all of events
142 // above. Using xmotion from XEvent's unions to avoid repeating 116 // above. Using xmotion from XEvent's unions to avoid repeating
143 // the code. 117 // the code.
144 xevent.xmotion.root = DefaultRootWindow(xev->xgeneric.display); 118 xevent.xmotion.root = DefaultRootWindow(xev->xgeneric.display);
145 xevent.xmotion.time = ui::EventTimeFromNative(xev).InMilliseconds(); 119 xevent.xmotion.time = ui::EventTimeFromNative(xev).InMilliseconds();
146 gfx::Point point(ui::EventSystemLocationFromNative(xev)); 120 gfx::Point point(ui::EventSystemLocationFromNative(xev));
147 xevent.xmotion.x_root = point.x(); 121 xevent.xmotion.x_root = point.x();
148 xevent.xmotion.y_root = point.y(); 122 xevent.xmotion.y_root = point.y();
149 DispatchEvent(&xevent); 123 return DispatchEvent(&xevent);
150 return ui::POST_DISPATCH_NONE;
151 } 124 }
152 default: 125 default:
153 break; 126 break;
154 } 127 }
155 } 128 }
156 } 129 }
157 130
158 return (event->xany.window == grab_input_window_) ? 131 return ui::POST_DISPATCH_PERFORM_DEFAULT;
159 ui::POST_DISPATCH_NONE : ui::POST_DISPATCH_PERFORM_DEFAULT;
160 } 132 }
161 133
162 bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, 134 bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source,
163 gfx::NativeCursor cursor) { 135 gfx::NativeCursor cursor) {
164 DCHECK(!in_move_loop_); // Can only handle one nested loop at a time. 136 DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
165 137
166 // Start a capture on the host, so that it continues to receive events during 138 // Query the mouse cursor prior to the move loop starting so that it can be
167 // the drag. This may be second time we are capturing the mouse events - the 139 // restored when the move loop finishes.
168 // first being when a mouse is first pressed. That first capture needs to be 140 initial_cursor_ = source->GetHost()->last_cursor();
169 // released before the call to GrabPointerAndKeyboard below, otherwise it may
170 // get released while we still need the pointer grab, which is why we restrict
171 // the scope here.
172 {
173 ScopedCapturer capturer(source->GetHost());
174 141
175 grab_input_window_ = CreateDragInputWindow(gfx::GetXDisplay()); 142 grab_input_window_ = CreateDragInputWindow(gfx::GetXDisplay());
176 // Releasing ScopedCapturer ensures that any other instance of 143
177 // X11ScopedCapture will not prematurely release grab that will be acquired 144 // Only grab mouse capture of |grab_input_window_| if |source| does not have
178 // below. 145 // capture.
146 // - The caller may intend to transfer capture to a different aura::Window
147 // when the move loop ends and not release capture.
148 // - Releasing capture and X window destruction are both asynchronous. We drop
149 // events targeted at |grab_input_window_| in the time between the move
150 // loop ends and |grab_input_window_| loses capture.
151 grabbed_pointer_ = false;
152 if (!source->HasCapture()) {
153 aura::client::CaptureClient* capture_client =
154 aura::client::GetCaptureClient(source->GetRootWindow());
155 CHECK(capture_client->GetGlobalCaptureWindow() == NULL);
156 grabbed_pointer_ = GrabPointer(cursor);
157 if (!grabbed_pointer_) {
158 XDestroyWindow(gfx::GetXDisplay(), grab_input_window_);
159 return false;
160 }
179 } 161 }
180 // TODO(varkha): Consider integrating GrabPointerAndKeyboard with 162
181 // ScopedCapturer to avoid possibility of logically keeping multiple grabs. 163 if (!GrabKeyboard()) {
182 if (!GrabPointerAndKeyboard(cursor)) {
183 XDestroyWindow(gfx::GetXDisplay(), grab_input_window_); 164 XDestroyWindow(gfx::GetXDisplay(), grab_input_window_);
184 return false; 165 return false;
185 } 166 }
186 167
187 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = 168 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher =
188 nested_dispatcher_.Pass(); 169 nested_dispatcher_.Pass();
189 nested_dispatcher_ = 170 nested_dispatcher_ =
190 ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this); 171 ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
191 172
192 // We are handling a mouse drag outside of the aura::RootWindow system. We 173 // We are handling a mouse drag outside of the aura::Window system. We must
193 // must manually make aura think that the mouse button is pressed so that we 174 // manually make aura think that the mouse button is pressed so that we don't
194 // don't draw extraneous tooltips. 175 // draw extraneous tooltips.
195 aura::Env* env = aura::Env::GetInstance(); 176 aura::Env* env = aura::Env::GetInstance();
196 if (!env->IsMouseButtonDown()) { 177 if (!env->IsMouseButtonDown()) {
197 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON); 178 env->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON);
198 should_reset_mouse_flags_ = true; 179 should_reset_mouse_flags_ = true;
199 } 180 }
200 181
201 in_move_loop_ = true; 182 in_move_loop_ = true;
202 canceled_ = false; 183 canceled_ = false;
203 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); 184 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
204 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); 185 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
205 base::RunLoop run_loop; 186 base::RunLoop run_loop;
206 quit_closure_ = run_loop.QuitClosure(); 187 quit_closure_ = run_loop.QuitClosure();
207 run_loop.Run(); 188 run_loop.Run();
208 nested_dispatcher_ = old_dispatcher.Pass(); 189 nested_dispatcher_ = old_dispatcher.Pass();
209 return !canceled_; 190 return !canceled_;
210 } 191 }
211 192
212 void X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) { 193 void X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) {
213 if (in_move_loop_) { 194 if (in_move_loop_) {
214 // If we're still in the move loop, regrab the pointer with the updated 195 // We cannot call GrabPointer() because we do not want to change the
215 // cursor. Note: we can be called from handling an XdndStatus message after 196 // "owner_events" property of the active pointer grab.
216 // EndMoveLoop() was called, but before we return from the nested RunLoop. 197 XChangeActivePointerGrab(
217 GrabPointerAndKeyboard(cursor); 198 gfx::GetXDisplay(),
pkotwicz 2014/08/10 18:58:49 This comment sounds like a description of the "own
199 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
200 cursor.platform(),
201 CurrentTime);
218 } 202 }
219 } 203 }
220 204
221 void X11WholeScreenMoveLoop::EndMoveLoop() { 205 void X11WholeScreenMoveLoop::EndMoveLoop() {
222 if (!in_move_loop_) 206 if (!in_move_loop_)
223 return; 207 return;
224 208
225 // Prevent DispatchMouseMovement from dispatching any posted motion event. 209 // Prevent DispatchMouseMovement from dispatching any posted motion event.
226 weak_factory_.InvalidateWeakPtrs(); 210 weak_factory_.InvalidateWeakPtrs();
227 last_xmotion_.type = LASTEvent; 211 last_xmotion_.type = LASTEvent;
228 212
229 // We undo our emulated mouse click from RunMoveLoop(); 213 // We undo our emulated mouse click from RunMoveLoop();
230 if (should_reset_mouse_flags_) { 214 if (should_reset_mouse_flags_) {
231 aura::Env::GetInstance()->set_mouse_button_flags(0); 215 aura::Env::GetInstance()->set_mouse_button_flags(0);
232 should_reset_mouse_flags_ = false; 216 should_reset_mouse_flags_ = false;
233 } 217 }
234 218
235 // TODO(erg): Is this ungrab the cause of having to click to give input focus 219 // TODO(erg): Is this ungrab the cause of having to click to give input focus
236 // on drawn out windows? Not ungrabbing here screws the X server until I kill 220 // on drawn out windows? Not ungrabbing here screws the X server until I kill
237 // the chrome process. 221 // the chrome process.
238 222
239 // Ungrab before we let go of the window. 223 // Ungrab before we let go of the window.
240 XDisplay* display = gfx::GetXDisplay(); 224 XDisplay* display = gfx::GetXDisplay();
241 // Only ungrab pointer if capture was not switched to another window. 225 if (grabbed_pointer_)
242 if (has_grab_) {
243 XUngrabPointer(display, CurrentTime); 226 XUngrabPointer(display, CurrentTime);
244 XUngrabKeyboard(display, CurrentTime); 227 else
245 } 228 UpdateCursor(initial_cursor_);
229
230 XUngrabKeyboard(display, CurrentTime);
246 231
247 // Restore the previous dispatcher. 232 // Restore the previous dispatcher.
248 nested_dispatcher_.reset(); 233 nested_dispatcher_.reset();
249 delegate_->OnMoveLoopEnded(); 234 delegate_->OnMoveLoopEnded();
250 XDestroyWindow(display, grab_input_window_); 235 XDestroyWindow(display, grab_input_window_);
251 grab_input_window_ = None; 236 grab_input_window_ = None;
252 237
253 in_move_loop_ = false; 238 in_move_loop_ = false;
254 quit_closure_.Run(); 239 quit_closure_.Run();
255 } 240 }
256 241
257 bool X11WholeScreenMoveLoop::GrabPointerAndKeyboard(gfx::NativeCursor cursor) { 242 bool X11WholeScreenMoveLoop::GrabPointer(gfx::NativeCursor cursor) {
258 XDisplay* display = gfx::GetXDisplay(); 243 XDisplay* display = gfx::GetXDisplay();
259 XGrabServer(display); 244 XGrabServer(display);
260 245
261 XUngrabPointer(display, CurrentTime); 246 // Pass "owner_events" as false so that X sends all mouse events to
247 // |grab_input_window_|.
262 int ret = XGrabPointer( 248 int ret = XGrabPointer(
263 display, 249 display,
264 grab_input_window_, 250 grab_input_window_,
265 False, 251 False, // owner_events
266 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 252 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
267 GrabModeAsync, 253 GrabModeAsync,
268 GrabModeAsync, 254 GrabModeAsync,
269 None, 255 None,
270 cursor.platform(), 256 cursor.platform(),
271 CurrentTime); 257 CurrentTime);
272 if (ret != GrabSuccess) { 258 if (ret != GrabSuccess) {
273 DLOG(ERROR) << "Grabbing pointer for dragging failed: " 259 DLOG(ERROR) << "Grabbing pointer for dragging failed: "
274 << ui::GetX11ErrorString(display, ret); 260 << ui::GetX11ErrorString(display, ret);
275 } else {
276 has_grab_ = true;
277 XUngrabKeyboard(display, CurrentTime);
278 ret = XGrabKeyboard(
279 display,
280 grab_input_window_,
281 False,
282 GrabModeAsync,
283 GrabModeAsync,
284 CurrentTime);
285 if (ret != GrabSuccess) {
286 DLOG(ERROR) << "Grabbing keyboard for dragging failed: "
287 << ui::GetX11ErrorString(display, ret);
288 }
289 } 261 }
290
291 XUngrabServer(display); 262 XUngrabServer(display);
292 XFlush(display); 263 XFlush(display);
293 return ret == GrabSuccess; 264 return ret == GrabSuccess;
294 } 265 }
295 266
267 bool X11WholeScreenMoveLoop::GrabKeyboard() {
268 XDisplay* display = gfx::GetXDisplay();
269 int ret = XGrabKeyboard(display,
270 grab_input_window_,
271 False,
272 GrabModeAsync,
273 GrabModeAsync,
274 CurrentTime);
275 if (ret != GrabSuccess) {
276 DLOG(ERROR) << "Grabbing keyboard for dragging failed: "
277 << ui::GetX11ErrorString(display, ret);
278 return false;
279 }
280 return true;
281 }
282
296 Window X11WholeScreenMoveLoop::CreateDragInputWindow(XDisplay* display) { 283 Window X11WholeScreenMoveLoop::CreateDragInputWindow(XDisplay* display) {
297 // Creates an invisible, InputOnly toplevel window. This window will receive
298 // all mouse movement for drags. It turns out that normal windows doing a
299 // grab doesn't redirect pointer motion events if the pointer isn't over the
300 // grabbing window. But InputOnly windows are able to grab everything. This
301 // is what GTK+ does, and I found a patch to KDE that did something similar.
pkotwicz 2014/08/10 18:58:49 This comment sounds like a description of the "own
302 unsigned long attribute_mask = CWEventMask | CWOverrideRedirect; 284 unsigned long attribute_mask = CWEventMask | CWOverrideRedirect;
303 XSetWindowAttributes swa; 285 XSetWindowAttributes swa;
304 memset(&swa, 0, sizeof(swa)); 286 memset(&swa, 0, sizeof(swa));
305 swa.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | 287 swa.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
306 KeyPressMask | KeyReleaseMask | StructureNotifyMask; 288 KeyPressMask | KeyReleaseMask | StructureNotifyMask;
307 swa.override_redirect = True; 289 swa.override_redirect = True;
308 Window window = XCreateWindow(display, 290 Window window = XCreateWindow(display,
309 DefaultRootWindow(display), 291 DefaultRootWindow(display),
310 -100, -100, 10, 10, 292 -100, -100, 10, 10,
311 0, CopyFromParent, InputOnly, CopyFromParent, 293 0, CopyFromParent, InputOnly, CopyFromParent,
312 attribute_mask, &swa); 294 attribute_mask, &swa);
313 XMapRaised(display, window); 295 XMapRaised(display, window);
314 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window); 296 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(window);
315 return window; 297 return window;
316 } 298 }
317 299
318 } // namespace views 300 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698