OLD | NEW |
---|---|
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/root_window_host_linux.h" | 5 #include "wm/host/root_window_host_linux.h" |
6 | 6 |
7 #include <strings.h> | |
8 #include <X11/cursorfont.h> | |
9 #include <X11/extensions/Xfixes.h> | |
10 #include <X11/extensions/XInput2.h> | |
11 #include <X11/extensions/Xrandr.h> | |
12 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
13 #include <X11/Xcursor/Xcursor.h> | 8 #include <X11/Xcursor/Xcursor.h> |
14 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
10 #include <X11/cursorfont.h> | |
11 #include <X11/extensions/XInput2.h> | |
12 #include <X11/extensions/Xcomposite.h> | |
13 #include <X11/extensions/Xfixes.h> | |
14 #include <X11/extensions/Xrandr.h> | |
15 #include <X11/extensions/shape.h> | |
16 #include <strings.h> | |
15 | 17 |
16 #include <algorithm> | 18 #include <algorithm> |
17 #include <limits> | 19 #include <limits> |
18 #include <string> | 20 #include <string> |
19 | 21 |
20 #include "base/command_line.h" | 22 #include "base/command_line.h" |
21 #include "base/message_loop.h" | 23 #include "base/message_loop.h" |
22 #include "base/message_pump_aurax11.h" | 24 #include "base/message_pump_aurax11.h" |
23 #include "base/stl_util.h" | 25 #include "base/stl_util.h" |
24 #include "base/stringprintf.h" | 26 #include "base/stringprintf.h" |
25 #include "third_party/skia/include/core/SkBitmap.h" | 27 #include "third_party/skia/include/core/SkBitmap.h" |
26 #include "third_party/skia/include/core/SkCanvas.h" | 28 #include "third_party/skia/include/core/SkCanvas.h" |
27 #include "third_party/skia/include/core/SkPostConfig.h" | |
28 #include "ui/aura/client/capture_client.h" | 29 #include "ui/aura/client/capture_client.h" |
29 #include "ui/aura/client/cursor_client.h" | 30 #include "ui/aura/client/cursor_client.h" |
30 #include "ui/aura/client/screen_position_client.h" | 31 #include "ui/aura/client/screen_position_client.h" |
31 #include "ui/aura/client/user_action_client.h" | 32 #include "ui/aura/client/user_action_client.h" |
32 #include "ui/aura/env.h" | 33 #include "ui/aura/env.h" |
33 #include "ui/aura/root_window.h" | 34 #include "ui/aura/root_window.h" |
34 #include "ui/base/cursor/cursor.h" | 35 #include "ui/base/cursor/cursor.h" |
35 #include "ui/base/events/event.h" | 36 #include "ui/base/events/event.h" |
36 #include "ui/base/events/event_utils.h" | 37 #include "ui/base/events/event_utils.h" |
37 #include "ui/base/keycodes/keyboard_codes.h" | 38 #include "ui/base/keycodes/keyboard_codes.h" |
38 #include "ui/base/touch/touch_factory.h" | 39 #include "ui/base/touch/touch_factory.h" |
39 #include "ui/base/ui_base_switches.h" | 40 #include "ui/base/ui_base_switches.h" |
40 #include "ui/base/view_prop.h" | 41 #include "ui/base/view_prop.h" |
41 #include "ui/base/x/device_list_cache_x.h" | 42 #include "ui/base/x/device_list_cache_x.h" |
42 #include "ui/base/x/valuators.h" | 43 #include "ui/base/x/valuators.h" |
43 #include "ui/base/x/x11_util.h" | 44 #include "ui/base/x/x11_util.h" |
44 #include "ui/compositor/dip_util.h" | 45 #include "ui/compositor/dip_util.h" |
45 #include "ui/compositor/layer.h" | 46 #include "ui/compositor/layer.h" |
46 #include "ui/gfx/codec/png_codec.h" | 47 #include "ui/gfx/codec/png_codec.h" |
47 #include "ui/gfx/screen.h" | 48 #include "ui/gfx/screen.h" |
49 #include "wm/foreign_window.h" | |
50 #include "wm/foreign_window_widget.h" | |
48 | 51 |
49 #if defined(OS_CHROMEOS) | 52 #if defined(OS_CHROMEOS) |
50 #include "base/chromeos/chromeos_version.h" | 53 #include "base/chromeos/chromeos_version.h" |
51 #endif | 54 #endif |
52 | 55 |
53 using std::max; | 56 using std::max; |
54 using std::min; | 57 using std::min; |
55 | 58 |
56 namespace aura { | 59 namespace wm { |
57 | 60 |
58 namespace { | 61 namespace { |
59 | 62 |
60 // Standard Linux mouse buttons for going back and forward. | 63 // Standard Linux mouse buttons for going back and forward. |
61 const int kBackMouseButton = 8; | 64 const int kBackMouseButton = 8; |
62 const int kForwardMouseButton = 9; | 65 const int kForwardMouseButton = 9; |
63 | 66 |
64 // These are the same values that are used to calibrate touch events in | 67 // These are the same values that are used to calibrate touch events in |
65 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc). | 68 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc). |
66 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605) | 69 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 case ui::VKEY_OEM_PLUS: | 165 case ui::VKEY_OEM_PLUS: |
163 case ui::VKEY_OEM_COMMA: | 166 case ui::VKEY_OEM_COMMA: |
164 case ui::VKEY_OEM_MINUS: | 167 case ui::VKEY_OEM_MINUS: |
165 case ui::VKEY_OEM_PERIOD: | 168 case ui::VKEY_OEM_PERIOD: |
166 return true; | 169 return true; |
167 default: | 170 default: |
168 return false; | 171 return false; |
169 } | 172 } |
170 } | 173 } |
171 | 174 |
175 unsigned InitWindowChanges(const gfx::Rect& bounds, | |
176 ::Window sibling_to_stack_above, | |
177 XWindowChanges& wc) { | |
178 wc.x = bounds.x(); | |
179 wc.y = bounds.y(); | |
180 wc.width = bounds.width(); | |
181 wc.height = bounds.height(); | |
182 if (!sibling_to_stack_above) { | |
183 wc.stack_mode = Below; | |
184 return CWX | CWY | CWWidth | CWHeight | CWStackMode; | |
185 } | |
186 | |
187 wc.sibling = sibling_to_stack_above; | |
188 wc.stack_mode = Above; | |
189 return CWX | CWY | CWWidth | CWHeight | CWStackMode | CWSibling; | |
190 } | |
191 | |
192 aura::Window* FindLowestCommonAncestor( | |
193 aura::Window* root, const aura::Window* p, const aura::Window* q) { | |
194 // Root is the LCA. | |
195 if (root == p || root == q) | |
196 return root; | |
197 | |
198 aura::Window* prev = NULL; | |
199 const aura::Window::Windows& children = root->children(); | |
200 for (size_t i = 0; i < children.size(); ++i) { | |
201 // Try to find LCA of p and q in subtree. | |
202 aura::Window* next = FindLowestCommonAncestor(children[i], p, q); | |
203 if (next) { | |
204 // If a LCA was previously found, p and q must be in different subtrees. | |
205 if (prev) | |
206 return root; | |
207 | |
208 prev = next; | |
209 } | |
210 } | |
211 | |
212 return prev; | |
213 } | |
214 | |
215 gfx::Point GetTargetOriginInRootWindow(const aura::Window* window) { | |
danakj
2013/02/21 01:33:15
GetTargetOffset.. and return a Vector2d? Then GetT
reveman
2013/02/22 01:26:44
Sg, I'll get this fixed soon or maybe if it's not
danakj
2013/02/22 01:48:08
We can do it after, it should be easy to do either
reveman
2013/02/22 06:53:01
Got this done. Please verify that my changes to Re
| |
216 gfx::Point origin; | |
217 | |
218 const aura::Window* p = window; | |
219 for (; p != window->GetRootWindow(); p = p->parent()) | |
220 origin += p->GetTargetBounds().OffsetFromOrigin(); | |
221 | |
222 return origin; | |
223 } | |
224 | |
225 gfx::Rect GetTargetBoundsInRootWindow(const aura::Window* window) { | |
226 return gfx::Rect( | |
227 GetTargetOriginInRootWindow(window), | |
228 window->GetTargetBounds().size()); | |
229 } | |
230 | |
172 } // namespace | 231 } // namespace |
173 | 232 |
174 namespace internal { | 233 namespace internal { |
175 | 234 |
176 // A very lightweight message-pump observer that routes all the touch events to | 235 // A very lightweight message-pump observer that routes all the touch events to |
177 // the X root window so that they can be calibrated properly. | 236 // the X root window so that they can be calibrated properly. |
178 class TouchEventCalibrate : public base::MessagePumpObserver { | 237 class TouchEventCalibrate : public base::MessagePumpObserver { |
179 public: | 238 public: |
180 TouchEventCalibrate() { | 239 TouchEventCalibrate() { |
181 MessageLoopForUI::current()->AddObserver(this); | 240 MessageLoopForUI::current()->AddObserver(this); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 | 316 |
258 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) | 317 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
259 : delegate_(NULL), | 318 : delegate_(NULL), |
260 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), | 319 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), |
261 xwindow_(0), | 320 xwindow_(0), |
262 x_root_window_(DefaultRootWindow(xdisplay_)), | 321 x_root_window_(DefaultRootWindow(xdisplay_)), |
263 current_cursor_(ui::kCursorNull), | 322 current_cursor_(ui::kCursorNull), |
264 window_mapped_(false), | 323 window_mapped_(false), |
265 bounds_(bounds), | 324 bounds_(bounds), |
266 focus_when_shown_(false), | 325 focus_when_shown_(false), |
326 pointer_barriers_(NULL), | |
267 touch_calibrate_(new internal::TouchEventCalibrate), | 327 touch_calibrate_(new internal::TouchEventCalibrate), |
268 mouse_move_filter_(new MouseMoveFilter), | 328 mouse_move_filter_(new MouseMoveFilter), |
269 atom_cache_(xdisplay_, kAtomsToCache) { | 329 atom_cache_(xdisplay_, kAtomsToCache), |
330 configure_window_(NULL), | |
331 x_input_window_(0), | |
332 need_to_set_default_cursor_(true) { | |
270 XSetWindowAttributes swa; | 333 XSetWindowAttributes swa; |
271 memset(&swa, 0, sizeof(swa)); | 334 memset(&swa, 0, sizeof(swa)); |
272 swa.background_pixmap = None; | 335 swa.background_pixmap = None; |
273 xwindow_ = XCreateWindow( | 336 xwindow_ = XCreateWindow( |
274 xdisplay_, x_root_window_, | 337 xdisplay_, x_root_window_, |
275 bounds.x(), bounds.y(), bounds.width(), bounds.height(), | 338 bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
276 0, // border width | 339 0, // border width |
277 CopyFromParent, // depth | 340 CopyFromParent, // depth |
278 InputOutput, | 341 InputOutput, |
279 CopyFromParent, // visual | 342 CopyFromParent, // visual |
280 CWBackPixmap, | 343 CWBackPixmap, |
281 &swa); | 344 &swa); |
345 x_input_window_ = XCreateWindow( | |
346 xdisplay_, xwindow_, | |
347 -100, -100, 1, 1, | |
348 0, // border width | |
349 CopyFromParent, // depth | |
350 InputOnly, | |
351 CopyFromParent, // visual | |
352 0, | |
353 NULL); | |
354 XMapWindow(xdisplay_, x_input_window_); | |
355 XCompositeRedirectSubwindows(xdisplay_, xwindow_, CompositeRedirectManual); | |
356 | |
282 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); | 357 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); |
283 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this); | 358 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this); |
284 | 359 |
285 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | | 360 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
286 KeyPressMask | KeyReleaseMask | | 361 KeyPressMask | KeyReleaseMask | |
287 EnterWindowMask | LeaveWindowMask | | 362 EnterWindowMask | LeaveWindowMask | |
288 ExposureMask | VisibilityChangeMask | | 363 ExposureMask | VisibilityChangeMask | |
289 StructureNotifyMask | PropertyChangeMask | | 364 StructureNotifyMask | PropertyChangeMask | |
290 PointerMotionMask; | 365 PointerMotionMask | |
366 SubstructureNotifyMask | SubstructureRedirectMask; | |
291 XSelectInput(xdisplay_, xwindow_, event_mask); | 367 XSelectInput(xdisplay_, xwindow_, event_mask); |
292 XFlush(xdisplay_); | 368 XFlush(xdisplay_); |
293 | 369 |
294 if (base::MessagePumpForUI::HasXInput2()) | 370 if (base::MessagePumpForUI::HasXInput2()) |
295 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); | 371 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); |
296 | 372 |
297 SelectEventsForRootWindow(); | 373 SelectEventsForRootWindow(); |
298 | 374 |
299 // Get the initial size of the X root window. | 375 // Get the initial size of the X root window. |
300 XWindowAttributes attrs; | 376 XWindowAttributes attrs; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 XRRSelectInput(xdisplay_, x_root_window_, | 409 XRRSelectInput(xdisplay_, x_root_window_, |
334 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); | 410 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); |
335 } | 411 } |
336 | 412 |
337 RootWindowHostLinux::~RootWindowHostLinux() { | 413 RootWindowHostLinux::~RootWindowHostLinux() { |
338 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this); | 414 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this); |
339 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); | 415 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); |
340 | 416 |
341 UnConfineCursor(); | 417 UnConfineCursor(); |
342 | 418 |
419 GetRootWindow()->RemoveObserver(this); | |
420 XDestroyWindow(xdisplay_, x_input_window_); | |
343 XDestroyWindow(xdisplay_, xwindow_); | 421 XDestroyWindow(xdisplay_, xwindow_); |
344 } | 422 } |
345 | 423 |
346 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { | 424 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
347 XEvent* xev = event; | 425 XEvent* xev = event; |
348 | 426 |
349 if (FindEventTarget(event) == x_root_window_) | 427 if (FindEventTarget(event) == x_root_window_) |
350 return DispatchEventForRootWindow(event); | 428 return DispatchEventForRootWindow(event); |
351 | 429 |
352 switch (xev->type) { | 430 switch (xev->type) { |
431 case ConfigureNotify: { | |
432 if (event->xconfigure.window == x_input_window_) | |
433 return true; | |
434 | |
435 ForeignWindowMap::iterator it = foreign_windows_.find( | |
436 event->xconfigure.window); | |
437 if (it != foreign_windows_.end()) { | |
438 ForeignWindow* window = it->second; | |
439 | |
440 int border_size = event->xconfigure.border_width * 2; | |
441 gfx::Size size(event->xconfigure.width + border_size, | |
442 event->xconfigure.height + border_size); | |
443 window->SetWindowSize(size); | |
444 return true; | |
445 } | |
446 break; | |
447 } | |
448 case MapNotify: { | |
449 ForeignWindowMap::iterator it = foreign_windows_.find( | |
450 event->xmap.window); | |
451 if (it != foreign_windows_.end()) { | |
452 ForeignWindow* window = it->second; | |
453 | |
454 window->SetWindowVisible(true); | |
455 return true; | |
456 } | |
457 break; | |
458 } | |
459 case UnmapNotify: { | |
460 ForeignWindowMap::iterator it = foreign_windows_.find( | |
461 event->xunmap.window); | |
462 if (it != foreign_windows_.end()) { | |
463 ForeignWindow* window = it->second; | |
464 | |
465 // Hide top level widget. | |
466 views::Widget* widget = window->GetWidget(); | |
467 widget->Hide(); | |
468 | |
469 window->SetWindowVisible(false); | |
470 return true; | |
471 } | |
472 break; | |
473 } | |
474 case CreateNotify: { | |
475 int border_size = event->xcreatewindow.border_width * 2; | |
476 gfx::Size size(event->xcreatewindow.width + border_size, | |
477 event->xcreatewindow.height + border_size); | |
478 | |
479 // Create a foreign window for this X window. | |
480 ForeignWindow::CreateParams params(event->xcreatewindow.window, size); | |
481 scoped_refptr<ForeignWindow> window(new ForeignWindow(params)); | |
482 | |
483 // Create top level window widget. | |
484 ForeignWindowWidget::CreateWindow(window.get()); | |
485 | |
486 // Add foreign window to map. | |
487 foreign_windows_[event->xcreatewindow.window] = window.get(); | |
488 return true; | |
489 } | |
490 case DestroyNotify: { | |
491 ForeignWindowMap::iterator it = foreign_windows_.find( | |
492 event->xdestroywindow.window); | |
493 if (it != foreign_windows_.end()) { | |
494 ForeignWindow* window = it->second; | |
495 | |
496 // Tell foreign window that X window has been destroyed. | |
497 window->OnWindowDestroyed(); | |
498 | |
499 // Close top level widget. | |
500 views::Widget* widget = window->GetWidget(); | |
501 widget->Close(); | |
502 | |
503 foreign_windows_.erase(it); | |
504 } | |
505 return true; | |
506 } | |
507 case MapRequest: { | |
508 ForeignWindowMap::iterator it = foreign_windows_.find( | |
509 event->xmaprequest.window); | |
510 if (it != foreign_windows_.end()) { | |
511 ForeignWindow* window = it->second; | |
512 | |
513 // Show top level widget. | |
514 views::Widget* widget = window->GetWidget(); | |
515 widget->Show(); | |
516 } | |
517 return true; | |
518 } | |
519 case ConfigureRequest: { | |
520 // TODO(reveman): Respect ConfigureRequest events. | |
521 return true; | |
522 } | |
523 case CirculateRequest: { | |
524 // TODO(reveman): Respect CirculateRequest events. | |
525 return true; | |
526 } | |
527 } | |
528 | |
529 switch (xev->type) { | |
353 case EnterNotify: { | 530 case EnterNotify: { |
354 ui::MouseEvent mouseenter_event(xev); | 531 ui::MouseEvent mouseenter_event(xev); |
355 TranslateAndDispatchMouseEvent(&mouseenter_event); | 532 TranslateAndDispatchMouseEvent(&mouseenter_event); |
356 break; | 533 break; |
357 } | 534 } |
358 case Expose: | 535 case Expose: |
359 delegate_->AsRootWindow()->ScheduleFullDraw(); | 536 delegate_->AsRootWindow()->ScheduleFullDraw(); |
360 break; | 537 break; |
361 case KeyPress: { | 538 case KeyPress: { |
362 ui::KeyEvent keydown_event(xev, false); | 539 ui::KeyEvent keydown_event(xev, false); |
363 delegate_->OnHostKeyEvent(&keydown_event); | 540 delegate_->OnHostKeyEvent(&keydown_event); |
364 break; | 541 break; |
365 } | 542 } |
366 case KeyRelease: { | 543 case KeyRelease: { |
367 ui::KeyEvent keyup_event(xev, false); | 544 ui::KeyEvent keyup_event(xev, false); |
368 delegate_->OnHostKeyEvent(&keyup_event); | 545 delegate_->OnHostKeyEvent(&keyup_event); |
369 break; | 546 break; |
370 } | 547 } |
371 case ButtonPress: { | 548 case ButtonPress: { |
372 if (static_cast<int>(xev->xbutton.button) == kBackMouseButton || | 549 if (static_cast<int>(xev->xbutton.button) == kBackMouseButton || |
373 static_cast<int>(xev->xbutton.button) == kForwardMouseButton) { | 550 static_cast<int>(xev->xbutton.button) == kForwardMouseButton) { |
374 client::UserActionClient* gesture_client = | 551 aura::client::UserActionClient* gesture_client = |
375 client::GetUserActionClient(delegate_->AsRootWindow()); | 552 aura::client::GetUserActionClient(delegate_->AsRootWindow()); |
376 if (gesture_client) { | 553 if (gesture_client) { |
377 gesture_client->OnUserAction( | 554 gesture_client->OnUserAction( |
378 static_cast<int>(xev->xbutton.button) == kBackMouseButton ? | 555 static_cast<int>(xev->xbutton.button) == kBackMouseButton ? |
379 client::UserActionClient::BACK : | 556 aura::client::UserActionClient::BACK : |
380 client::UserActionClient::FORWARD); | 557 aura::client::UserActionClient::FORWARD); |
381 } | 558 } |
382 break; | 559 break; |
383 } | 560 } |
384 } // fallthrough | 561 } // fallthrough |
385 case ButtonRelease: { | 562 case ButtonRelease: { |
386 ui::MouseEvent mouseev(xev); | 563 ui::MouseEvent mouseev(xev); |
387 TranslateAndDispatchMouseEvent(&mouseev); | 564 TranslateAndDispatchMouseEvent(&mouseev); |
388 break; | 565 break; |
389 } | 566 } |
390 case FocusOut: | 567 case FocusOut: |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 } | 653 } |
477 | 654 |
478 ui::MouseEvent mouseev(xev); | 655 ui::MouseEvent mouseev(xev); |
479 TranslateAndDispatchMouseEvent(&mouseev); | 656 TranslateAndDispatchMouseEvent(&mouseev); |
480 break; | 657 break; |
481 } | 658 } |
482 } | 659 } |
483 return true; | 660 return true; |
484 } | 661 } |
485 | 662 |
486 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { | 663 void RootWindowHostLinux::OnWindowAdded(aura::Window* window) { |
664 window->AddObserver(this); | |
665 } | |
666 | |
667 void RootWindowHostLinux::OnWillRemoveWindow(aura::Window* window) { | |
668 if (configure_window_ == window) | |
669 configure_window_ = window->parent(); | |
670 | |
671 window->RemoveObserver(this); | |
672 } | |
673 | |
674 void RootWindowHostLinux::OnWindowStackingChanged(aura::Window* window) { | |
675 ScheduleConfigure(GetRootWindow()); | |
676 } | |
677 | |
678 void RootWindowHostLinux::OnWindowVisibilityChanged( | |
679 aura::Window* window, bool visible) { | |
680 ScheduleConfigure(GetRootWindow()); | |
681 } | |
682 | |
683 void RootWindowHostLinux::OnWindowBoundsChanged( | |
684 aura::Window* window, | |
685 const gfx::Rect& old_bounds, | |
686 const gfx::Rect& new_bounds) { | |
687 ScheduleConfigure(GetRootWindow()); | |
688 } | |
689 | |
690 void RootWindowHostLinux::OnWindowDestroying(aura::Window* window) { | |
691 window->RemoveObserver(this); | |
692 } | |
693 | |
694 ::Window RootWindowHostLinux::GetTopForeignWindow(const aura::Window* window) { | |
695 // children are ordered back to front, so walk through it in reverse. | |
696 const aura::Window::Windows& children = window->children(); | |
697 for (size_t i = children.size(); i; --i) { | |
698 ::Window top = GetTopForeignWindow(children[i - 1]); | |
699 if (top) | |
700 return top; | |
701 } | |
702 | |
703 ForeignWindow* foreign_window = ForeignWindow::GetForeignWindowForNativeView( | |
704 const_cast<gfx::NativeView>(window)); | |
705 if (foreign_window) { | |
706 // Ignore windows that we're not allowed to configure. | |
707 if (foreign_window->IsManaged()) | |
708 return foreign_window->GetWindowHandle(); | |
709 } | |
710 | |
711 return 0; | |
712 } | |
713 | |
714 ::Window RootWindowHostLinux::FindForeignWindowToStackAbove( | |
715 const aura::Window* window) { | |
716 const aura::Window* parent = window->parent(); | |
717 if (!parent) | |
718 return 0; | |
719 | |
720 ::Window above = 0; | |
721 | |
722 const aura::Window::Windows& children = parent->children(); | |
723 for (size_t i = 0; i < children.size(); ++i) { | |
724 if (children[i] == window) | |
725 break; | |
726 | |
727 ::Window top = GetTopForeignWindow(children[i]); | |
728 if (top) | |
729 above = top; | |
730 } | |
731 | |
732 if (!above) | |
733 above = FindForeignWindowToStackAbove(parent); | |
734 | |
735 return above; | |
736 } | |
737 | |
738 void RootWindowHostLinux::MapWindowIfNeeded(ForeignWindow* window) { | |
739 ForeignWindow::DisplayState current_display_state = | |
740 window->GetDisplayState(); | |
741 | |
742 if (current_display_state != ForeignWindow::DISPLAY_NORMAL) { | |
743 // TODO(reveman): Ignore possible X error. | |
744 XMapWindow(xdisplay_, window->GetWindowHandle()); | |
745 | |
746 window->SetDisplayState(ForeignWindow::DISPLAY_NORMAL); | |
747 } | |
748 } | |
749 | |
750 void RootWindowHostLinux::UnmapWindowIfNeeded(ForeignWindow* window) { | |
751 ForeignWindow::DisplayState current_display_state = | |
752 window->GetDisplayState(); | |
753 | |
754 if (current_display_state == ForeignWindow::DISPLAY_NORMAL) { | |
755 // TODO(reveman): Ignore possible X error. | |
756 XUnmapWindow(xdisplay_, window->GetWindowHandle()); | |
757 | |
758 window->SetDisplayState(ForeignWindow::DISPLAY_ICONIC); | |
759 } | |
760 } | |
761 | |
762 void RootWindowHostLinux::RecursiveConfigure( | |
763 aura::Window* window, | |
764 const gfx::Point& origin, | |
765 ::Window* sibling_to_stack_above, | |
766 SkRegion* input_region) { | |
767 gfx::Rect bounds(origin, window->GetTargetBounds().size()); | |
768 SkRegion::Op input_region_op; | |
769 | |
770 ForeignWindow* foreign_window = ForeignWindow::GetForeignWindowForNativeView( | |
771 const_cast<gfx::NativeView>(window)); | |
772 if (foreign_window) { | |
773 DCHECK(!bounds.IsEmpty()); | |
774 | |
775 // We should only be adjusting attributes of managed windows. | |
776 if (foreign_window->IsManaged()) { | |
777 if (!window->IsVisible()) | |
778 UnmapWindowIfNeeded(foreign_window); | |
779 | |
780 XWindowChanges wc; | |
781 unsigned mask = InitWindowChanges(bounds, *sibling_to_stack_above, wc); | |
782 // Get rid of any borders. | |
783 wc.border_width = 0; | |
784 mask |= CWBorderWidth; | |
785 // TODO(reveman): Ignore possible X error. | |
786 XConfigureWindow(xdisplay_, | |
787 foreign_window->GetWindowHandle(), | |
788 mask, | |
789 &wc); | |
790 | |
791 *sibling_to_stack_above = foreign_window->GetWindowHandle(); | |
792 | |
793 if (window->IsVisible()) | |
794 MapWindowIfNeeded(foreign_window); | |
795 } | |
796 | |
797 // Remove foreign window bounds from input region. | |
798 bounds.Inset(window->hit_test_bounds_override_inner()); | |
799 input_region_op = SkRegion::kDifference_Op; | |
800 } else { | |
801 // Add window bounds to output region. | |
802 bounds.Inset(window->hit_test_bounds_override_outer_mouse()); | |
803 input_region_op = SkRegion::kUnion_Op; | |
804 } | |
805 | |
806 if (window->delegate() && window->IsVisible()) { | |
807 input_region->op(bounds.x(), | |
808 bounds.y(), | |
809 bounds.right(), | |
810 bounds.bottom(), | |
811 input_region_op); | |
812 } | |
813 | |
814 const aura::Window::Windows& children = window->children(); | |
815 for (size_t i = 0; i < children.size(); ++i) { | |
816 RecursiveConfigure( | |
817 children[i], | |
818 origin + children[i]->GetTargetBounds().OffsetFromOrigin(), | |
819 sibling_to_stack_above, | |
820 input_region); | |
821 } | |
822 } | |
823 | |
824 void RootWindowHostLinux::Configure() { | |
825 if (!configure_window_) | |
826 return; | |
827 | |
828 SkRegion input_region; | |
829 ::Window sibling_to_stack_above = | |
830 FindForeignWindowToStackAbove(configure_window_); | |
831 RecursiveConfigure(configure_window_, | |
832 GetTargetOriginInRootWindow(configure_window_), | |
833 &sibling_to_stack_above, | |
834 &input_region); | |
835 | |
836 // Update input window and set focus when we configure the root window. | |
837 if (configure_window_ == GetRootWindow()) { | |
838 // Configure input window above all other windows. | |
839 XWindowChanges wc; | |
840 gfx::Rect bounds(gfx::Point(0, 0), bounds_.size()); | |
841 unsigned mask = InitWindowChanges(bounds, sibling_to_stack_above, wc); | |
842 XConfigureWindow(xdisplay_, x_input_window_, mask, &wc); | |
843 | |
844 // Update input window shape. | |
845 std::vector<XRectangle> rectangles; | |
846 for (SkRegion::Iterator iter(input_region); !iter.done(); iter.next()) { | |
847 const SkIRect& sk_rect = iter.rect(); | |
848 XRectangle x_rect; | |
849 x_rect.x = sk_rect.x(); | |
850 x_rect.y = sk_rect.y(); | |
851 x_rect.width = sk_rect.width(); | |
852 x_rect.height = sk_rect.height(); | |
853 rectangles.push_back(x_rect); | |
854 } | |
855 | |
856 XShapeCombineRectangles(xdisplay_, | |
857 x_input_window_, | |
858 ShapeInput, | |
859 0, | |
860 0, | |
861 &rectangles.front(), | |
862 rectangles.size(), | |
863 ShapeSet, | |
864 Unsorted); | |
865 } | |
866 | |
867 XFlush(xdisplay_); | |
868 configure_window_ = NULL; | |
869 } | |
870 | |
871 void RootWindowHostLinux::ScheduleConfigure(aura::Window* window) { | |
872 if (!configure_window_) { | |
873 configure_window_ = window; | |
874 MessageLoop::current()->PostTask( | |
875 FROM_HERE, | |
876 base::Bind(&RootWindowHostLinux::Configure, AsWeakPtr())); | |
877 } else { | |
878 configure_window_ = FindLowestCommonAncestor( | |
879 GetRootWindow(), configure_window_, window); | |
880 } | |
881 } | |
882 | |
883 void RootWindowHostLinux::SetDelegate(aura::RootWindowHostDelegate* delegate) { | |
884 DCHECK(!delegate_); | |
487 delegate_ = delegate; | 885 delegate_ = delegate; |
488 } | 886 DCHECK(delegate_); |
489 | 887 delegate_->AsRootWindow()->AddObserver(this); |
490 RootWindow* RootWindowHostLinux::GetRootWindow() { | 888 ScheduleConfigure(delegate_->AsRootWindow()); |
889 } | |
890 | |
891 aura::RootWindow* RootWindowHostLinux::GetRootWindow() { | |
491 return delegate_->AsRootWindow(); | 892 return delegate_->AsRootWindow(); |
492 } | 893 } |
493 | 894 |
494 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 895 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
495 return xwindow_; | 896 return xwindow_; |
496 } | 897 } |
497 | 898 |
498 void RootWindowHostLinux::Show() { | 899 void RootWindowHostLinux::Show() { |
499 if (!window_mapped_) { | 900 if (!window_mapped_) { |
500 // Before we map the window, set size hints. Otherwise, some window managers | 901 // Before we map the window, set size hints. Otherwise, some window managers |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 } | 988 } |
588 | 989 |
589 void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { | 990 void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { |
590 if (cursor == current_cursor_) | 991 if (cursor == current_cursor_) |
591 return; | 992 return; |
592 current_cursor_ = cursor; | 993 current_cursor_ = cursor; |
593 SetCursorInternal(cursor); | 994 SetCursorInternal(cursor); |
594 } | 995 } |
595 | 996 |
596 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { | 997 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { |
597 client::CursorClient* cursor_client = | 998 aura::client::CursorClient* cursor_client = |
598 client::GetCursorClient(GetRootWindow()); | 999 aura::client::GetCursorClient(GetRootWindow()); |
599 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) { | 1000 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) { |
600 *location_return = gfx::Point(0, 0); | 1001 *location_return = gfx::Point(0, 0); |
601 return false; | 1002 return false; |
602 } | 1003 } |
603 | 1004 |
604 ::Window root_return, child_return; | 1005 ::Window root_return, child_return; |
605 int root_x_return, root_y_return, win_x_return, win_y_return; | 1006 int root_x_return, root_y_return, win_x_return, win_y_return; |
606 unsigned int mask_return; | 1007 unsigned int mask_return; |
607 XQueryPointer(xdisplay_, | 1008 XQueryPointer(xdisplay_, |
608 xwindow_, | 1009 xwindow_, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 const gfx::Point& dest_offset, | 1115 const gfx::Point& dest_offset, |
715 SkCanvas* canvas) { | 1116 SkCanvas* canvas) { |
716 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds)); | 1117 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds)); |
717 if (!scoped_image.get()) | 1118 if (!scoped_image.get()) |
718 return false; | 1119 return false; |
719 | 1120 |
720 XImage* image = scoped_image->get(); | 1121 XImage* image = scoped_image->get(); |
721 DCHECK(image); | 1122 DCHECK(image); |
722 | 1123 |
723 if (image->bits_per_pixel == 32) { | 1124 if (image->bits_per_pixel == 32) { |
724 if ((0xff << SK_R32_SHIFT) != image->red_mask || | |
725 (0xff << SK_G32_SHIFT) != image->green_mask || | |
726 (0xff << SK_B32_SHIFT) != image->blue_mask) { | |
727 LOG(WARNING) << "XImage and Skia byte orders differ"; | |
728 return false; | |
729 } | |
730 | |
731 // Set the alpha channel before copying to the canvas. Otherwise, areas of | 1125 // Set the alpha channel before copying to the canvas. Otherwise, areas of |
732 // the framebuffer that were cleared by ply-image rather than being obscured | 1126 // the framebuffer that were cleared by ply-image rather than being obscured |
733 // by an image during boot may end up transparent. | 1127 // by an image during boot may end up transparent. |
734 // TODO(derat|marcheu): Remove this if/when ply-image has been updated to | 1128 // TODO(derat|marcheu): Remove this if/when ply-image has been updated to |
735 // set the framebuffer's alpha channel regardless of whether the device | 1129 // set the framebuffer's alpha channel regardless of whether the device |
736 // claims to support alpha or not. | 1130 // claims to support alpha or not. |
737 for (int i = 0; i < image->width * image->height * 4; i += 4) | 1131 for (int i = 0; i < image->width * image->height * 4; i += 4) |
738 image->data[i + 3] = 0xff; | 1132 image->data[i + 3] = 0xff; |
739 | 1133 |
740 SkBitmap bitmap; | 1134 SkBitmap bitmap; |
741 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | 1135 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
742 image->width, image->height, | 1136 image->width, image->height, |
743 image->bytes_per_line); | 1137 image->bytes_per_line); |
744 bitmap.setPixels(image->data); | 1138 bitmap.setPixels(image->data); |
745 canvas->drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), NULL); | 1139 SkCanvas::Config8888 config = |
746 } else { | 1140 (image->byte_order == LSBFirst) ? |
1141 SkCanvas::kBGRA_Unpremul_Config8888 : | |
1142 SkCanvas::kRGBA_Unpremul_Config8888; | |
1143 canvas->writePixels(bitmap, dest_offset.x(), dest_offset.y(), config); | |
1144 } else if (image->bits_per_pixel == 24) { | |
747 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; | 1145 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; |
748 return false; | 1146 return false; |
749 } | 1147 } |
750 | 1148 |
751 return true; | 1149 return true; |
752 } | 1150 } |
753 | 1151 |
754 bool RootWindowHostLinux::GrabSnapshot( | 1152 bool RootWindowHostLinux::GrabSnapshot( |
755 const gfx::Rect& snapshot_bounds, | 1153 const gfx::Rect& snapshot_bounds, |
756 std::vector<unsigned char>* png_representation) { | 1154 std::vector<unsigned char>* png_representation) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
860 XEvent last_event; | 1258 XEvent last_event; |
861 int num_coalesced = 0; | 1259 int num_coalesced = 0; |
862 | 1260 |
863 switch (type) { | 1261 switch (type) { |
864 case ui::ET_TOUCH_MOVED: | 1262 case ui::ET_TOUCH_MOVED: |
865 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | 1263 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); |
866 if (num_coalesced > 0) | 1264 if (num_coalesced > 0) |
867 xev = &last_event; | 1265 xev = &last_event; |
868 // fallthrough | 1266 // fallthrough |
869 case ui::ET_TOUCH_PRESSED: | 1267 case ui::ET_TOUCH_PRESSED: |
870 case ui::ET_TOUCH_CANCELLED: | |
871 case ui::ET_TOUCH_RELEASED: { | 1268 case ui::ET_TOUCH_RELEASED: { |
872 ui::TouchEvent touchev(xev); | 1269 ui::TouchEvent touchev(xev); |
873 #if defined(OS_CHROMEOS) | 1270 #if defined(OS_CHROMEOS) |
874 if (base::chromeos::IsRunningOnChromeOS()) { | 1271 if (base::chromeos::IsRunningOnChromeOS()) { |
875 if (!bounds_.Contains(touchev.location())) { | 1272 if (!bounds_.Contains(touchev.location())) { |
876 // This might still be in the bezel region. | 1273 // This might still be in the bezel region. |
877 gfx::Rect expanded(bounds_); | 1274 gfx::Rect expanded(bounds_); |
878 expanded.Inset(-kXRootWindowPaddingLeft, | 1275 expanded.Inset(-kXRootWindowPaddingLeft, |
879 -kXRootWindowPaddingTop, | 1276 -kXRootWindowPaddingTop, |
880 -kXRootWindowPaddingRight, | 1277 -kXRootWindowPaddingRight, |
(...skipping 29 matching lines...) Expand all Loading... | |
910 if (mouse_move_filter_ && mouse_move_filter_->Filter(xev)) | 1307 if (mouse_move_filter_ && mouse_move_filter_->Filter(xev)) |
911 break; | 1308 break; |
912 } else if (type == ui::ET_MOUSE_PRESSED || | 1309 } else if (type == ui::ET_MOUSE_PRESSED || |
913 type == ui::ET_MOUSE_RELEASED) { | 1310 type == ui::ET_MOUSE_RELEASED) { |
914 XIDeviceEvent* xievent = | 1311 XIDeviceEvent* xievent = |
915 static_cast<XIDeviceEvent*>(xev->xcookie.data); | 1312 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
916 int button = xievent->detail; | 1313 int button = xievent->detail; |
917 if (button == kBackMouseButton || button == kForwardMouseButton) { | 1314 if (button == kBackMouseButton || button == kForwardMouseButton) { |
918 if (type == ui::ET_MOUSE_RELEASED) | 1315 if (type == ui::ET_MOUSE_RELEASED) |
919 break; | 1316 break; |
920 client::UserActionClient* gesture_client = | 1317 aura::client::UserActionClient* gesture_client = |
921 client::GetUserActionClient(delegate_->AsRootWindow()); | 1318 aura::client::GetUserActionClient(delegate_->AsRootWindow()); |
922 if (gesture_client) { | 1319 if (gesture_client) { |
923 bool reverse_direction = | 1320 bool reverse_direction = |
924 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); | 1321 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); |
925 gesture_client->OnUserAction( | 1322 gesture_client->OnUserAction( |
926 (button == kBackMouseButton && !reverse_direction) || | 1323 (button == kBackMouseButton && !reverse_direction) || |
927 (button == kForwardMouseButton && reverse_direction) ? | 1324 (button == kForwardMouseButton && reverse_direction) ? |
928 client::UserActionClient::BACK : | 1325 aura::client::UserActionClient::BACK : |
929 client::UserActionClient::FORWARD); | 1326 aura::client::UserActionClient::FORWARD); |
930 } | 1327 } |
931 break; | 1328 break; |
932 } | 1329 } |
933 } | 1330 } |
934 ui::MouseEvent mouseev(xev); | 1331 ui::MouseEvent mouseev(xev); |
935 TranslateAndDispatchMouseEvent(&mouseev); | 1332 TranslateAndDispatchMouseEvent(&mouseev); |
936 break; | 1333 break; |
937 } | 1334 } |
938 case ui::ET_MOUSEWHEEL: { | 1335 case ui::ET_MOUSEWHEEL: { |
939 ui::MouseWheelEvent mouseev(xev); | 1336 ui::MouseWheelEvent mouseev(xev); |
(...skipping 19 matching lines...) Expand all Loading... | |
959 } | 1356 } |
960 | 1357 |
961 bool RootWindowHostLinux::IsWindowManagerPresent() { | 1358 bool RootWindowHostLinux::IsWindowManagerPresent() { |
962 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 1359 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
963 // of WM_Sn selections (where n is a screen number). | 1360 // of WM_Sn selections (where n is a screen number). |
964 return XGetSelectionOwner( | 1361 return XGetSelectionOwner( |
965 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; | 1362 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; |
966 } | 1363 } |
967 | 1364 |
968 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 1365 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
969 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 1366 XDefineCursor(xdisplay_, x_input_window_, cursor.platform()); |
1367 | |
1368 // Set default native window cursor. | |
1369 if (need_to_set_default_cursor_ && cursor.native_type() == ui::kCursorNull) { | |
1370 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | |
1371 need_to_set_default_cursor_ = false; | |
1372 } | |
970 } | 1373 } |
971 | 1374 |
972 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( | 1375 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( |
973 ui::MouseEvent* event) { | 1376 ui::MouseEvent* event) { |
974 RootWindow* root = GetRootWindow(); | 1377 aura::RootWindow* root = GetRootWindow(); |
975 client::ScreenPositionClient* screen_position_client = | 1378 aura::client::ScreenPositionClient* screen_position_client = |
976 GetScreenPositionClient(root); | 1379 GetScreenPositionClient(root); |
977 if (screen_position_client && !bounds_.Contains(event->location())) { | 1380 if (screen_position_client && !bounds_.Contains(event->location())) { |
978 gfx::Point location(event->location()); | 1381 gfx::Point location(event->location()); |
979 screen_position_client->ConvertNativePointToScreen(root, &location); | 1382 screen_position_client->ConvertNativePointToScreen(root, &location); |
980 screen_position_client->ConvertPointFromScreen(root, &location); | 1383 screen_position_client->ConvertPointFromScreen(root, &location); |
981 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to | 1384 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to |
982 // root. | 1385 // root. |
983 location = ui::ConvertPointToPixel(root->layer(), location); | 1386 location = ui::ConvertPointToPixel(root->layer(), location); |
984 event->set_location(location); | 1387 event->set_location(location); |
985 event->set_root_location(location); | 1388 event->set_root_location(location); |
986 } | 1389 } |
987 delegate_->OnHostMouseEvent(event); | 1390 delegate_->OnHostMouseEvent(event); |
988 } | 1391 } |
989 | 1392 |
990 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage( | 1393 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage( |
991 const gfx::Rect& snapshot_bounds) { | 1394 const gfx::Rect& snapshot_bounds) { |
992 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( | 1395 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( |
993 XGetImage(xdisplay_, xwindow_, | 1396 XGetImage(xdisplay_, xwindow_, |
994 snapshot_bounds.x(), snapshot_bounds.y(), | 1397 snapshot_bounds.x(), snapshot_bounds.y(), |
995 snapshot_bounds.width(), snapshot_bounds.height(), | 1398 snapshot_bounds.width(), snapshot_bounds.height(), |
996 AllPlanes, ZPixmap))); | 1399 AllPlanes, ZPixmap))); |
997 if (!image->get()) { | 1400 if (!image->get()) { |
998 LOG(ERROR) << "XGetImage failed"; | 1401 LOG(ERROR) << "XGetImage failed"; |
999 image.reset(); | 1402 image.reset(); |
1000 } | 1403 } |
1001 return image.Pass(); | 1404 return image.Pass(); |
1002 } | 1405 } |
1003 | 1406 |
1004 // static | 1407 } // namespace wm |
1005 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { | |
1006 return new RootWindowHostLinux(bounds); | |
1007 } | |
1008 | |
1009 // static | |
1010 gfx::Size RootWindowHost::GetNativeScreenSize() { | |
1011 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); | |
1012 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | |
1013 } | |
1014 | |
1015 } // namespace aura | |
OLD | NEW |