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

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

Powered by Google App Engine
This is Rietveld 408576698