| 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 |