Removed unused icon resources from app_list.
[chromium-blink-merge.git] / ui / aura / window_tree_host_x11.cc
blob7239b048afd79eb9640424a9c128ab3adbf23f06
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
3 // found in the LICENSE file.
5 #include "ui/aura/window_tree_host_x11.h"
7 #include <strings.h>
8 #include <X11/cursorfont.h>
9 #include <X11/extensions/XInput2.h>
10 #include <X11/extensions/Xrandr.h>
11 #include <X11/Xatom.h>
12 #include <X11/Xcursor/Xcursor.h>
13 #include <X11/Xlib.h>
15 #include <algorithm>
16 #include <limits>
17 #include <string>
19 #include "base/basictypes.h"
20 #include "base/command_line.h"
21 #include "base/debug/trace_event.h"
22 #include "base/stl_util.h"
23 #include "base/strings/string_number_conversions.h"
24 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h"
26 #include "base/sys_info.h"
27 #include "ui/aura/client/cursor_client.h"
28 #include "ui/aura/env.h"
29 #include "ui/aura/window.h"
30 #include "ui/aura/window_event_dispatcher.h"
31 #include "ui/base/cursor/cursor.h"
32 #include "ui/base/ui_base_switches.h"
33 #include "ui/base/view_prop.h"
34 #include "ui/base/x/x11_util.h"
35 #include "ui/compositor/compositor.h"
36 #include "ui/compositor/dip_util.h"
37 #include "ui/compositor/layer.h"
38 #include "ui/events/devices/x11/device_data_manager_x11.h"
39 #include "ui/events/devices/x11/device_list_cache_x11.h"
40 #include "ui/events/devices/x11/touch_factory_x11.h"
41 #include "ui/events/event.h"
42 #include "ui/events/event_switches.h"
43 #include "ui/events/event_utils.h"
44 #include "ui/events/keycodes/keyboard_codes.h"
45 #include "ui/events/platform/platform_event_observer.h"
46 #include "ui/events/platform/x11/x11_event_source.h"
47 #include "ui/gfx/screen.h"
49 using std::max;
50 using std::min;
52 namespace aura {
54 namespace {
56 const char* kAtomsToCache[] = {
57 "WM_DELETE_WINDOW",
58 "_NET_WM_PING",
59 "_NET_WM_PID",
60 NULL
63 ::Window FindEventTarget(const base::NativeEvent& xev) {
64 ::Window target = xev->xany.window;
65 if (xev->type == GenericEvent)
66 target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
67 return target;
70 void SelectXInput2EventsForRootWindow(XDisplay* display, ::Window root_window) {
71 CHECK(ui::IsXInput2Available());
72 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
73 memset(mask, 0, sizeof(mask));
75 XISetMask(mask, XI_HierarchyChanged);
77 XIEventMask evmask;
78 evmask.deviceid = XIAllDevices;
79 evmask.mask_len = sizeof(mask);
80 evmask.mask = mask;
81 XISelectEvents(display, root_window, &evmask, 1);
83 #if defined(OS_CHROMEOS)
84 if (base::SysInfo::IsRunningOnChromeOS()) {
85 // It is necessary to listen for touch events on the root window for proper
86 // touch event calibration on Chrome OS, but this is not currently necessary
87 // on the desktop. This seems to fail in some cases (e.g. when logging
88 // in incognito). So select for non-touch events first, and then select for
89 // touch-events (but keep the other events in the mask, i.e. do not memset
90 // |mask| back to 0).
91 // TODO(sad): Figure out why this happens. http://crbug.com/153976
92 XISetMask(mask, XI_TouchBegin);
93 XISetMask(mask, XI_TouchUpdate);
94 XISetMask(mask, XI_TouchEnd);
95 XISelectEvents(display, root_window, &evmask, 1);
97 #endif
100 bool default_override_redirect = false;
102 } // namespace
104 namespace internal {
106 // TODO(miletus) : Move this into DeviceDataManager.
107 // Accomplishes 2 tasks concerning touch event calibration:
108 // 1. Being a message-pump observer,
109 // routes all the touch events to the X root window,
110 // where they can be calibrated later.
111 // 2. Has the Calibrate method that does the actual bezel calibration,
112 // when invoked from X root window's event dispatcher.
113 class TouchEventCalibrate : public ui::PlatformEventObserver {
114 public:
115 TouchEventCalibrate() : left_(0), right_(0), top_(0), bottom_(0) {
116 if (ui::PlatformEventSource::GetInstance())
117 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
118 std::vector<std::string> parts;
119 if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
120 switches::kTouchCalibration),
121 ",",
122 &parts) >= 4) {
123 if (!base::StringToInt(parts[0], &left_))
124 DLOG(ERROR) << "Incorrect left border calibration value passed.";
125 if (!base::StringToInt(parts[1], &right_))
126 DLOG(ERROR) << "Incorrect right border calibration value passed.";
127 if (!base::StringToInt(parts[2], &top_))
128 DLOG(ERROR) << "Incorrect top border calibration value passed.";
129 if (!base::StringToInt(parts[3], &bottom_))
130 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
134 ~TouchEventCalibrate() override {
135 if (ui::PlatformEventSource::GetInstance())
136 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
139 // Modify the location of the |event|,
140 // expanding it from |bounds| to (|bounds| + bezels).
141 // Required when touchscreen is bigger than screen (i.e. has bezels),
142 // because we receive events in touchscreen coordinates,
143 // which need to be expanded when converting to screen coordinates,
144 // so that location on bezels will be outside of screen area.
145 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
146 int x = event->x();
147 int y = event->y();
149 if (!left_ && !right_ && !top_ && !bottom_)
150 return;
152 const int resolution_x = bounds.width();
153 const int resolution_y = bounds.height();
154 // The "grace area" (10% in this case) is to make it easier for the user to
155 // navigate to the corner.
156 const double kGraceAreaFraction = 0.1;
157 if (left_ || right_) {
158 // Offset the x position to the real
159 x -= left_;
160 // Check if we are in the grace area of the left side.
161 // Note: We might not want to do this when the gesture is locked?
162 if (x < 0 && x > -left_ * kGraceAreaFraction)
163 x = 0;
164 // Check if we are in the grace area of the right side.
165 // Note: We might not want to do this when the gesture is locked?
166 if (x > resolution_x - left_ &&
167 x < resolution_x - left_ + right_ * kGraceAreaFraction)
168 x = resolution_x - left_;
169 // Scale the screen area back to the full resolution of the screen.
170 x = (x * resolution_x) / (resolution_x - (right_ + left_));
172 if (top_ || bottom_) {
173 // When there is a top bezel we add our border,
174 y -= top_;
176 // Check if we are in the grace area of the top side.
177 // Note: We might not want to do this when the gesture is locked?
178 if (y < 0 && y > -top_ * kGraceAreaFraction)
179 y = 0;
181 // Check if we are in the grace area of the bottom side.
182 // Note: We might not want to do this when the gesture is locked?
183 if (y > resolution_y - top_ &&
184 y < resolution_y - top_ + bottom_ * kGraceAreaFraction)
185 y = resolution_y - top_;
186 // Scale the screen area back to the full resolution of the screen.
187 y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
190 // Set the modified coordinate back to the event.
191 if (event->root_location() == event->location()) {
192 // Usually those will be equal,
193 // if not, I am not sure what the correct value should be.
194 event->set_root_location(gfx::Point(x, y));
196 event->set_location(gfx::Point(x, y));
199 private:
200 // ui::PlatformEventObserver:
201 void WillProcessEvent(const ui::PlatformEvent& event) override {
202 if (event->type == GenericEvent &&
203 (event->xgeneric.evtype == XI_TouchBegin ||
204 event->xgeneric.evtype == XI_TouchUpdate ||
205 event->xgeneric.evtype == XI_TouchEnd)) {
206 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
207 xievent->event = xievent->root;
208 xievent->event_x = xievent->root_x;
209 xievent->event_y = xievent->root_y;
213 void DidProcessEvent(const ui::PlatformEvent& event) override {}
215 // The difference in screen's native resolution pixels between
216 // the border of the touchscreen and the border of the screen,
217 // aka bezel sizes.
218 int left_;
219 int right_;
220 int top_;
221 int bottom_;
223 DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate);
226 } // namespace internal
228 ////////////////////////////////////////////////////////////////////////////////
229 // WindowTreeHostX11
231 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds)
232 : xdisplay_(gfx::GetXDisplay()),
233 xwindow_(0),
234 x_root_window_(DefaultRootWindow(xdisplay_)),
235 current_cursor_(ui::kCursorNull),
236 window_mapped_(false),
237 bounds_(bounds),
238 touch_calibrate_(new internal::TouchEventCalibrate),
239 atom_cache_(xdisplay_, kAtomsToCache) {
240 XSetWindowAttributes swa;
241 memset(&swa, 0, sizeof(swa));
242 swa.background_pixmap = None;
243 swa.override_redirect = default_override_redirect;
244 xwindow_ = XCreateWindow(
245 xdisplay_, x_root_window_,
246 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
247 0, // border width
248 CopyFromParent, // depth
249 InputOutput,
250 CopyFromParent, // visual
251 CWBackPixmap | CWOverrideRedirect,
252 &swa);
253 if (ui::PlatformEventSource::GetInstance())
254 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
256 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
257 KeyPressMask | KeyReleaseMask |
258 EnterWindowMask | LeaveWindowMask |
259 ExposureMask | VisibilityChangeMask |
260 StructureNotifyMask | PropertyChangeMask |
261 PointerMotionMask;
262 XSelectInput(xdisplay_, xwindow_, event_mask);
263 XFlush(xdisplay_);
265 if (ui::IsXInput2Available()) {
266 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
267 SelectXInput2EventsForRootWindow(xdisplay_, x_root_window_);
270 // TODO(erg): We currently only request window deletion events. We also
271 // should listen for activation events and anything else that GTK+ listens
272 // for, and do something useful.
273 ::Atom protocols[2];
274 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
275 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
276 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
278 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
279 // the desktop environment.
280 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
282 // Likewise, the X server needs to know this window's pid so it knows which
283 // program to kill if the window hangs.
284 // XChangeProperty() expects "pid" to be long.
285 COMPILE_ASSERT(sizeof(long) >= sizeof(pid_t), pid_t_bigger_than_long);
286 long pid = getpid();
287 XChangeProperty(xdisplay_,
288 xwindow_,
289 atom_cache_.GetAtom("_NET_WM_PID"),
290 XA_CARDINAL,
292 PropModeReplace,
293 reinterpret_cast<unsigned char*>(&pid), 1);
295 // Allow subclasses to create and cache additional atoms.
296 atom_cache_.allow_uncached_atoms();
298 XRRSelectInput(xdisplay_, x_root_window_,
299 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
300 CreateCompositor(GetAcceleratedWidget());
303 WindowTreeHostX11::~WindowTreeHostX11() {
304 if (ui::PlatformEventSource::GetInstance())
305 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
307 DestroyCompositor();
308 DestroyDispatcher();
309 XDestroyWindow(xdisplay_, xwindow_);
312 bool WindowTreeHostX11::CanDispatchEvent(const ui::PlatformEvent& event) {
313 ::Window target = FindEventTarget(event);
314 return target == xwindow_ || target == x_root_window_;
317 uint32_t WindowTreeHostX11::DispatchEvent(const ui::PlatformEvent& event) {
318 XEvent* xev = event;
319 if (FindEventTarget(xev) == x_root_window_) {
320 if (xev->type == GenericEvent)
321 DispatchXI2Event(xev);
322 return ui::POST_DISPATCH_NONE;
325 if (xev->type == MotionNotify) {
326 // Discard all but the most recent motion event that targets the same
327 // window with unchanged state.
328 XEvent last_event;
329 while (XPending(xev->xany.display)) {
330 XEvent next_event;
331 XPeekEvent(xev->xany.display, &next_event);
332 if (next_event.type == MotionNotify &&
333 next_event.xmotion.window == xev->xmotion.window &&
334 next_event.xmotion.subwindow == xev->xmotion.subwindow &&
335 next_event.xmotion.state == xev->xmotion.state) {
336 XNextEvent(xev->xany.display, &last_event);
337 xev = &last_event;
338 } else {
339 break;
344 if ((xev->type == EnterNotify || xev->type == LeaveNotify) &&
345 xev->xcrossing.detail == NotifyInferior) {
346 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|.
347 // NativeViewGLSurfaceGLX adds a child to |xwindow_|.
348 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is
349 // necessary. crbug.com/385716
350 return ui::POST_DISPATCH_STOP_PROPAGATION;
353 if (xev->type == EnterNotify ||
354 xev->type == LeaveNotify ||
355 xev->type == KeyPress ||
356 xev->type == KeyRelease ||
357 xev->type == ButtonPress ||
358 xev->type == ButtonRelease ||
359 xev->type == MotionNotify) {
360 switch (ui::EventTypeFromNative(xev)) {
361 case ui::ET_KEY_PRESSED:
362 case ui::ET_KEY_RELEASED: {
363 ui::KeyEvent keydown_event(xev);
364 SendEventToProcessor(&keydown_event);
365 break;
367 case ui::ET_MOUSE_MOVED:
368 case ui::ET_MOUSE_DRAGGED:
369 case ui::ET_MOUSE_ENTERED:
370 case ui::ET_MOUSE_EXITED:
371 case ui::ET_MOUSE_PRESSED:
372 case ui::ET_MOUSE_RELEASED: {
373 ui::MouseEvent mouse_event(xev);
374 if (xev->type == EnterNotify) {
375 aura::Window* root_window = window();
376 client::CursorClient* cursor_client =
377 client::GetCursorClient(root_window);
378 if (cursor_client) {
379 const gfx::Display display = gfx::Screen::GetScreenFor(
380 root_window)->GetDisplayNearestWindow(root_window);
381 cursor_client->SetDisplay(display);
383 // EnterNotify creates ET_MOUSE_MOVE. Mark as synthesized as this is
384 // not a real mouse move event.
385 mouse_event.set_flags(mouse_event.flags() | ui::EF_IS_SYNTHESIZED);
388 TranslateAndDispatchLocatedEvent(&mouse_event);
389 break;
391 case ui::ET_MOUSEWHEEL: {
392 ui::MouseWheelEvent mouseev(xev);
393 TranslateAndDispatchLocatedEvent(&mouseev);
394 break;
396 case ui::ET_UNKNOWN:
397 // No event is created for X11-release events for mouse-wheel buttons.
398 break;
399 default:
400 NOTREACHED();
402 return ui::POST_DISPATCH_STOP_PROPAGATION;
405 switch (xev->type) {
406 case Expose: {
407 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y,
408 xev->xexpose.width, xev->xexpose.height);
409 compositor()->ScheduleRedrawRect(damage_rect);
410 break;
412 case FocusOut:
413 if (xev->xfocus.mode != NotifyGrab)
414 OnHostLostWindowCapture();
415 break;
416 case ConfigureNotify: {
417 DCHECK_EQ(xwindow_, xev->xconfigure.event);
418 DCHECK_EQ(xwindow_, xev->xconfigure.window);
419 // It's possible that the X window may be resized by some other means
420 // than from within aura (e.g. the X window manager can change the
421 // size). Make sure the root window size is maintained properly.
422 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
423 xev->xconfigure.width, xev->xconfigure.height);
424 bool size_changed = bounds_.size() != bounds.size();
425 bool origin_changed = bounds_.origin() != bounds.origin();
426 bounds_ = bounds;
427 OnConfigureNotify();
428 if (size_changed)
429 OnHostResized(bounds.size());
430 if (origin_changed)
431 OnHostMoved(bounds_.origin());
432 break;
434 case GenericEvent:
435 DispatchXI2Event(xev);
436 break;
437 case ClientMessage: {
438 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
439 if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
440 // We have received a close message from the window manager.
441 OnHostCloseRequested();
442 } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
443 XEvent reply_event = *xev;
444 reply_event.xclient.window = x_root_window_;
446 XSendEvent(xdisplay_,
447 reply_event.xclient.window,
448 False,
449 SubstructureRedirectMask | SubstructureNotifyMask,
450 &reply_event);
451 XFlush(xdisplay_);
453 break;
455 case MappingNotify: {
456 switch (xev->xmapping.request) {
457 case MappingModifier:
458 case MappingKeyboard:
459 XRefreshKeyboardMapping(&xev->xmapping);
460 break;
461 case MappingPointer:
462 ui::DeviceDataManagerX11::GetInstance()->UpdateButtonMap();
463 break;
464 default:
465 NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request;
466 break;
468 break;
471 return ui::POST_DISPATCH_STOP_PROPAGATION;
474 ui::EventSource* WindowTreeHostX11::GetEventSource() {
475 return this;
478 gfx::AcceleratedWidget WindowTreeHostX11::GetAcceleratedWidget() {
479 return xwindow_;
482 void WindowTreeHostX11::Show() {
483 if (!window_mapped_) {
484 // Before we map the window, set size hints. Otherwise, some window managers
485 // will ignore toplevel XMoveWindow commands.
486 XSizeHints size_hints;
487 size_hints.flags = PPosition | PWinGravity;
488 size_hints.x = bounds_.x();
489 size_hints.y = bounds_.y();
490 // Set StaticGravity so that the window position is not affected by the
491 // frame width when running with window manager.
492 size_hints.win_gravity = StaticGravity;
493 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
495 XMapWindow(xdisplay_, xwindow_);
497 // We now block until our window is mapped. Some X11 APIs will crash and
498 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
499 // asynchronous.
500 if (ui::X11EventSource::GetInstance())
501 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
502 window_mapped_ = true;
506 void WindowTreeHostX11::Hide() {
507 if (window_mapped_) {
508 XWithdrawWindow(xdisplay_, xwindow_, 0);
509 window_mapped_ = false;
513 gfx::Rect WindowTreeHostX11::GetBounds() const {
514 return bounds_;
517 void WindowTreeHostX11::SetBounds(const gfx::Rect& bounds) {
518 // Even if the host window's size doesn't change, aura's root window
519 // size, which is in DIP, changes when the scale changes.
520 float current_scale = compositor()->device_scale_factor();
521 float new_scale = gfx::Screen::GetScreenFor(window())->
522 GetDisplayNearestWindow(window()).device_scale_factor();
523 bool origin_changed = bounds_.origin() != bounds.origin();
524 bool size_changed = bounds_.size() != bounds.size();
525 XWindowChanges changes = {0};
526 unsigned value_mask = 0;
528 if (size_changed) {
529 changes.width = bounds.width();
530 changes.height = bounds.height();
531 value_mask = CWHeight | CWWidth;
534 if (origin_changed) {
535 changes.x = bounds.x();
536 changes.y = bounds.y();
537 value_mask |= CWX | CWY;
539 if (value_mask)
540 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
542 // Assume that the resize will go through as requested, which should be the
543 // case if we're running without a window manager. If there's a window
544 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
545 // (possibly synthetic) ConfigureNotify about the actual size and correct
546 // |bounds_| later.
547 bounds_ = bounds;
548 if (origin_changed)
549 OnHostMoved(bounds.origin());
550 if (size_changed || current_scale != new_scale) {
551 OnHostResized(bounds.size());
552 } else {
553 window()->SchedulePaintInRect(window()->bounds());
557 gfx::Point WindowTreeHostX11::GetLocationOnNativeScreen() const {
558 return bounds_.origin();
561 void WindowTreeHostX11::SetCapture() {
562 // TODO(oshima): Grab x input.
565 void WindowTreeHostX11::ReleaseCapture() {
566 // TODO(oshima): Release x input.
569 void WindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) {
570 if (cursor == current_cursor_)
571 return;
572 current_cursor_ = cursor;
573 SetCursorInternal(cursor);
576 void WindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) {
577 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
578 bounds_.x() + location.x(),
579 bounds_.y() + location.y());
582 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
585 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() {
586 return dispatcher();
589 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) {
590 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
591 XEvent* xev = event;
592 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
593 if (!factory->ShouldProcessXI2Event(xev))
594 return;
596 TRACE_EVENT1("input", "WindowTreeHostX11::DispatchXI2Event",
597 "event_latency_us",
598 (ui::EventTimeForNow() - ui::EventTimeFromNative(event)).
599 InMicroseconds());
601 int num_coalesced = 0;
602 XEvent last_event;
603 if (xev->xgeneric.evtype == XI_Motion) {
604 // If this is a motion event, we want to coalesce all pending motion
605 // events that are at the top of the queue. Note, we don't coalesce
606 // touch update events here.
607 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
608 if (num_coalesced > 0)
609 xev = &last_event;
611 ui::EventType type = ui::EventTypeFromNative(xev);
613 switch (type) {
614 case ui::ET_TOUCH_MOVED:
615 case ui::ET_TOUCH_PRESSED:
616 case ui::ET_TOUCH_CANCELLED:
617 case ui::ET_TOUCH_RELEASED: {
618 ui::TouchEvent touchev(xev);
619 if (ui::DeviceDataManagerX11::GetInstance()->TouchEventNeedsCalibrate(
620 xiev->deviceid)) {
621 touch_calibrate_->Calibrate(&touchev, bounds_);
623 TranslateAndDispatchLocatedEvent(&touchev);
624 break;
626 case ui::ET_MOUSE_MOVED:
627 case ui::ET_MOUSE_DRAGGED:
628 case ui::ET_MOUSE_PRESSED:
629 case ui::ET_MOUSE_RELEASED:
630 case ui::ET_MOUSE_ENTERED:
631 case ui::ET_MOUSE_EXITED: {
632 ui::MouseEvent mouseev(xev);
633 TranslateAndDispatchLocatedEvent(&mouseev);
634 break;
636 case ui::ET_MOUSEWHEEL: {
637 ui::MouseWheelEvent mouseev(xev);
638 TranslateAndDispatchLocatedEvent(&mouseev);
639 break;
641 case ui::ET_SCROLL_FLING_START:
642 case ui::ET_SCROLL_FLING_CANCEL:
643 case ui::ET_SCROLL: {
644 ui::ScrollEvent scrollev(xev);
645 SendEventToProcessor(&scrollev);
646 break;
648 case ui::ET_KEY_PRESSED:
649 case ui::ET_KEY_RELEASED: {
650 ui::KeyEvent key_event(xev);
651 SendEventToProcessor(&key_event);
652 break;
654 case ui::ET_UMA_DATA:
655 break;
656 case ui::ET_UNKNOWN:
657 break;
658 default:
659 NOTREACHED();
662 // If we coalesced an event we need to free its cookie.
663 if (num_coalesced > 0)
664 XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
667 void WindowTreeHostX11::SetCursorInternal(gfx::NativeCursor cursor) {
668 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
671 void WindowTreeHostX11::OnConfigureNotify() {}
673 void WindowTreeHostX11::TranslateAndDispatchLocatedEvent(
674 ui::LocatedEvent* event) {
675 SendEventToProcessor(event);
678 // static
679 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
680 return new WindowTreeHostX11(bounds);
683 // static
684 gfx::Size WindowTreeHost::GetNativeScreenSize() {
685 ::XDisplay* xdisplay = gfx::GetXDisplay();
686 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
689 namespace test {
691 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
692 default_override_redirect = override_redirect;
695 } // namespace test
696 } // namespace aura