OLD | NEW |
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 "ui/events/devices/x11/touch_factory_x11.h" |
12 #include "ui/events/event.h" | 13 #include "ui/events/event.h" |
13 #include "ui/events/platform/platform_event_builder.h" | 14 #include "ui/events/event_utils.h" |
14 #include "ui/events/platform/platform_event_dispatcher.h" | 15 #include "ui/events/platform/platform_event_dispatcher.h" |
15 #include "ui/events/platform/platform_event_source.h" | 16 #include "ui/events/platform/platform_event_source.h" |
16 #include "ui/events/platform/platform_event_utils.h" | |
17 #include "ui/events/platform/x11/touch_factory_x11.h" | |
18 #include "ui/events/platform/x11/x11_event_source.h" | 17 #include "ui/events/platform/x11/x11_event_source.h" |
19 #include "ui/gfx/geometry/rect.h" | 18 #include "ui/gfx/geometry/rect.h" |
20 #include "ui/gfx/x/x11_atom_cache.h" | 19 #include "ui/gfx/x/x11_atom_cache.h" |
21 #include "ui/gfx/x/x11_types.h" | 20 #include "ui/gfx/x/x11_types.h" |
22 #include "ui/platform_window/platform_window_delegate.h" | 21 #include "ui/platform_window/platform_window_delegate.h" |
23 | 22 |
24 namespace ui { | 23 namespace ui { |
25 | 24 |
26 namespace { | 25 namespace { |
27 | 26 |
(...skipping 18 matching lines...) Expand all Loading... |
46 xdisplay_(gfx::GetXDisplay()), | 45 xdisplay_(gfx::GetXDisplay()), |
47 xwindow_(None), | 46 xwindow_(None), |
48 xroot_window_(DefaultRootWindow(xdisplay_)), | 47 xroot_window_(DefaultRootWindow(xdisplay_)), |
49 atom_cache_(xdisplay_, kAtomsToCache), | 48 atom_cache_(xdisplay_, kAtomsToCache), |
50 window_mapped_(false) { | 49 window_mapped_(false) { |
51 CHECK(delegate_); | 50 CHECK(delegate_); |
52 TouchFactory::SetTouchDeviceListFromCommandLine(); | 51 TouchFactory::SetTouchDeviceListFromCommandLine(); |
53 } | 52 } |
54 | 53 |
55 X11Window::~X11Window() { | 54 X11Window::~X11Window() { |
56 Destroy(); | |
57 } | 55 } |
58 | 56 |
59 void X11Window::Destroy() { | 57 void X11Window::Destroy() { |
60 delegate_->OnClosed(); | |
61 if (xwindow_ == None) | 58 if (xwindow_ == None) |
62 return; | 59 return; |
63 | 60 |
64 // Stop processing events. | 61 // Stop processing events. |
65 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 62 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
66 XDestroyWindow(xdisplay_, xwindow_); | 63 XID xwindow = xwindow_; |
| 64 XDisplay* xdisplay = xdisplay_; |
67 xwindow_ = None; | 65 xwindow_ = None; |
| 66 delegate_->OnClosed(); |
| 67 // |this| might be deleted because of the above call. |
| 68 |
| 69 XDestroyWindow(xdisplay, xwindow); |
68 } | 70 } |
69 | 71 |
70 void X11Window::ProcessXInput2Event(XEvent* xev) { | 72 void X11Window::ProcessXInput2Event(XEvent* xev) { |
71 if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev)) | 73 if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev)) |
72 return; | 74 return; |
73 EventType event_type = EventTypeFromNative(xev); | 75 EventType event_type = EventTypeFromNative(xev); |
74 switch (event_type) { | 76 switch (event_type) { |
75 case ET_KEY_PRESSED: | 77 case ET_KEY_PRESSED: |
76 case ET_KEY_RELEASED: { | 78 case ET_KEY_RELEASED: { |
77 KeyEvent key_event = PlatformEventBuilder::BuildKeyEvent(xev); | 79 KeyEvent key_event(xev); |
78 delegate_->DispatchEvent(&key_event); | 80 delegate_->DispatchEvent(&key_event); |
79 break; | 81 break; |
80 } | 82 } |
81 case ET_MOUSE_PRESSED: | 83 case ET_MOUSE_PRESSED: |
82 case ET_MOUSE_MOVED: | 84 case ET_MOUSE_MOVED: |
83 case ET_MOUSE_DRAGGED: | 85 case ET_MOUSE_DRAGGED: |
84 case ET_MOUSE_RELEASED: { | 86 case ET_MOUSE_RELEASED: { |
85 MouseEvent mouse_event = PlatformEventBuilder::BuildMouseEvent(xev); | 87 MouseEvent mouse_event(xev); |
86 delegate_->DispatchEvent(&mouse_event); | 88 delegate_->DispatchEvent(&mouse_event); |
87 break; | 89 break; |
88 } | 90 } |
89 case ET_MOUSEWHEEL: { | 91 case ET_MOUSEWHEEL: { |
90 MouseWheelEvent wheel_event = | 92 MouseWheelEvent wheel_event(xev); |
91 PlatformEventBuilder::BuildMouseWheelEvent(xev); | |
92 delegate_->DispatchEvent(&wheel_event); | 93 delegate_->DispatchEvent(&wheel_event); |
93 break; | 94 break; |
94 } | 95 } |
95 case ET_SCROLL_FLING_START: | 96 case ET_SCROLL_FLING_START: |
96 case ET_SCROLL_FLING_CANCEL: | 97 case ET_SCROLL_FLING_CANCEL: |
97 case ET_SCROLL: { | 98 case ET_SCROLL: { |
98 ScrollEvent scroll_event = PlatformEventBuilder::BuildScrollEvent(xev); | 99 ScrollEvent scroll_event(xev); |
99 delegate_->DispatchEvent(&scroll_event); | 100 delegate_->DispatchEvent(&scroll_event); |
100 break; | 101 break; |
101 } | 102 } |
102 case ET_TOUCH_MOVED: | 103 case ET_TOUCH_MOVED: |
103 case ET_TOUCH_PRESSED: | 104 case ET_TOUCH_PRESSED: |
104 case ET_TOUCH_CANCELLED: | 105 case ET_TOUCH_CANCELLED: |
105 case ET_TOUCH_RELEASED: { | 106 case ET_TOUCH_RELEASED: { |
106 TouchEvent touch_event = PlatformEventBuilder::BuildTouchEvent(xev); | 107 TouchEvent touch_event(xev); |
107 | |
108 if (touch_event.type() == ET_TOUCH_PRESSED) | |
109 IncrementTouchIdRefCount(xev); | |
110 | |
111 delegate_->DispatchEvent(&touch_event); | 108 delegate_->DispatchEvent(&touch_event); |
112 | |
113 ClearTouchIdIfReleased(xev); | |
114 break; | 109 break; |
115 } | 110 } |
116 default: | 111 default: |
117 break; | 112 break; |
118 } | 113 } |
119 } | 114 } |
120 | 115 |
121 void X11Window::Show() { | 116 void X11Window::Show() { |
122 if (window_mapped_) | 117 if (window_mapped_) |
123 return; | 118 return; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); | 169 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); |
175 | 170 |
176 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with | 171 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with |
177 // the desktop environment. | 172 // the desktop environment. |
178 XSetWMProperties( | 173 XSetWMProperties( |
179 xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); | 174 xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); |
180 | 175 |
181 // Likewise, the X server needs to know this window's pid so it knows which | 176 // Likewise, the X server needs to know this window's pid so it knows which |
182 // program to kill if the window hangs. | 177 // program to kill if the window hangs. |
183 // XChangeProperty() expects "pid" to be long. | 178 // XChangeProperty() expects "pid" to be long. |
184 COMPILE_ASSERT(sizeof(long) >= sizeof(pid_t), pid_t_bigger_than_long); | 179 static_assert(sizeof(long) >= sizeof(pid_t), |
| 180 "pid_t should not be larger than long"); |
185 long pid = getpid(); | 181 long pid = getpid(); |
186 XChangeProperty(xdisplay_, | 182 XChangeProperty(xdisplay_, |
187 xwindow_, | 183 xwindow_, |
188 atom_cache_.GetAtom("_NET_WM_PID"), | 184 atom_cache_.GetAtom("_NET_WM_PID"), |
189 XA_CARDINAL, | 185 XA_CARDINAL, |
190 32, | 186 32, |
191 PropModeReplace, | 187 PropModeReplace, |
192 reinterpret_cast<unsigned char*>(&pid), | 188 reinterpret_cast<unsigned char*>(&pid), |
193 1); | 189 1); |
194 // Before we map the window, set size hints. Otherwise, some window managers | 190 // Before we map the window, set size hints. Otherwise, some window managers |
195 // will ignore toplevel XMoveWindow commands. | 191 // will ignore toplevel XMoveWindow commands. |
196 XSizeHints size_hints; | 192 XSizeHints size_hints; |
197 size_hints.flags = PPosition | PWinGravity; | 193 size_hints.flags = PPosition | PWinGravity; |
198 size_hints.x = requested_bounds_.x(); | 194 size_hints.x = requested_bounds_.x(); |
199 size_hints.y = requested_bounds_.y(); | 195 size_hints.y = requested_bounds_.y(); |
200 // Set StaticGravity so that the window position is not affected by the | 196 // Set StaticGravity so that the window position is not affected by the |
201 // frame width when running with window manager. | 197 // frame width when running with window manager. |
202 size_hints.win_gravity = StaticGravity; | 198 size_hints.win_gravity = StaticGravity; |
203 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); | 199 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); |
204 | 200 |
| 201 // TODO(sky): provide real scale factor. |
205 delegate_->OnAcceleratedWidgetAvailable(xwindow_); | 202 delegate_->OnAcceleratedWidgetAvailable(xwindow_); |
206 | 203 |
207 XMapWindow(xdisplay_, xwindow_); | 204 XMapWindow(xdisplay_, xwindow_); |
208 | 205 |
209 // We now block until our window is mapped. Some X11 APIs will crash and | 206 // We now block until our window is mapped. Some X11 APIs will crash and |
210 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | 207 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is |
211 // asynchronous. | 208 // asynchronous. |
212 if (X11EventSource::GetInstance()) | 209 if (X11EventSource::GetInstance()) |
213 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | 210 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); |
214 window_mapped_ = true; | 211 window_mapped_ = true; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 void X11Window::Maximize() {} | 248 void X11Window::Maximize() {} |
252 | 249 |
253 void X11Window::Minimize() {} | 250 void X11Window::Minimize() {} |
254 | 251 |
255 void X11Window::Restore() {} | 252 void X11Window::Restore() {} |
256 | 253 |
257 void X11Window::SetCursor(PlatformCursor cursor) {} | 254 void X11Window::SetCursor(PlatformCursor cursor) {} |
258 | 255 |
259 void X11Window::MoveCursorTo(const gfx::Point& location) {} | 256 void X11Window::MoveCursorTo(const gfx::Point& location) {} |
260 | 257 |
| 258 void X11Window::ConfineCursorToBounds(const gfx::Rect& bounds) { |
| 259 } |
| 260 |
261 bool X11Window::CanDispatchEvent(const PlatformEvent& event) { | 261 bool X11Window::CanDispatchEvent(const PlatformEvent& event) { |
262 return FindXEventTarget(event) == xwindow_; | 262 return FindXEventTarget(event) == xwindow_; |
263 } | 263 } |
264 | 264 |
265 uint32_t X11Window::DispatchEvent(const PlatformEvent& event) { | 265 uint32_t X11Window::DispatchEvent(const PlatformEvent& event) { |
266 XEvent* xev = event; | 266 XEvent* xev = event; |
267 switch (xev->type) { | 267 switch (xev->type) { |
268 case EnterNotify: { | 268 case EnterNotify: { |
269 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is | 269 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is |
270 // not real mouse move event. | 270 // not real mouse move event. |
271 MouseEvent mouse_event = PlatformEventBuilder::BuildMouseEvent(xev); | 271 MouseEvent mouse_event(xev); |
272 CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type()); | 272 CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type()); |
273 mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED); | 273 mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED); |
274 delegate_->DispatchEvent(&mouse_event); | 274 delegate_->DispatchEvent(&mouse_event); |
275 break; | 275 break; |
276 } | 276 } |
277 case LeaveNotify: { | 277 case LeaveNotify: { |
278 MouseEvent mouse_event = PlatformEventBuilder::BuildMouseEvent(xev); | 278 MouseEvent mouse_event(xev); |
279 delegate_->DispatchEvent(&mouse_event); | 279 delegate_->DispatchEvent(&mouse_event); |
280 break; | 280 break; |
281 } | 281 } |
282 | 282 |
283 case Expose: { | 283 case Expose: { |
284 gfx::Rect damage_rect(xev->xexpose.x, | 284 gfx::Rect damage_rect(xev->xexpose.x, |
285 xev->xexpose.y, | 285 xev->xexpose.y, |
286 xev->xexpose.width, | 286 xev->xexpose.width, |
287 xev->xexpose.height); | 287 xev->xexpose.height); |
288 delegate_->OnDamageRect(damage_rect); | 288 delegate_->OnDamageRect(damage_rect); |
289 break; | 289 break; |
290 } | 290 } |
291 | 291 |
292 case KeyPress: | 292 case KeyPress: |
293 case KeyRelease: { | 293 case KeyRelease: { |
294 KeyEvent key_event = PlatformEventBuilder::BuildKeyEvent(xev); | 294 KeyEvent key_event(xev); |
295 delegate_->DispatchEvent(&key_event); | 295 delegate_->DispatchEvent(&key_event); |
296 break; | 296 break; |
297 } | 297 } |
298 | 298 |
299 case ButtonPress: | 299 case ButtonPress: |
300 case ButtonRelease: { | 300 case ButtonRelease: { |
301 switch (EventTypeFromNative(xev)) { | 301 switch (EventTypeFromNative(xev)) { |
302 case ET_MOUSEWHEEL: { | 302 case ET_MOUSEWHEEL: { |
303 MouseWheelEvent mouseev = | 303 MouseWheelEvent mouseev(xev); |
304 PlatformEventBuilder::BuildMouseWheelEvent(xev); | |
305 delegate_->DispatchEvent(&mouseev); | 304 delegate_->DispatchEvent(&mouseev); |
306 break; | 305 break; |
307 } | 306 } |
308 case ET_MOUSE_PRESSED: | 307 case ET_MOUSE_PRESSED: |
309 case ET_MOUSE_RELEASED: { | 308 case ET_MOUSE_RELEASED: { |
310 MouseEvent mouseev = PlatformEventBuilder::BuildMouseEvent(xev); | 309 MouseEvent mouseev(xev); |
311 delegate_->DispatchEvent(&mouseev); | 310 delegate_->DispatchEvent(&mouseev); |
312 break; | 311 break; |
313 } | 312 } |
314 case ET_UNKNOWN: | 313 case ET_UNKNOWN: |
315 // No event is created for X11-release events for mouse-wheel | 314 // No event is created for X11-release events for mouse-wheel |
316 // buttons. | 315 // buttons. |
317 break; | 316 break; |
318 default: | 317 default: |
319 NOTREACHED(); | 318 NOTREACHED(); |
320 } | 319 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 | 359 |
361 case GenericEvent: { | 360 case GenericEvent: { |
362 ProcessXInput2Event(xev); | 361 ProcessXInput2Event(xev); |
363 break; | 362 break; |
364 } | 363 } |
365 } | 364 } |
366 return POST_DISPATCH_STOP_PROPAGATION; | 365 return POST_DISPATCH_STOP_PROPAGATION; |
367 } | 366 } |
368 | 367 |
369 } // namespace ui | 368 } // namespace ui |
OLD | NEW |