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

Side by Side Diff: ui/platform_window/x11/x11_window.cc

Issue 1602173005: Add PlatformWindow/Event related code for Ozone X11. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: XEventDispatcher added. Created 4 years, 10 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/platform_window/x11/x11_window.h" 5 #include "ui/platform_window/x11/x11_window.h"
6 6
7 #include <X11/extensions/XInput2.h> 7 #include <X11/extensions/XInput2.h>
8 #include <X11/Xatom.h> 8 #include <X11/Xatom.h>
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h> 10 #include <X11/Xutil.h>
11 11
12 #include <string>
13
12 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
13 #include "ui/events/devices/x11/touch_factory_x11.h" 15 #include "ui/events/devices/x11/touch_factory_x11.h"
14 #include "ui/events/event.h" 16 #include "ui/events/event.h"
15 #include "ui/events/event_utils.h" 17 #include "ui/events/event_utils.h"
16 #include "ui/events/platform/platform_event_dispatcher.h" 18 #include "ui/events/platform/platform_event_dispatcher.h"
17 #include "ui/events/platform/platform_event_source.h" 19 #include "ui/events/platform/platform_event_source.h"
18 #include "ui/events/platform/x11/x11_event_source.h"
19 #include "ui/gfx/geometry/rect.h" 20 #include "ui/gfx/geometry/rect.h"
20 #include "ui/gfx/x/x11_atom_cache.h" 21 #include "ui/gfx/x/x11_atom_cache.h"
21 #include "ui/gfx/x/x11_types.h" 22 #include "ui/gfx/x/x11_types.h"
22 #include "ui/platform_window/platform_window_delegate.h" 23 #include "ui/platform_window/platform_window_delegate.h"
23 24
24 namespace ui { 25 namespace ui {
25 26
26 namespace { 27 namespace {
27 28
28 const char* kAtomsToCache[] = { 29 const char* kAtomsToCache[] = {
29 "UTF8_STRING", 30 "UTF8_STRING",
30 "WM_DELETE_WINDOW", 31 "WM_DELETE_WINDOW",
31 "_NET_WM_NAME", 32 "_NET_WM_NAME",
32 "_NET_WM_PID", 33 "_NET_WM_PID",
33 "_NET_WM_PING", 34 "_NET_WM_PING",
34 NULL 35 NULL
35 }; 36 };
36 37
37 XID FindXEventTarget(XEvent* xevent) {
38 XID target = xevent->xany.window;
39 if (xevent->type == GenericEvent)
40 target = static_cast<XIDeviceEvent*>(xevent->xcookie.data)->event;
41 return target;
42 }
43
44 bool g_override_redirect = false; 38 bool g_override_redirect = false;
45 39
46 } // namespace 40 } // namespace
47 41
48 X11Window::X11Window(PlatformWindowDelegate* delegate) 42 X11Window::X11Window(PlatformWindowDelegate* delegate)
49 : delegate_(delegate), 43 : delegate_(delegate),
50 xdisplay_(gfx::GetXDisplay()), 44 xdisplay_(gfx::GetXDisplay()),
51 xwindow_(None), 45 xwindow_(None),
52 xroot_window_(DefaultRootWindow(xdisplay_)), 46 xroot_window_(DefaultRootWindow(xdisplay_)),
53 atom_cache_(xdisplay_, kAtomsToCache), 47 atom_cache_(xdisplay_, kAtomsToCache) {
54 window_mapped_(false) {
55 CHECK(delegate_); 48 CHECK(delegate_);
56 TouchFactory::SetTouchDeviceListFromCommandLine(); 49 TouchFactory::SetTouchDeviceListFromCommandLine();
57 } 50 }
58 51
59 X11Window::~X11Window() { 52 X11Window::~X11Window() {
60 Destroy(); 53 Destroy();
61 } 54 }
62 55
63 void X11Window::Destroy() { 56 void X11Window::Destroy() {
64 if (xwindow_ == None) 57 if (xwindow_ == None)
65 return; 58 return;
66 59
67 // Stop processing events. 60 // Stop processing events.
68 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); 61 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
69 XID xwindow = xwindow_; 62 XID xwindow = xwindow_;
70 XDisplay* xdisplay = xdisplay_; 63 XDisplay* xdisplay = xdisplay_;
71 xwindow_ = None; 64 xwindow_ = None;
72 delegate_->OnClosed(); 65 delegate_->OnClosed();
73 // |this| might be deleted because of the above call. 66 // |this| might be deleted because of the above call.
74 67
75 XDestroyWindow(xdisplay, xwindow); 68 XDestroyWindow(xdisplay, xwindow);
76 } 69 }
77 70
78 void X11Window::ProcessXInput2Event(XEvent* xev) { 71 void X11Window::Create() {
79 if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev)) 72 DCHECK(PlatformEventSource::GetInstance());
80 return; 73 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
81 EventType event_type = EventTypeFromNative(xev);
82 switch (event_type) {
83 case ET_KEY_PRESSED:
84 case ET_KEY_RELEASED: {
85 KeyEvent key_event(xev);
86 delegate_->DispatchEvent(&key_event);
87 break;
88 }
89 case ET_MOUSE_PRESSED:
90 case ET_MOUSE_MOVED:
91 case ET_MOUSE_DRAGGED:
92 case ET_MOUSE_RELEASED: {
93 MouseEvent mouse_event(xev);
94 delegate_->DispatchEvent(&mouse_event);
95 break;
96 }
97 case ET_MOUSEWHEEL: {
98 MouseWheelEvent wheel_event(xev);
99 delegate_->DispatchEvent(&wheel_event);
100 break;
101 }
102 case ET_SCROLL_FLING_START:
103 case ET_SCROLL_FLING_CANCEL:
104 case ET_SCROLL: {
105 ScrollEvent scroll_event(xev);
106 delegate_->DispatchEvent(&scroll_event);
107 break;
108 }
109 case ET_TOUCH_MOVED:
110 case ET_TOUCH_PRESSED:
111 case ET_TOUCH_CANCELLED:
112 case ET_TOUCH_RELEASED: {
113 TouchEvent touch_event(xev);
114 delegate_->DispatchEvent(&touch_event);
115 break;
116 }
117 default:
118 break;
119 }
120 }
121 74
122 void X11Window::Show() { 75 DCHECK(X11EventSource::GetInstance());
123 if (window_mapped_) 76 X11EventSource::GetInstance()->AddXEventDispatcher(this);
124 return;
125
126 CHECK(PlatformEventSource::GetInstance());
127 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
128 77
129 XSetWindowAttributes swa; 78 XSetWindowAttributes swa;
130 memset(&swa, 0, sizeof(swa)); 79 memset(&swa, 0, sizeof(swa));
131 swa.background_pixmap = None; 80 swa.background_pixmap = None;
132 swa.bit_gravity = NorthWestGravity; 81 swa.bit_gravity = NorthWestGravity;
133 swa.override_redirect = g_override_redirect; 82 swa.override_redirect = g_override_redirect;
134 xwindow_ = XCreateWindow(xdisplay_, 83 xwindow_ = XCreateWindow(xdisplay_,
135 xroot_window_, 84 xroot_window_,
136 requested_bounds_.x(), 85 requested_bounds_.x(),
137 requested_bounds_.y(), 86 requested_bounds_.y(),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // will ignore toplevel XMoveWindow commands. 147 // will ignore toplevel XMoveWindow commands.
199 XSizeHints size_hints; 148 XSizeHints size_hints;
200 size_hints.flags = PPosition | PWinGravity; 149 size_hints.flags = PPosition | PWinGravity;
201 size_hints.x = requested_bounds_.x(); 150 size_hints.x = requested_bounds_.x();
202 size_hints.y = requested_bounds_.y(); 151 size_hints.y = requested_bounds_.y();
203 // Set StaticGravity so that the window position is not affected by the 152 // Set StaticGravity so that the window position is not affected by the
204 // frame width when running with window manager. 153 // frame width when running with window manager.
205 size_hints.win_gravity = StaticGravity; 154 size_hints.win_gravity = StaticGravity;
206 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 155 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
207 156
157 // TODO(sky): provide real scale factor.
158 delegate_->OnAcceleratedWidgetAvailable(xwindow_, 1.f);
159 }
160
161 void X11Window::Show() {
162 if (window_mapped_)
163 return;
164 if (xwindow_ == None)
165 Create();
166
208 XMapWindow(xdisplay_, xwindow_); 167 XMapWindow(xdisplay_, xwindow_);
209 168
210 // We now block until our window is mapped. Some X11 APIs will crash and 169 // We now block until our window is mapped. Some X11 APIs will crash and
211 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is 170 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
212 // asynchronous. 171 // asynchronous.
213 if (X11EventSource::GetInstance()) 172 if (X11EventSource::GetInstance())
214 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); 173 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
215 window_mapped_ = true; 174 window_mapped_ = true;
216
217 // TODO(sky): provide real scale factor.
218 delegate_->OnAcceleratedWidgetAvailable(xwindow_, 1.f);
219 } 175 }
220 176
221 void X11Window::Hide() { 177 void X11Window::Hide() {
222 if (!window_mapped_) 178 if (!window_mapped_)
223 return; 179 return;
224 XWithdrawWindow(xdisplay_, xwindow_, 0); 180 XWithdrawWindow(xdisplay_, xwindow_, 0);
225 window_mapped_ = false; 181 window_mapped_ = false;
226 } 182 }
227 183
228 void X11Window::Close() { 184 void X11Window::Close() {
229 Destroy(); 185 Destroy();
230 } 186 }
231 187
232 void X11Window::SetBounds(const gfx::Rect& bounds) { 188 void X11Window::SetBounds(const gfx::Rect& bounds) {
233 requested_bounds_ = bounds; 189 requested_bounds_ = bounds;
234 if (!window_mapped_) 190 if (!window_mapped_ || bounds == confirmed_bounds_)
235 return; 191 return;
236 XWindowChanges changes = {0}; 192 XWindowChanges changes = {0};
237 unsigned value_mask = CWX | CWY | CWWidth | CWHeight; 193 unsigned value_mask = CWX | CWY | CWWidth | CWHeight;
238 changes.x = bounds.x(); 194 changes.x = bounds.x();
239 changes.y = bounds.y(); 195 changes.y = bounds.y();
240 changes.width = bounds.width(); 196 changes.width = bounds.width();
241 changes.height = bounds.height(); 197 changes.height = bounds.height();
242 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); 198 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
243 } 199 }
244 200
245 gfx::Rect X11Window::GetBounds() { 201 gfx::Rect X11Window::GetBounds() {
246 return confirmed_bounds_; 202 return confirmed_bounds_;
247 } 203 }
248 204
249 void X11Window::SetTitle(const base::string16& title) { 205 void X11Window::SetTitle(const base::string16& title) {
250 if (window_title_ == title) 206 if (window_title_ == title)
251 return; 207 return;
252 window_title_ = title; 208 window_title_ = title;
253 std::string utf8str = base::UTF16ToUTF8(title); 209 std::string utf8str = base::UTF16ToUTF8(title);
254 XChangeProperty(xdisplay_, 210 XChangeProperty(xdisplay_,
255 xwindow_, 211 xwindow_,
256 atom_cache_.GetAtom("_NET_WM_NAME"), 212 atom_cache_.GetAtom("_NET_WM_NAME"),
257 atom_cache_.GetAtom("UTF8_STRING"), 213 atom_cache_.GetAtom("UTF8_STRING"),
258 8, 214 8,
259 PropModeReplace, 215 PropModeReplace,
260 reinterpret_cast<const unsigned char*>(utf8str.c_str()), 216 reinterpret_cast<const unsigned char*>(utf8str.c_str()),
261 utf8str.size()); 217 utf8str.size());
262 XTextProperty xtp; 218 XTextProperty xtp;
263 char *c_utf8_str = const_cast<char *>(utf8str.c_str()); 219 char* c_utf8_str = const_cast<char*>(utf8str.c_str());
264 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, 220 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1,
265 XUTF8StringStyle, &xtp) == Success) { 221 XUTF8StringStyle, &xtp) == Success) {
266 XSetWMName(xdisplay_, xwindow_, &xtp); 222 XSetWMName(xdisplay_, xwindow_, &xtp);
267 XFree(xtp.value); 223 XFree(xtp.value);
268 } 224 }
269 } 225 }
270 226
271 void X11Window::SetCapture() {} 227 void X11Window::SetCapture() {}
272 228
273 void X11Window::ReleaseCapture() {} 229 void X11Window::ReleaseCapture() {}
274 230
275 void X11Window::ToggleFullscreen() {} 231 void X11Window::ToggleFullscreen() {}
276 232
277 void X11Window::Maximize() {} 233 void X11Window::Maximize() {}
278 234
279 void X11Window::Minimize() {} 235 void X11Window::Minimize() {}
280 236
281 void X11Window::Restore() {} 237 void X11Window::Restore() {}
282 238
283 void X11Window::SetCursor(PlatformCursor cursor) {
284 XDefineCursor(xdisplay_, xwindow_, cursor);
285 }
286
287 void X11Window::MoveCursorTo(const gfx::Point& location) {} 239 void X11Window::MoveCursorTo(const gfx::Point& location) {}
288 240
289 void X11Window::ConfineCursorToBounds(const gfx::Rect& bounds) { 241 void X11Window::ConfineCursorToBounds(const gfx::Rect& bounds) {
290 } 242 }
291 243
292 PlatformImeController* X11Window::GetPlatformImeController() { 244 PlatformImeController* X11Window::GetPlatformImeController() {
293 return nullptr; 245 return nullptr;
294 } 246 }
295 247
296 bool X11Window::CanDispatchEvent(const PlatformEvent& event) { 248 void X11Window::ProcessXWindowEvent(const XEvent& xev) {
297 return FindXEventTarget(event) == xwindow_; 249 switch (xev.type) {
298 }
299
300 uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
301 XEvent* xev = event;
302 switch (xev->type) {
303 case EnterNotify: {
304 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is
305 // not real mouse move event.
306 MouseEvent mouse_event(xev);
307 CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type());
308 mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED);
309 delegate_->DispatchEvent(&mouse_event);
310 break;
311 }
312 case LeaveNotify: {
313 MouseEvent mouse_event(xev);
314 delegate_->DispatchEvent(&mouse_event);
315 break;
316 }
317
318 case Expose: { 250 case Expose: {
319 gfx::Rect damage_rect(xev->xexpose.x, 251 gfx::Rect damage_rect(xev.xexpose.x, xev.xexpose.y, xev.xexpose.width,
320 xev->xexpose.y, 252 xev.xexpose.height);
321 xev->xexpose.width,
322 xev->xexpose.height);
323 delegate_->OnDamageRect(damage_rect); 253 delegate_->OnDamageRect(damage_rect);
324 break; 254 break;
325 } 255 }
326 256
327 case KeyPress:
328 case KeyRelease: {
329 KeyEvent key_event(xev);
330 delegate_->DispatchEvent(&key_event);
331 break;
332 }
333
334 case ButtonPress:
335 case ButtonRelease: {
336 switch (EventTypeFromNative(xev)) {
337 case ET_MOUSEWHEEL: {
338 MouseWheelEvent mouseev(xev);
339 delegate_->DispatchEvent(&mouseev);
340 break;
341 }
342 case ET_MOUSE_PRESSED:
343 case ET_MOUSE_RELEASED: {
344 MouseEvent mouseev(xev);
345 delegate_->DispatchEvent(&mouseev);
346 break;
347 }
348 case ET_UNKNOWN:
349 // No event is created for X11-release events for mouse-wheel
350 // buttons.
351 break;
352 default:
353 NOTREACHED();
354 }
355 break;
356 }
357
358 case FocusOut: 257 case FocusOut:
359 if (xev->xfocus.mode != NotifyGrab) 258 if (xev.xfocus.mode != NotifyGrab)
360 delegate_->OnLostCapture(); 259 delegate_->OnLostCapture();
361 break; 260 break;
362 261
363 case ConfigureNotify: { 262 case ConfigureNotify: {
364 DCHECK_EQ(xwindow_, xev->xconfigure.event); 263 DCHECK_EQ(xwindow_, xev.xconfigure.event);
365 DCHECK_EQ(xwindow_, xev->xconfigure.window); 264 DCHECK_EQ(xwindow_, xev.xconfigure.window);
366 gfx::Rect bounds(xev->xconfigure.x, 265 gfx::Rect bounds(xev.xconfigure.x, xev.xconfigure.y, xev.xconfigure.width,
367 xev->xconfigure.y, 266 xev.xconfigure.height);
368 xev->xconfigure.width,
369 xev->xconfigure.height);
370 if (confirmed_bounds_ != bounds) { 267 if (confirmed_bounds_ != bounds) {
371 confirmed_bounds_ = bounds; 268 confirmed_bounds_ = bounds;
372 delegate_->OnBoundsChanged(confirmed_bounds_); 269 delegate_->OnBoundsChanged(confirmed_bounds_);
373 } 270 }
374 break; 271 break;
375 } 272 }
376 273
377 case ClientMessage: { 274 case ClientMessage: {
378 Atom message = static_cast<Atom>(xev->xclient.data.l[0]); 275 Atom message = static_cast<Atom>(xev.xclient.data.l[0]);
379 if (message == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { 276 if (message == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
380 delegate_->OnCloseRequest(); 277 delegate_->OnCloseRequest();
381 } else if (message == atom_cache_.GetAtom("_NET_WM_PING")) { 278 } else if (message == atom_cache_.GetAtom("_NET_WM_PING")) {
382 XEvent reply_event = *xev; 279 XEvent reply_event = xev;
383 reply_event.xclient.window = xroot_window_; 280 reply_event.xclient.window = xroot_window_;
384 281
385 XSendEvent(xdisplay_, 282 XSendEvent(xdisplay_,
386 reply_event.xclient.window, 283 reply_event.xclient.window,
387 False, 284 False,
388 SubstructureRedirectMask | SubstructureNotifyMask, 285 SubstructureRedirectMask | SubstructureNotifyMask,
389 &reply_event); 286 &reply_event);
390 XFlush(xdisplay_); 287 XFlush(xdisplay_);
391 } 288 }
392 break; 289 break;
393 } 290 }
394
395 case GenericEvent: {
396 ProcessXInput2Event(xev);
397 break;
398 }
399 } 291 }
400 return POST_DISPATCH_STOP_PROPAGATION;
401 } 292 }
402 293
403 namespace test { 294 namespace test {
404 295
405 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { 296 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
406 g_override_redirect = override_redirect; 297 g_override_redirect = override_redirect;
407 } 298 }
408 299
409 } // namespace test 300 } // namespace test
410 } // namespace ui 301 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698