| 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 "base/bind.h" |
| 12 #include "ui/events/devices/x11/touch_factory_x11.h" | 13 #include "ui/events/devices/x11/touch_factory_x11.h" |
| 13 #include "ui/events/event.h" | 14 #include "ui/events/event.h" |
| 14 #include "ui/events/event_utils.h" | 15 #include "ui/events/event_utils.h" |
| 16 #include "ui/events/ozone/events_ozone.h" |
| 15 #include "ui/events/platform/platform_event_dispatcher.h" | 17 #include "ui/events/platform/platform_event_dispatcher.h" |
| 16 #include "ui/events/platform/platform_event_source.h" | 18 #include "ui/events/platform/platform_event_source.h" |
| 17 #include "ui/events/platform/x11/x11_event_source.h" | 19 #include "ui/events/platform/x11/x11_event_source.h" |
| 18 #include "ui/gfx/geometry/rect.h" | 20 #include "ui/gfx/geometry/rect.h" |
| 19 #include "ui/gfx/x/x11_atom_cache.h" | 21 #include "ui/gfx/x/x11_atom_cache.h" |
| 20 #include "ui/gfx/x/x11_types.h" | 22 #include "ui/gfx/x/x11_types.h" |
| 21 #include "ui/platform_window/platform_window_delegate.h" | 23 #include "ui/platform_window/platform_window_delegate.h" |
| 22 | 24 |
| 23 namespace ui { | 25 namespace ui { |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 const char* kAtomsToCache[] = { | 29 const char* kAtomsToCache[] = { |
| 28 "WM_DELETE_WINDOW", | 30 "WM_DELETE_WINDOW", |
| 29 "_NET_WM_PING", | 31 "_NET_WM_PING", |
| 30 "_NET_WM_PID", | 32 "_NET_WM_PID", |
| 31 NULL | 33 NULL |
| 32 }; | 34 }; |
| 33 | 35 |
| 34 XID FindXEventTarget(XEvent* xevent) { | |
| 35 XID target = xevent->xany.window; | |
| 36 if (xevent->type == GenericEvent) | |
| 37 target = static_cast<XIDeviceEvent*>(xevent->xcookie.data)->event; | |
| 38 return target; | |
| 39 } | |
| 40 | |
| 41 } // namespace | 36 } // namespace |
| 42 | 37 |
| 43 X11Window::X11Window(PlatformWindowDelegate* delegate) | 38 X11Window::X11Window(PlatformWindowDelegate* delegate) |
| 44 : delegate_(delegate), | 39 : delegate_(delegate), |
| 45 xdisplay_(gfx::GetXDisplay()), | 40 xdisplay_(gfx::GetXDisplay()), |
| 46 xwindow_(None), | 41 xwindow_(None), |
| 47 xroot_window_(DefaultRootWindow(xdisplay_)), | 42 xroot_window_(DefaultRootWindow(xdisplay_)), |
| 48 atom_cache_(xdisplay_, kAtomsToCache), | 43 atom_cache_(xdisplay_, kAtomsToCache), |
| 49 window_mapped_(false) { | 44 window_mapped_(false) { |
| 50 CHECK(delegate_); | 45 CHECK(delegate_); |
| 51 TouchFactory::SetTouchDeviceListFromCommandLine(); | 46 TouchFactory::SetTouchDeviceListFromCommandLine(); |
| 52 } | 47 } |
| 53 | 48 |
| 54 X11Window::~X11Window() { | 49 X11Window::~X11Window() { |
| 55 Destroy(); | 50 Destroy(); |
| 56 } | 51 } |
| 57 | 52 |
| 58 void X11Window::Destroy() { | 53 void X11Window::Destroy() { |
| 59 delegate_->OnClosed(); | 54 delegate_->OnClosed(); |
| 60 if (xwindow_ == None) | 55 if (xwindow_ == None) |
| 61 return; | 56 return; |
| 62 | 57 |
| 63 // Stop processing events. | 58 // Stop processing events. |
| 64 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 59 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
| 65 XDestroyWindow(xdisplay_, xwindow_); | 60 XDestroyWindow(xdisplay_, xwindow_); |
| 66 xwindow_ = None; | 61 xwindow_ = None; |
| 67 } | 62 } |
| 68 | 63 |
| 69 void X11Window::ProcessXInput2Event(XEvent* xev) { | 64 void X11Window::Create() { |
| 70 if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev)) | |
| 71 return; | |
| 72 EventType event_type = EventTypeFromNative(xev); | |
| 73 switch (event_type) { | |
| 74 case ET_KEY_PRESSED: | |
| 75 case ET_KEY_RELEASED: { | |
| 76 KeyEvent key_event(xev); | |
| 77 delegate_->DispatchEvent(&key_event); | |
| 78 break; | |
| 79 } | |
| 80 case ET_MOUSE_PRESSED: | |
| 81 case ET_MOUSE_MOVED: | |
| 82 case ET_MOUSE_DRAGGED: | |
| 83 case ET_MOUSE_RELEASED: { | |
| 84 MouseEvent mouse_event(xev); | |
| 85 delegate_->DispatchEvent(&mouse_event); | |
| 86 break; | |
| 87 } | |
| 88 case ET_MOUSEWHEEL: { | |
| 89 MouseWheelEvent wheel_event(xev); | |
| 90 delegate_->DispatchEvent(&wheel_event); | |
| 91 break; | |
| 92 } | |
| 93 case ET_SCROLL_FLING_START: | |
| 94 case ET_SCROLL_FLING_CANCEL: | |
| 95 case ET_SCROLL: { | |
| 96 ScrollEvent scroll_event(xev); | |
| 97 delegate_->DispatchEvent(&scroll_event); | |
| 98 break; | |
| 99 } | |
| 100 case ET_TOUCH_MOVED: | |
| 101 case ET_TOUCH_PRESSED: | |
| 102 case ET_TOUCH_CANCELLED: | |
| 103 case ET_TOUCH_RELEASED: { | |
| 104 TouchEvent touch_event(xev); | |
| 105 delegate_->DispatchEvent(&touch_event); | |
| 106 break; | |
| 107 } | |
| 108 default: | |
| 109 break; | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 void X11Window::Show() { | |
| 114 if (window_mapped_) | |
| 115 return; | |
| 116 | |
| 117 CHECK(PlatformEventSource::GetInstance()); | 65 CHECK(PlatformEventSource::GetInstance()); |
| 118 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 66 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
| 119 | 67 |
| 120 XSetWindowAttributes swa; | 68 XSetWindowAttributes swa; |
| 121 memset(&swa, 0, sizeof(swa)); | 69 memset(&swa, 0, sizeof(swa)); |
| 122 swa.background_pixmap = None; | 70 swa.background_pixmap = None; |
| 123 swa.override_redirect = False; | 71 swa.override_redirect = False; |
| 124 xwindow_ = XCreateWindow(xdisplay_, | 72 xwindow_ = XCreateWindow(xdisplay_, |
| 125 xroot_window_, | 73 xroot_window_, |
| 126 requested_bounds_.x(), | 74 requested_bounds_.x(), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 XSizeHints size_hints; | 136 XSizeHints size_hints; |
| 189 size_hints.flags = PPosition | PWinGravity; | 137 size_hints.flags = PPosition | PWinGravity; |
| 190 size_hints.x = requested_bounds_.x(); | 138 size_hints.x = requested_bounds_.x(); |
| 191 size_hints.y = requested_bounds_.y(); | 139 size_hints.y = requested_bounds_.y(); |
| 192 // Set StaticGravity so that the window position is not affected by the | 140 // Set StaticGravity so that the window position is not affected by the |
| 193 // frame width when running with window manager. | 141 // frame width when running with window manager. |
| 194 size_hints.win_gravity = StaticGravity; | 142 size_hints.win_gravity = StaticGravity; |
| 195 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); | 143 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); |
| 196 | 144 |
| 197 delegate_->OnAcceleratedWidgetAvailable(xwindow_); | 145 delegate_->OnAcceleratedWidgetAvailable(xwindow_); |
| 146 } |
| 147 |
| 148 void X11Window::Show() { |
| 149 if (window_mapped_) |
| 150 return; |
| 151 if (xwindow_ == None) |
| 152 Create(); |
| 198 | 153 |
| 199 XMapWindow(xdisplay_, xwindow_); | 154 XMapWindow(xdisplay_, xwindow_); |
| 200 | 155 |
| 201 // We now block until our window is mapped. Some X11 APIs will crash and | 156 // We now block until our window is mapped. Some X11 APIs will crash and |
| 202 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | 157 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is |
| 203 // asynchronous. | 158 // asynchronous. |
| 204 if (X11EventSource::GetInstance()) | 159 if (X11EventSource::GetInstance()) |
| 205 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | 160 X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); |
| 206 window_mapped_ = true; | 161 window_mapped_ = true; |
| 207 } | 162 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 199 |
| 245 void X11Window::Minimize() {} | 200 void X11Window::Minimize() {} |
| 246 | 201 |
| 247 void X11Window::Restore() {} | 202 void X11Window::Restore() {} |
| 248 | 203 |
| 249 void X11Window::SetCursor(PlatformCursor cursor) {} | 204 void X11Window::SetCursor(PlatformCursor cursor) {} |
| 250 | 205 |
| 251 void X11Window::MoveCursorTo(const gfx::Point& location) {} | 206 void X11Window::MoveCursorTo(const gfx::Point& location) {} |
| 252 | 207 |
| 253 bool X11Window::CanDispatchEvent(const PlatformEvent& event) { | 208 bool X11Window::CanDispatchEvent(const PlatformEvent& event) { |
| 254 return FindXEventTarget(event) == xwindow_; | 209 return true; |
| 255 } | 210 } |
| 256 | 211 |
| 257 uint32_t X11Window::DispatchEvent(const PlatformEvent& event) { | 212 void X11Window::DispatchXEvent(XEvent* xev) { |
| 258 XEvent* xev = event; | |
| 259 switch (xev->type) { | 213 switch (xev->type) { |
| 260 case EnterNotify: { | |
| 261 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is | |
| 262 // not real mouse move event. | |
| 263 MouseEvent mouse_event(xev); | |
| 264 CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type()); | |
| 265 mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED); | |
| 266 delegate_->DispatchEvent(&mouse_event); | |
| 267 break; | |
| 268 } | |
| 269 case LeaveNotify: { | |
| 270 MouseEvent mouse_event(xev); | |
| 271 delegate_->DispatchEvent(&mouse_event); | |
| 272 break; | |
| 273 } | |
| 274 | |
| 275 case Expose: { | 214 case Expose: { |
| 276 gfx::Rect damage_rect(xev->xexpose.x, | 215 gfx::Rect damage_rect(xev->xexpose.x, |
| 277 xev->xexpose.y, | 216 xev->xexpose.y, |
| 278 xev->xexpose.width, | 217 xev->xexpose.width, |
| 279 xev->xexpose.height); | 218 xev->xexpose.height); |
| 280 delegate_->OnDamageRect(damage_rect); | 219 delegate_->OnDamageRect(damage_rect); |
| 281 break; | 220 break; |
| 282 } | 221 } |
| 283 | 222 |
| 284 case KeyPress: | |
| 285 case KeyRelease: { | |
| 286 KeyEvent key_event(xev); | |
| 287 delegate_->DispatchEvent(&key_event); | |
| 288 break; | |
| 289 } | |
| 290 | |
| 291 case ButtonPress: | |
| 292 case ButtonRelease: { | |
| 293 switch (EventTypeFromNative(xev)) { | |
| 294 case ET_MOUSEWHEEL: { | |
| 295 MouseWheelEvent mouseev(xev); | |
| 296 delegate_->DispatchEvent(&mouseev); | |
| 297 break; | |
| 298 } | |
| 299 case ET_MOUSE_PRESSED: | |
| 300 case ET_MOUSE_RELEASED: { | |
| 301 MouseEvent mouseev(xev); | |
| 302 delegate_->DispatchEvent(&mouseev); | |
| 303 break; | |
| 304 } | |
| 305 case ET_UNKNOWN: | |
| 306 // No event is created for X11-release events for mouse-wheel | |
| 307 // buttons. | |
| 308 break; | |
| 309 default: | |
| 310 NOTREACHED(); | |
| 311 } | |
| 312 break; | |
| 313 } | |
| 314 | |
| 315 case FocusOut: | 223 case FocusOut: |
| 316 if (xev->xfocus.mode != NotifyGrab) | 224 if (xev->xfocus.mode != NotifyGrab) |
| 317 delegate_->OnLostCapture(); | 225 delegate_->OnLostCapture(); |
| 318 break; | 226 break; |
| 319 | 227 |
| 320 case ConfigureNotify: { | 228 case ConfigureNotify: { |
| 321 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 229 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| 322 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 230 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| 323 gfx::Rect bounds(xev->xconfigure.x, | 231 gfx::Rect bounds(xev->xconfigure.x, |
| 324 xev->xconfigure.y, | 232 xev->xconfigure.y, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 341 | 249 |
| 342 XSendEvent(xdisplay_, | 250 XSendEvent(xdisplay_, |
| 343 reply_event.xclient.window, | 251 reply_event.xclient.window, |
| 344 False, | 252 False, |
| 345 SubstructureRedirectMask | SubstructureNotifyMask, | 253 SubstructureRedirectMask | SubstructureNotifyMask, |
| 346 &reply_event); | 254 &reply_event); |
| 347 XFlush(xdisplay_); | 255 XFlush(xdisplay_); |
| 348 } | 256 } |
| 349 break; | 257 break; |
| 350 } | 258 } |
| 259 } |
| 260 } |
| 351 | 261 |
| 352 case GenericEvent: { | 262 uint32_t X11Window::DispatchEvent(const PlatformEvent& event) { |
| 353 ProcessXInput2Event(xev); | 263 if (EventTypeFromNative(event) == ET_X_RAW_EVENT) { |
| 354 break; | 264 XEvent* xev = static_cast<XEvent*>( |
| 355 } | 265 static_cast<CustomEvent*>(event)->generic_event_data()); |
| 266 DispatchXEvent(xev); |
| 267 } else { |
| 268 DispatchEventFromNativeUiEvent( |
| 269 event, base::Bind(&PlatformWindowDelegate::DispatchEvent, |
| 270 base::Unretained(delegate_))); |
| 356 } | 271 } |
| 272 |
| 357 return POST_DISPATCH_STOP_PROPAGATION; | 273 return POST_DISPATCH_STOP_PROPAGATION; |
| 358 } | 274 } |
| 359 | 275 |
| 360 } // namespace ui | 276 } // namespace ui |
| OLD | NEW |