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

Side by Side Diff: ui/aura/window_tree_host_x11.cc

Issue 201573015: Introdcue AshWindowTreeHost and move ash/chrome specific code in WTH to ash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « ui/aura/window_tree_host_x11.h ('k') | ui/aura/window_tree_host_x11_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/aura/window_tree_host_x11.h" 5 #include "ui/aura/window_tree_host_x11.h"
6 6
7 #include <strings.h> 7 #include <strings.h>
8 #include <X11/cursorfont.h> 8 #include <X11/cursorfont.h>
9 #include <X11/extensions/Xfixes.h>
10 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
11 #include <X11/extensions/Xrandr.h> 10 #include <X11/extensions/Xrandr.h>
12 #include <X11/Xatom.h> 11 #include <X11/Xatom.h>
13 #include <X11/Xcursor/Xcursor.h> 12 #include <X11/Xcursor/Xcursor.h>
14 #include <X11/Xlib.h> 13 #include <X11/Xlib.h>
15 14
16 #include <algorithm> 15 #include <algorithm>
17 #include <limits> 16 #include <limits>
18 #include <string> 17 #include <string>
19 18
20 #include "base/basictypes.h" 19 #include "base/basictypes.h"
21 #include "base/command_line.h" 20 #include "base/command_line.h"
22 #include "base/debug/trace_event.h" 21 #include "base/debug/trace_event.h"
23 #include "base/stl_util.h" 22 #include "base/stl_util.h"
24 #include "base/strings/string_number_conversions.h" 23 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
27 #include "base/sys_info.h" 26 #include "base/sys_info.h"
28 #include "ui/aura/client/cursor_client.h" 27 #include "ui/aura/client/cursor_client.h"
29 #include "ui/aura/client/screen_position_client.h"
30 #include "ui/aura/env.h" 28 #include "ui/aura/env.h"
29 #include "ui/aura/window.h"
31 #include "ui/aura/window_event_dispatcher.h" 30 #include "ui/aura/window_event_dispatcher.h"
32 #include "ui/base/cursor/cursor.h" 31 #include "ui/base/cursor/cursor.h"
33 #include "ui/base/ui_base_switches.h" 32 #include "ui/base/ui_base_switches.h"
34 #include "ui/base/view_prop.h" 33 #include "ui/base/view_prop.h"
35 #include "ui/base/x/x11_util.h" 34 #include "ui/base/x/x11_util.h"
36 #include "ui/compositor/compositor.h" 35 #include "ui/compositor/compositor.h"
37 #include "ui/compositor/dip_util.h" 36 #include "ui/compositor/dip_util.h"
38 #include "ui/compositor/layer.h" 37 #include "ui/compositor/layer.h"
39 #include "ui/events/event.h" 38 #include "ui/events/event.h"
40 #include "ui/events/event_switches.h" 39 #include "ui/events/event_switches.h"
41 #include "ui/events/event_utils.h" 40 #include "ui/events/event_utils.h"
42 #include "ui/events/keycodes/keyboard_codes.h" 41 #include "ui/events/keycodes/keyboard_codes.h"
43 #include "ui/events/platform/platform_event_observer.h"
44 #include "ui/events/platform/x11/x11_event_source.h" 42 #include "ui/events/platform/x11/x11_event_source.h"
45 #include "ui/events/x/device_data_manager.h" 43 #include "ui/events/x/device_data_manager.h"
46 #include "ui/events/x/device_list_cache_x.h" 44 #include "ui/events/x/device_list_cache_x.h"
47 #include "ui/events/x/touch_factory_x11.h" 45 #include "ui/events/x/touch_factory_x11.h"
48 #include "ui/gfx/screen.h" 46 #include "ui/gfx/screen.h"
49 47
50 using std::max; 48 using std::max;
51 using std::min; 49 using std::min;
52 50
53 namespace aura { 51 namespace aura {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 XISetMask(mask, XI_TouchEnd); 99 XISetMask(mask, XI_TouchEnd);
102 XISelectEvents(display, root_window, &evmask, 1); 100 XISelectEvents(display, root_window, &evmask, 1);
103 } 101 }
104 #endif 102 #endif
105 } 103 }
106 104
107 bool default_override_redirect = false; 105 bool default_override_redirect = false;
108 106
109 } // namespace 107 } // namespace
110 108
111 namespace internal {
112
113 // Accomplishes 2 tasks concerning touch event calibration:
114 // 1. Being a message-pump observer,
115 // routes all the touch events to the X root window,
116 // where they can be calibrated later.
117 // 2. Has the Calibrate method that does the actual bezel calibration,
118 // when invoked from X root window's event dispatcher.
119 class TouchEventCalibrate : public ui::PlatformEventObserver {
120 public:
121 TouchEventCalibrate()
122 : left_(0),
123 right_(0),
124 top_(0),
125 bottom_(0) {
126 if (ui::PlatformEventSource::GetInstance())
127 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
128 #if defined(USE_XI2_MT)
129 std::vector<std::string> parts;
130 if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
131 switches::kTouchCalibration), ",", &parts) >= 4) {
132 if (!base::StringToInt(parts[0], &left_))
133 DLOG(ERROR) << "Incorrect left border calibration value passed.";
134 if (!base::StringToInt(parts[1], &right_))
135 DLOG(ERROR) << "Incorrect right border calibration value passed.";
136 if (!base::StringToInt(parts[2], &top_))
137 DLOG(ERROR) << "Incorrect top border calibration value passed.";
138 if (!base::StringToInt(parts[3], &bottom_))
139 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
140 }
141 #endif // defined(USE_XI2_MT)
142 }
143
144 virtual ~TouchEventCalibrate() {
145 if (ui::PlatformEventSource::GetInstance())
146 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
147 }
148
149 // Modify the location of the |event|,
150 // expanding it from |bounds| to (|bounds| + bezels).
151 // Required when touchscreen is bigger than screen (i.e. has bezels),
152 // because we receive events in touchscreen coordinates,
153 // which need to be expanded when converting to screen coordinates,
154 // so that location on bezels will be outside of screen area.
155 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
156 #if defined(USE_XI2_MT)
157 int x = event->x();
158 int y = event->y();
159
160 if (!left_ && !right_ && !top_ && !bottom_)
161 return;
162
163 const int resolution_x = bounds.width();
164 const int resolution_y = bounds.height();
165 // The "grace area" (10% in this case) is to make it easier for the user to
166 // navigate to the corner.
167 const double kGraceAreaFraction = 0.1;
168 if (left_ || right_) {
169 // Offset the x position to the real
170 x -= left_;
171 // Check if we are in the grace area of the left side.
172 // Note: We might not want to do this when the gesture is locked?
173 if (x < 0 && x > -left_ * kGraceAreaFraction)
174 x = 0;
175 // Check if we are in the grace area of the right side.
176 // Note: We might not want to do this when the gesture is locked?
177 if (x > resolution_x - left_ &&
178 x < resolution_x - left_ + right_ * kGraceAreaFraction)
179 x = resolution_x - left_;
180 // Scale the screen area back to the full resolution of the screen.
181 x = (x * resolution_x) / (resolution_x - (right_ + left_));
182 }
183 if (top_ || bottom_) {
184 // When there is a top bezel we add our border,
185 y -= top_;
186
187 // Check if we are in the grace area of the top side.
188 // Note: We might not want to do this when the gesture is locked?
189 if (y < 0 && y > -top_ * kGraceAreaFraction)
190 y = 0;
191
192 // Check if we are in the grace area of the bottom side.
193 // Note: We might not want to do this when the gesture is locked?
194 if (y > resolution_y - top_ &&
195 y < resolution_y - top_ + bottom_ * kGraceAreaFraction)
196 y = resolution_y - top_;
197 // Scale the screen area back to the full resolution of the screen.
198 y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
199 }
200
201 // Set the modified coordinate back to the event.
202 if (event->root_location() == event->location()) {
203 // Usually those will be equal,
204 // if not, I am not sure what the correct value should be.
205 event->set_root_location(gfx::Point(x, y));
206 }
207 event->set_location(gfx::Point(x, y));
208 #endif // defined(USE_XI2_MT)
209 }
210
211 private:
212 // ui::PlatformEventObserver:
213 virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE {
214 #if defined(USE_XI2_MT)
215 if (event->type == GenericEvent &&
216 (event->xgeneric.evtype == XI_TouchBegin ||
217 event->xgeneric.evtype == XI_TouchUpdate ||
218 event->xgeneric.evtype == XI_TouchEnd)) {
219 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
220 xievent->event = xievent->root;
221 xievent->event_x = xievent->root_x;
222 xievent->event_y = xievent->root_y;
223 }
224 #endif // defined(USE_XI2_MT)
225 }
226
227 virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE {}
228
229 // The difference in screen's native resolution pixels between
230 // the border of the touchscreen and the border of the screen,
231 // aka bezel sizes.
232 int left_;
233 int right_;
234 int top_;
235 int bottom_;
236
237 DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate);
238 };
239
240 } // namespace internal
241
242 //////////////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////////////////
243 // WindowTreeHostX11 110 // WindowTreeHostX11
244 111
245 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds) 112 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds)
246 : xdisplay_(gfx::GetXDisplay()), 113 : xdisplay_(gfx::GetXDisplay()),
247 xwindow_(0), 114 xwindow_(0),
248 x_root_window_(DefaultRootWindow(xdisplay_)), 115 x_root_window_(DefaultRootWindow(xdisplay_)),
249 current_cursor_(ui::kCursorNull), 116 current_cursor_(ui::kCursorNull),
250 window_mapped_(false), 117 window_mapped_(false),
251 bounds_(bounds), 118 bounds_(bounds),
252 is_internal_display_(false),
253 touch_calibrate_(new internal::TouchEventCalibrate),
254 atom_cache_(xdisplay_, kAtomsToCache) { 119 atom_cache_(xdisplay_, kAtomsToCache) {
255 XSetWindowAttributes swa; 120 XSetWindowAttributes swa;
256 memset(&swa, 0, sizeof(swa)); 121 memset(&swa, 0, sizeof(swa));
257 swa.background_pixmap = None; 122 swa.background_pixmap = None;
258 swa.override_redirect = default_override_redirect; 123 swa.override_redirect = default_override_redirect;
259 xwindow_ = XCreateWindow( 124 xwindow_ = XCreateWindow(
260 xdisplay_, x_root_window_, 125 xdisplay_, x_root_window_,
261 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 126 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
262 0, // border width 127 0, // border width
263 CopyFromParent, // depth 128 CopyFromParent, // depth
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 XChangeProperty(xdisplay_, 167 XChangeProperty(xdisplay_,
303 xwindow_, 168 xwindow_,
304 atom_cache_.GetAtom("_NET_WM_PID"), 169 atom_cache_.GetAtom("_NET_WM_PID"),
305 XA_CARDINAL, 170 XA_CARDINAL,
306 32, 171 32,
307 PropModeReplace, 172 PropModeReplace,
308 reinterpret_cast<unsigned char*>(&pid), 1); 173 reinterpret_cast<unsigned char*>(&pid), 1);
309 174
310 XRRSelectInput(xdisplay_, x_root_window_, 175 XRRSelectInput(xdisplay_, x_root_window_,
311 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 176 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
312 Env::GetInstance()->AddObserver(this);
313 CreateCompositor(GetAcceleratedWidget()); 177 CreateCompositor(GetAcceleratedWidget());
314 } 178 }
315 179
316 WindowTreeHostX11::~WindowTreeHostX11() { 180 WindowTreeHostX11::~WindowTreeHostX11() {
317 Env::GetInstance()->RemoveObserver(this);
318 if (ui::PlatformEventSource::GetInstance()) 181 if (ui::PlatformEventSource::GetInstance())
319 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); 182 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
320 183
321 UnConfineCursor();
322
323 DestroyCompositor(); 184 DestroyCompositor();
324 DestroyDispatcher(); 185 DestroyDispatcher();
325 XDestroyWindow(xdisplay_, xwindow_); 186 XDestroyWindow(xdisplay_, xwindow_);
326 } 187 }
327 188
328 bool WindowTreeHostX11::CanDispatchEvent(const ui::PlatformEvent& event) { 189 bool WindowTreeHostX11::CanDispatchEvent(const ui::PlatformEvent& event) {
329 ::Window target = FindEventTarget(event); 190 ::Window target = FindEventTarget(event);
330 return target == xwindow_ || target == x_root_window_; 191 return target == xwindow_ || target == x_root_window_;
331 } 192 }
332 193
(...skipping 12 matching lines...) Expand all
345 client::GetCursorClient(root_window); 206 client::GetCursorClient(root_window);
346 if (cursor_client) { 207 if (cursor_client) {
347 const gfx::Display display = gfx::Screen::GetScreenFor(root_window)-> 208 const gfx::Display display = gfx::Screen::GetScreenFor(root_window)->
348 GetDisplayNearestWindow(root_window); 209 GetDisplayNearestWindow(root_window);
349 cursor_client->SetDisplay(display); 210 cursor_client->SetDisplay(display);
350 } 211 }
351 ui::MouseEvent mouse_event(xev); 212 ui::MouseEvent mouse_event(xev);
352 // EnterNotify creates ET_MOUSE_MOVE. Mark as synthesized as this is not 213 // EnterNotify creates ET_MOUSE_MOVE. Mark as synthesized as this is not
353 // real mouse move event. 214 // real mouse move event.
354 mouse_event.set_flags(mouse_event.flags() | ui::EF_IS_SYNTHESIZED); 215 mouse_event.set_flags(mouse_event.flags() | ui::EF_IS_SYNTHESIZED);
355 TranslateAndDispatchMouseEvent(&mouse_event); 216 TranslateAndDispatchLocatedEvent(&mouse_event);
356 break; 217 break;
357 } 218 }
358 case LeaveNotify: { 219 case LeaveNotify: {
359 ui::MouseEvent mouse_event(xev); 220 ui::MouseEvent mouse_event(xev);
360 TranslateAndDispatchMouseEvent(&mouse_event); 221 TranslateAndDispatchLocatedEvent(&mouse_event);
361 break; 222 break;
362 } 223 }
363 case Expose: { 224 case Expose: {
364 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, 225 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y,
365 xev->xexpose.width, xev->xexpose.height); 226 xev->xexpose.width, xev->xexpose.height);
366 compositor()->ScheduleRedrawRect(damage_rect); 227 compositor()->ScheduleRedrawRect(damage_rect);
367 break; 228 break;
368 } 229 }
369 case KeyPress: { 230 case KeyPress: {
370 ui::KeyEvent keydown_event(xev, false); 231 ui::KeyEvent keydown_event(xev, false);
371 SendEventToProcessor(&keydown_event); 232 SendEventToProcessor(&keydown_event);
372 break; 233 break;
373 } 234 }
374 case KeyRelease: { 235 case KeyRelease: {
375 ui::KeyEvent keyup_event(xev, false); 236 ui::KeyEvent keyup_event(xev, false);
376 SendEventToProcessor(&keyup_event); 237 SendEventToProcessor(&keyup_event);
377 break; 238 break;
378 } 239 }
379 case ButtonPress: 240 case ButtonPress:
380 case ButtonRelease: { 241 case ButtonRelease: {
381 switch (ui::EventTypeFromNative(xev)) { 242 switch (ui::EventTypeFromNative(xev)) {
382 case ui::ET_MOUSEWHEEL: { 243 case ui::ET_MOUSEWHEEL: {
383 ui::MouseWheelEvent mouseev(xev); 244 ui::MouseWheelEvent mouseev(xev);
384 TranslateAndDispatchMouseEvent(&mouseev); 245 TranslateAndDispatchLocatedEvent(&mouseev);
385 break; 246 break;
386 } 247 }
387 case ui::ET_MOUSE_PRESSED: 248 case ui::ET_MOUSE_PRESSED:
388 case ui::ET_MOUSE_RELEASED: { 249 case ui::ET_MOUSE_RELEASED: {
389 ui::MouseEvent mouseev(xev); 250 ui::MouseEvent mouseev(xev);
390 TranslateAndDispatchMouseEvent(&mouseev); 251 TranslateAndDispatchLocatedEvent(&mouseev);
391 break; 252 break;
392 } 253 }
393 case ui::ET_UNKNOWN: 254 case ui::ET_UNKNOWN:
394 // No event is created for X11-release events for mouse-wheel buttons. 255 // No event is created for X11-release events for mouse-wheel buttons.
395 break; 256 break;
396 default: 257 default:
397 NOTREACHED(); 258 NOTREACHED();
398 } 259 }
399 break; 260 break;
400 } 261 }
401 case FocusOut: 262 case FocusOut:
402 if (xev->xfocus.mode != NotifyGrab) 263 if (xev->xfocus.mode != NotifyGrab)
403 OnHostLostWindowCapture(); 264 OnHostLostWindowCapture();
404 break; 265 break;
405 case ConfigureNotify: { 266 case ConfigureNotify: {
406 DCHECK_EQ(xwindow_, xev->xconfigure.event); 267 DCHECK_EQ(xwindow_, xev->xconfigure.event);
407 DCHECK_EQ(xwindow_, xev->xconfigure.window); 268 DCHECK_EQ(xwindow_, xev->xconfigure.window);
408 // It's possible that the X window may be resized by some other means 269 // It's possible that the X window may be resized by some other means
409 // than from within aura (e.g. the X window manager can change the 270 // than from within aura (e.g. the X window manager can change the
410 // size). Make sure the root window size is maintained properly. 271 // size). Make sure the root window size is maintained properly.
411 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, 272 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
412 xev->xconfigure.width, xev->xconfigure.height); 273 xev->xconfigure.width, xev->xconfigure.height);
413 bool size_changed = bounds_.size() != bounds.size(); 274 bool size_changed = bounds_.size() != bounds.size();
414 bool origin_changed = bounds_.origin() != bounds.origin(); 275 bool origin_changed = bounds_.origin() != bounds.origin();
415 bounds_ = bounds; 276 bounds_ = bounds;
416 UpdateIsInternalDisplay(); 277 OnConfigureNotify();
417 // Always update barrier and mouse location because |bounds_| might
418 // have already been updated in |SetBounds|.
419 if (pointer_barriers_) {
420 UnConfineCursor();
421 ConfineCursorToRootWindow();
422 }
423 if (size_changed) 278 if (size_changed)
424 OnHostResized(bounds.size()); 279 OnHostResized(bounds.size());
425 if (origin_changed) 280 if (origin_changed)
426 OnHostMoved(bounds_.origin()); 281 OnHostMoved(bounds_.origin());
427 break; 282 break;
428 } 283 }
429 case GenericEvent: 284 case GenericEvent:
430 DispatchXI2Event(xev); 285 DispatchXI2Event(xev);
431 break; 286 break;
432 case ClientMessage: { 287 case ClientMessage: {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 next_event.xmotion.subwindow == xev->xmotion.subwindow && 328 next_event.xmotion.subwindow == xev->xmotion.subwindow &&
474 next_event.xmotion.state == xev->xmotion.state) { 329 next_event.xmotion.state == xev->xmotion.state) {
475 XNextEvent(xev->xany.display, &last_event); 330 XNextEvent(xev->xany.display, &last_event);
476 xev = &last_event; 331 xev = &last_event;
477 } else { 332 } else {
478 break; 333 break;
479 } 334 }
480 } 335 }
481 336
482 ui::MouseEvent mouseev(xev); 337 ui::MouseEvent mouseev(xev);
483 TranslateAndDispatchMouseEvent(&mouseev); 338 TranslateAndDispatchLocatedEvent(&mouseev);
484 break; 339 break;
485 } 340 }
486 } 341 }
487 return ui::POST_DISPATCH_STOP_PROPAGATION; 342 return ui::POST_DISPATCH_STOP_PROPAGATION;
488 } 343 }
489 344
490 gfx::AcceleratedWidget WindowTreeHostX11::GetAcceleratedWidget() { 345 gfx::AcceleratedWidget WindowTreeHostX11::GetAcceleratedWidget() {
491 return xwindow_; 346 return xwindow_;
492 } 347 }
493 348
(...skipping 21 matching lines...) Expand all
515 } 370 }
516 } 371 }
517 372
518 void WindowTreeHostX11::Hide() { 373 void WindowTreeHostX11::Hide() {
519 if (window_mapped_) { 374 if (window_mapped_) {
520 XWithdrawWindow(xdisplay_, xwindow_, 0); 375 XWithdrawWindow(xdisplay_, xwindow_, 0);
521 window_mapped_ = false; 376 window_mapped_ = false;
522 } 377 }
523 } 378 }
524 379
525 void WindowTreeHostX11::ToggleFullScreen() {
526 NOTIMPLEMENTED();
527 }
528
529 gfx::Rect WindowTreeHostX11::GetBounds() const { 380 gfx::Rect WindowTreeHostX11::GetBounds() const {
530 return bounds_; 381 return bounds_;
531 } 382 }
532 383
533 void WindowTreeHostX11::SetBounds(const gfx::Rect& bounds) { 384 void WindowTreeHostX11::SetBounds(const gfx::Rect& bounds) {
534 // Even if the host window's size doesn't change, aura's root window 385 // Even if the host window's size doesn't change, aura's root window
535 // size, which is in DIP, changes when the scale changes. 386 // size, which is in DIP, changes when the scale changes.
536 float current_scale = compositor()->device_scale_factor(); 387 float current_scale = compositor()->device_scale_factor();
537 float new_scale = gfx::Screen::GetScreenFor(window())-> 388 float new_scale = gfx::Screen::GetScreenFor(window())->
538 GetDisplayNearestWindow(window()).device_scale_factor(); 389 GetDisplayNearestWindow(window()).device_scale_factor();
(...skipping 15 matching lines...) Expand all
554 } 405 }
555 if (value_mask) 406 if (value_mask)
556 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); 407 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
557 408
558 // Assume that the resize will go through as requested, which should be the 409 // Assume that the resize will go through as requested, which should be the
559 // case if we're running without a window manager. If there's a window 410 // case if we're running without a window manager. If there's a window
560 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a 411 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
561 // (possibly synthetic) ConfigureNotify about the actual size and correct 412 // (possibly synthetic) ConfigureNotify about the actual size and correct
562 // |bounds_| later. 413 // |bounds_| later.
563 bounds_ = bounds; 414 bounds_ = bounds;
564 UpdateIsInternalDisplay();
565 if (origin_changed) 415 if (origin_changed)
566 OnHostMoved(bounds.origin()); 416 OnHostMoved(bounds.origin());
567 if (size_changed || current_scale != new_scale) { 417 if (size_changed || current_scale != new_scale) {
568 OnHostResized(bounds.size()); 418 OnHostResized(bounds.size());
569 } else { 419 } else {
570 window()->SchedulePaintInRect(window()->bounds()); 420 window()->SchedulePaintInRect(window()->bounds());
571 } 421 }
572 } 422 }
573 423
574 gfx::Insets WindowTreeHostX11::GetInsets() const {
575 return insets_;
576 }
577
578 void WindowTreeHostX11::SetInsets(const gfx::Insets& insets) {
579 insets_ = insets;
580 if (pointer_barriers_) {
581 UnConfineCursor();
582 ConfineCursorToRootWindow();
583 }
584 }
585
586 gfx::Point WindowTreeHostX11::GetLocationOnNativeScreen() const { 424 gfx::Point WindowTreeHostX11::GetLocationOnNativeScreen() const {
587 return bounds_.origin(); 425 return bounds_.origin();
588 } 426 }
589 427
590 void WindowTreeHostX11::SetCapture() { 428 void WindowTreeHostX11::SetCapture() {
591 // TODO(oshima): Grab x input. 429 // TODO(oshima): Grab x input.
592 } 430 }
593 431
594 void WindowTreeHostX11::ReleaseCapture() { 432 void WindowTreeHostX11::ReleaseCapture() {
595 // TODO(oshima): Release x input. 433 // TODO(oshima): Release x input.
(...skipping 16 matching lines...) Expand all
612 &child_return, 450 &child_return,
613 &root_x_return, &root_y_return, 451 &root_x_return, &root_y_return,
614 &win_x_return, &win_y_return, 452 &win_x_return, &win_y_return,
615 &mask_return); 453 &mask_return);
616 *location_return = gfx::Point(max(0, min(bounds_.width(), win_x_return)), 454 *location_return = gfx::Point(max(0, min(bounds_.width(), win_x_return)),
617 max(0, min(bounds_.height(), win_y_return))); 455 max(0, min(bounds_.height(), win_y_return)));
618 return (win_x_return >= 0 && win_x_return < bounds_.width() && 456 return (win_x_return >= 0 && win_x_return < bounds_.width() &&
619 win_y_return >= 0 && win_y_return < bounds_.height()); 457 win_y_return >= 0 && win_y_return < bounds_.height());
620 } 458 }
621 459
622 bool WindowTreeHostX11::ConfineCursorToRootWindow() {
623 #if XFIXES_MAJOR >= 5
624 DCHECK(!pointer_barriers_.get());
625 if (pointer_barriers_)
626 return false;
627 pointer_barriers_.reset(new XID[4]);
628 gfx::Rect bounds(bounds_);
629 bounds.Inset(insets_);
630 // Horizontal, top barriers.
631 pointer_barriers_[0] = XFixesCreatePointerBarrier(
632 xdisplay_, x_root_window_,
633 bounds.x(), bounds.y(), bounds.right(), bounds.y(),
634 BarrierPositiveY,
635 0, XIAllDevices);
636 // Horizontal, bottom barriers.
637 pointer_barriers_[1] = XFixesCreatePointerBarrier(
638 xdisplay_, x_root_window_,
639 bounds.x(), bounds.bottom(), bounds.right(), bounds.bottom(),
640 BarrierNegativeY,
641 0, XIAllDevices);
642 // Vertical, left barriers.
643 pointer_barriers_[2] = XFixesCreatePointerBarrier(
644 xdisplay_, x_root_window_,
645 bounds.x(), bounds.y(), bounds.x(), bounds.bottom(),
646 BarrierPositiveX,
647 0, XIAllDevices);
648 // Vertical, right barriers.
649 pointer_barriers_[3] = XFixesCreatePointerBarrier(
650 xdisplay_, x_root_window_,
651 bounds.right(), bounds.y(), bounds.right(), bounds.bottom(),
652 BarrierNegativeX,
653 0, XIAllDevices);
654 #endif
655 return true;
656 }
657
658 void WindowTreeHostX11::UnConfineCursor() {
659 #if XFIXES_MAJOR >= 5
660 if (pointer_barriers_) {
661 XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[0]);
662 XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[1]);
663 XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[2]);
664 XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[3]);
665 pointer_barriers_.reset();
666 }
667 #endif
668 }
669
670 void WindowTreeHostX11::PostNativeEvent( 460 void WindowTreeHostX11::PostNativeEvent(
671 const base::NativeEvent& native_event) { 461 const base::NativeEvent& native_event) {
672 DCHECK(xwindow_); 462 DCHECK(xwindow_);
673 DCHECK(xdisplay_); 463 DCHECK(xdisplay_);
674 XEvent xevent = *native_event; 464 XEvent xevent = *native_event;
675 xevent.xany.display = xdisplay_; 465 xevent.xany.display = xdisplay_;
676 xevent.xany.window = xwindow_; 466 xevent.xany.window = xwindow_;
677 467
678 switch (xevent.type) { 468 switch (xevent.type) {
679 case EnterNotify: 469 case EnterNotify:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 SetCursorInternal(cursor); 501 SetCursorInternal(cursor);
712 } 502 }
713 503
714 void WindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { 504 void WindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) {
715 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, 505 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
716 bounds_.x() + location.x(), 506 bounds_.x() + location.x(),
717 bounds_.y() + location.y()); 507 bounds_.y() + location.y());
718 } 508 }
719 509
720 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { 510 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
721 SetCrOSTapPaused(!show);
722 }
723
724 void WindowTreeHostX11::OnWindowInitialized(Window* window) {
725 }
726
727 void WindowTreeHostX11::OnHostInitialized(WindowTreeHost* host) {
728 // TODO(beng): I'm not sure that this comment makes much sense anymore??
729 // UpdateIsInternalDisplay relies on WED's kDisplayIdKey property being set
730 // available by the time WED::Init is called. (set in
731 // DisplayManager::CreateRootWindowForDisplay)
732 // Ready when NotifyHostInitialized is called from WED::Init.
733 if (host != this)
734 return;
735 UpdateIsInternalDisplay();
736
737 // We have to enable Tap-to-click by default because the cursor is set to
738 // visible in Shell::InitRootWindowController.
739 SetCrOSTapPaused(false);
740 } 511 }
741 512
742 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() { 513 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() {
743 return dispatcher(); 514 return dispatcher();
744 } 515 }
745 516
746 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) { 517 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) {
747 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 518 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
748 XEvent* xev = event; 519 XEvent* xev = event;
749 if (!factory->ShouldProcessXI2Event(xev)) 520 if (!factory->ShouldProcessXI2Event(xev))
(...skipping 15 matching lines...) Expand all
765 case ui::ET_TOUCH_RELEASED: { 536 case ui::ET_TOUCH_RELEASED: {
766 #if defined(OS_CHROMEOS) 537 #if defined(OS_CHROMEOS)
767 // Bail out early before generating a ui::TouchEvent if this event 538 // Bail out early before generating a ui::TouchEvent if this event
768 // is not within the range of this RootWindow. Converting an xevent 539 // is not within the range of this RootWindow. Converting an xevent
769 // to ui::TouchEvent might change the state of the global touch tracking 540 // to ui::TouchEvent might change the state of the global touch tracking
770 // state, e.g. touch release event can remove the touch id from the 541 // state, e.g. touch release event can remove the touch id from the
771 // record, and doing this multiple time when there are multiple 542 // record, and doing this multiple time when there are multiple
772 // RootWindow will cause problem. So only generate the ui::TouchEvent 543 // RootWindow will cause problem. So only generate the ui::TouchEvent
773 // when we are sure it belongs to this RootWindow. 544 // when we are sure it belongs to this RootWindow.
774 if (base::SysInfo::IsRunningOnChromeOS() && 545 if (base::SysInfo::IsRunningOnChromeOS() &&
775 !bounds_.Contains(ui::EventLocationFromNative(xev))) 546 !bounds().Contains(ui::EventLocationFromNative(xev)))
776 break; 547 return;
777 #endif // defined(OS_CHROMEOS) 548 #endif
778 ui::TouchEvent touchev(xev); 549 ui::TouchEvent touchev(xev);
779 #if defined(OS_CHROMEOS) 550 TranslateAndDispatchLocatedEvent(&touchev);
780 if (base::SysInfo::IsRunningOnChromeOS()) {
781 // X maps the touch-surface to the size of the X root-window.
782 // In multi-monitor setup, Coordinate Transformation Matrix
783 // repositions the touch-surface onto part of X root-window
784 // containing aura root-window corresponding to the touchscreen.
785 // However, if aura root-window has non-zero origin,
786 // we need to relocate the event into aura root-window coordinates.
787 touchev.Relocate(bounds_.origin());
788 #if defined(USE_XI2_MT)
789 if (is_internal_display_)
790 touch_calibrate_->Calibrate(&touchev, bounds_);
791 #endif // defined(USE_XI2_MT)
792 }
793 #endif // defined(OS_CHROMEOS)
794 SendEventToProcessor(&touchev);
795 break; 551 break;
796 } 552 }
797 case ui::ET_MOUSE_MOVED: 553 case ui::ET_MOUSE_MOVED:
798 case ui::ET_MOUSE_DRAGGED: 554 case ui::ET_MOUSE_DRAGGED:
799 case ui::ET_MOUSE_PRESSED: 555 case ui::ET_MOUSE_PRESSED:
800 case ui::ET_MOUSE_RELEASED: 556 case ui::ET_MOUSE_RELEASED:
801 case ui::ET_MOUSE_ENTERED: 557 case ui::ET_MOUSE_ENTERED:
802 case ui::ET_MOUSE_EXITED: { 558 case ui::ET_MOUSE_EXITED: {
803 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { 559 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
804 // If this is a motion event, we want to coalesce all pending motion 560 // If this is a motion event, we want to coalesce all pending motion
805 // events that are at the top of the queue. 561 // events that are at the top of the queue.
806 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); 562 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
807 if (num_coalesced > 0) 563 if (num_coalesced > 0)
808 xev = &last_event; 564 xev = &last_event;
809 } 565 }
810 ui::MouseEvent mouseev(xev); 566 ui::MouseEvent mouseev(xev);
811 TranslateAndDispatchMouseEvent(&mouseev); 567 TranslateAndDispatchLocatedEvent(&mouseev);
812 break; 568 break;
813 } 569 }
814 case ui::ET_MOUSEWHEEL: { 570 case ui::ET_MOUSEWHEEL: {
815 ui::MouseWheelEvent mouseev(xev); 571 ui::MouseWheelEvent mouseev(xev);
816 TranslateAndDispatchMouseEvent(&mouseev); 572 TranslateAndDispatchLocatedEvent(&mouseev);
817 break; 573 break;
818 } 574 }
819 case ui::ET_SCROLL_FLING_START: 575 case ui::ET_SCROLL_FLING_START:
820 case ui::ET_SCROLL_FLING_CANCEL: 576 case ui::ET_SCROLL_FLING_CANCEL:
821 case ui::ET_SCROLL: { 577 case ui::ET_SCROLL: {
822 ui::ScrollEvent scrollev(xev); 578 ui::ScrollEvent scrollev(xev);
823 SendEventToProcessor(&scrollev); 579 SendEventToProcessor(&scrollev);
824 break; 580 break;
825 } 581 }
826 case ui::ET_UMA_DATA: 582 case ui::ET_UMA_DATA:
(...skipping 13 matching lines...) Expand all
840 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 596 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
841 // of WM_Sn selections (where n is a screen number). 597 // of WM_Sn selections (where n is a screen number).
842 return XGetSelectionOwner( 598 return XGetSelectionOwner(
843 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 599 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
844 } 600 }
845 601
846 void WindowTreeHostX11::SetCursorInternal(gfx::NativeCursor cursor) { 602 void WindowTreeHostX11::SetCursorInternal(gfx::NativeCursor cursor) {
847 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); 603 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
848 } 604 }
849 605
850 void WindowTreeHostX11::TranslateAndDispatchMouseEvent( 606 void WindowTreeHostX11::OnConfigureNotify() {}
851 ui::MouseEvent* event) {
852 Window* root_window = window();
853 client::ScreenPositionClient* screen_position_client =
854 client::GetScreenPositionClient(root_window);
855 gfx::Rect local(bounds_.size());
856 607
857 if (screen_position_client && !local.Contains(event->location())) { 608 void WindowTreeHostX11::TranslateAndDispatchLocatedEvent(
858 gfx::Point location(event->location()); 609 ui::LocatedEvent* event) {
859 // In order to get the correct point in screen coordinates
860 // during passive grab, we first need to find on which host window
861 // the mouse is on, and find out the screen coordinates on that
862 // host window, then convert it back to this host window's coordinate.
863 screen_position_client->ConvertHostPointToScreen(root_window, &location);
864 screen_position_client->ConvertPointFromScreen(root_window, &location);
865 ConvertPointToHost(&location);
866 event->set_location(location);
867 event->set_root_location(location);
868 }
869 SendEventToProcessor(event); 610 SendEventToProcessor(event);
870 } 611 }
871 612
872 void WindowTreeHostX11::UpdateIsInternalDisplay() {
873 Window* root_window = window();
874 gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
875 gfx::Display display = screen->GetDisplayNearestWindow(root_window);
876 is_internal_display_ = display.IsInternal();
877 }
878
879 void WindowTreeHostX11::SetCrOSTapPaused(bool state) {
880 #if defined(OS_CHROMEOS)
881 if (!ui::IsXInput2Available())
882 return;
883 // Temporarily pause tap-to-click when the cursor is hidden.
884 Atom prop = atom_cache_.GetAtom("Tap Paused");
885 unsigned char value = state;
886 XIDeviceList dev_list =
887 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_);
888
889 // Only slave pointer devices could possibly have tap-paused property.
890 for (int i = 0; i < dev_list.count; i++) {
891 if (dev_list[i].use == XISlavePointer) {
892 Atom old_type;
893 int old_format;
894 unsigned long old_nvalues, bytes;
895 unsigned char* data;
896 int result = XIGetProperty(xdisplay_, dev_list[i].deviceid, prop, 0, 0,
897 False, AnyPropertyType, &old_type, &old_format,
898 &old_nvalues, &bytes, &data);
899 if (result != Success)
900 continue;
901 XFree(data);
902 XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8,
903 PropModeReplace, &value, 1);
904 }
905 }
906 #endif
907 }
908
909 // static 613 // static
910 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) { 614 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
911 return new WindowTreeHostX11(bounds); 615 return new WindowTreeHostX11(bounds);
912 } 616 }
913 617
914 // static 618 // static
915 gfx::Size WindowTreeHost::GetNativeScreenSize() { 619 gfx::Size WindowTreeHost::GetNativeScreenSize() {
916 ::XDisplay* xdisplay = gfx::GetXDisplay(); 620 ::XDisplay* xdisplay = gfx::GetXDisplay();
917 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 621 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
918 } 622 }
919 623
920 namespace test { 624 namespace test {
921 625
922 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { 626 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
923 default_override_redirect = override_redirect; 627 default_override_redirect = override_redirect;
924 } 628 }
925 629
926 } // namespace test 630 } // namespace test
927 } // namespace aura 631 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/window_tree_host_x11.h ('k') | ui/aura/window_tree_host_x11_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698