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 "ui/aura/root_window_host_linux.h" |
6 | 6 |
| 7 #include <strings.h> |
7 #include <X11/cursorfont.h> | 8 #include <X11/cursorfont.h> |
8 #include <X11/extensions/Xfixes.h> | 9 #include <X11/extensions/Xfixes.h> |
9 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
10 #include <X11/extensions/Xrandr.h> | 11 #include <X11/extensions/Xrandr.h> |
11 #include <X11/Xatom.h> | 12 #include <X11/Xatom.h> |
12 #include <X11/Xcursor/Xcursor.h> | 13 #include <X11/Xcursor/Xcursor.h> |
13 #include <X11/Xlib.h> | 14 #include <X11/Xlib.h> |
| 15 |
14 #include <algorithm> | 16 #include <algorithm> |
15 | 17 |
16 #include "base/command_line.h" | 18 #include "base/command_line.h" |
17 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
18 #include "base/message_pump_aurax11.h" | 20 #include "base/message_pump_aurax11.h" |
19 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
20 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
| 23 #include "third_party/skia/include/core/SkBitmap.h" |
| 24 #include "third_party/skia/include/core/SkCanvas.h" |
21 #include "ui/aura/client/capture_client.h" | 25 #include "ui/aura/client/capture_client.h" |
22 #include "ui/aura/client/cursor_client.h" | 26 #include "ui/aura/client/cursor_client.h" |
23 #include "ui/aura/client/screen_position_client.h" | 27 #include "ui/aura/client/screen_position_client.h" |
24 #include "ui/aura/client/user_action_client.h" | 28 #include "ui/aura/client/user_action_client.h" |
25 #include "ui/aura/env.h" | 29 #include "ui/aura/env.h" |
26 #include "ui/aura/root_window.h" | 30 #include "ui/aura/root_window.h" |
27 #include "ui/base/cursor/cursor.h" | 31 #include "ui/base/cursor/cursor.h" |
28 #include "ui/base/events/event.h" | 32 #include "ui/base/events/event.h" |
29 #include "ui/base/keycodes/keyboard_codes.h" | 33 #include "ui/base/keycodes/keyboard_codes.h" |
30 #include "ui/base/touch/touch_factory.h" | 34 #include "ui/base/touch/touch_factory.h" |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 } | 429 } |
426 | 430 |
427 ui::MouseEvent mouseev(xev); | 431 ui::MouseEvent mouseev(xev); |
428 TranslateAndDispatchMouseEvent(&mouseev); | 432 TranslateAndDispatchMouseEvent(&mouseev); |
429 break; | 433 break; |
430 } | 434 } |
431 } | 435 } |
432 return true; | 436 return true; |
433 } | 437 } |
434 | 438 |
435 bool RootWindowHostLinux::DispatchEventForRootWindow( | |
436 const base::NativeEvent& event) { | |
437 switch (event->type) { | |
438 case ConfigureNotify: | |
439 DCHECK_EQ(x_root_window_, event->xconfigure.event); | |
440 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, | |
441 event->xconfigure.width, event->xconfigure.height); | |
442 break; | |
443 | |
444 case GenericEvent: | |
445 DispatchXI2Event(event); | |
446 break; | |
447 } | |
448 | |
449 return true; | |
450 } | |
451 | |
452 void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) { | |
453 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | |
454 XEvent* xev = event; | |
455 if (!factory->ShouldProcessXI2Event(xev)) | |
456 return; | |
457 | |
458 ui::EventType type = ui::EventTypeFromNative(xev); | |
459 XEvent last_event; | |
460 int num_coalesced = 0; | |
461 | |
462 switch (type) { | |
463 case ui::ET_TOUCH_MOVED: | |
464 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
465 if (num_coalesced > 0) | |
466 xev = &last_event; | |
467 // fallthrough | |
468 case ui::ET_TOUCH_PRESSED: | |
469 case ui::ET_TOUCH_RELEASED: { | |
470 ui::TouchEvent touchev(xev); | |
471 #if defined(OS_CHROMEOS) | |
472 // X maps the touch-surface to the size of the X root-window. In | |
473 // multi-monitor setup, the X root-window size is a combination of | |
474 // both the monitor sizes. So it is necessary to remap the location of | |
475 // the event from the X root-window to the X host-window for the aura | |
476 // root-window. | |
477 if (base::chromeos::IsRunningOnChromeOS()) { | |
478 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); | |
479 if (!bounds_.Contains(touchev.location())) { | |
480 // This might still be in the bezel region. | |
481 gfx::Rect expanded(bounds_); | |
482 expanded.Inset(-kXRootWindowPaddingLeft, | |
483 -kXRootWindowPaddingTop, | |
484 -kXRootWindowPaddingRight, | |
485 -kXRootWindowPaddingBottom); | |
486 if (!expanded.Contains(touchev.location())) | |
487 break; | |
488 } | |
489 } | |
490 #endif // defined(OS_CHROMEOS) | |
491 delegate_->OnHostTouchEvent(&touchev); | |
492 break; | |
493 } | |
494 case ui::ET_MOUSE_MOVED: | |
495 case ui::ET_MOUSE_DRAGGED: | |
496 case ui::ET_MOUSE_PRESSED: | |
497 case ui::ET_MOUSE_RELEASED: | |
498 case ui::ET_MOUSE_ENTERED: | |
499 case ui::ET_MOUSE_EXITED: { | |
500 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { | |
501 // If this is a motion event, we want to coalesce all pending motion | |
502 // events that are at the top of the queue. | |
503 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
504 if (num_coalesced > 0) | |
505 xev = &last_event; | |
506 } else if (type == ui::ET_MOUSE_PRESSED) { | |
507 XIDeviceEvent* xievent = | |
508 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
509 int button = xievent->detail; | |
510 if (button == kBackMouseButton || button == kForwardMouseButton) { | |
511 client::UserActionClient* gesture_client = | |
512 client::GetUserActionClient(delegate_->AsRootWindow()); | |
513 if (gesture_client) { | |
514 bool reverse_direction = | |
515 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); | |
516 gesture_client->OnUserAction( | |
517 (button == kBackMouseButton && !reverse_direction) || | |
518 (button == kForwardMouseButton && reverse_direction) ? | |
519 client::UserActionClient::BACK : | |
520 client::UserActionClient::FORWARD); | |
521 } | |
522 break; | |
523 } | |
524 } | |
525 ui::MouseEvent mouseev(xev); | |
526 TranslateAndDispatchMouseEvent(&mouseev); | |
527 break; | |
528 } | |
529 case ui::ET_MOUSEWHEEL: { | |
530 ui::MouseWheelEvent mouseev(xev); | |
531 TranslateAndDispatchMouseEvent(&mouseev); | |
532 break; | |
533 } | |
534 case ui::ET_SCROLL_FLING_START: | |
535 case ui::ET_SCROLL_FLING_CANCEL: | |
536 case ui::ET_SCROLL: { | |
537 ui::ScrollEvent scrollev(xev); | |
538 delegate_->OnHostScrollEvent(&scrollev); | |
539 break; | |
540 } | |
541 case ui::ET_UNKNOWN: | |
542 break; | |
543 default: | |
544 NOTREACHED(); | |
545 } | |
546 | |
547 // If we coalesced an event we need to free its cookie. | |
548 if (num_coalesced > 0) | |
549 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | |
550 } | |
551 | |
552 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { | 439 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { |
553 delegate_ = delegate; | 440 delegate_ = delegate; |
554 } | 441 } |
555 | 442 |
556 RootWindow* RootWindowHostLinux::GetRootWindow() { | 443 RootWindow* RootWindowHostLinux::GetRootWindow() { |
557 return delegate_->AsRootWindow(); | 444 return delegate_->AsRootWindow(); |
558 } | 445 } |
559 | 446 |
560 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 447 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
561 return xwindow_; | 448 return xwindow_; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME"; | 621 static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME"; |
735 focus_when_shown_ = focus_when_shown; | 622 focus_when_shown_ = focus_when_shown; |
736 if (IsWindowManagerPresent() && !focus_when_shown_) { | 623 if (IsWindowManagerPresent() && !focus_when_shown_) { |
737 ui::SetIntProperty(xwindow_, | 624 ui::SetIntProperty(xwindow_, |
738 k_NET_WM_USER_TIME, | 625 k_NET_WM_USER_TIME, |
739 k_NET_WM_USER_TIME, | 626 k_NET_WM_USER_TIME, |
740 0); | 627 0); |
741 } | 628 } |
742 } | 629 } |
743 | 630 |
| 631 bool RootWindowHostLinux::CopyAreaToSkCanvas(const gfx::Rect& source_bounds, |
| 632 const gfx::Point& dest_offset, |
| 633 SkCanvas* canvas) { |
| 634 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds)); |
| 635 if (!scoped_image.get()) |
| 636 return false; |
| 637 |
| 638 XImage* image = scoped_image->get(); |
| 639 DCHECK(image); |
| 640 |
| 641 if (image->bits_per_pixel == 32) { |
| 642 // Set the alpha channel before copying to the canvas. Otherwise, areas of |
| 643 // the framebuffer that were cleared by ply-image rather than being obscured |
| 644 // by an image during boot may end up transparent. |
| 645 // TODO(derat|marcheu): Remove this if/when ply-image has been updated to |
| 646 // set the framebuffer's alpha channel regardless of whether the device |
| 647 // claims to support alpha or not. |
| 648 for (int i = 0; i < image->width * image->height * 4; i += 4) |
| 649 image->data[i + 3] = 0xff; |
| 650 |
| 651 SkBitmap bitmap; |
| 652 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 653 image->width, image->height, |
| 654 image->bytes_per_line); |
| 655 bitmap.setPixels(image->data); |
| 656 SkCanvas::Config8888 config = |
| 657 (image->byte_order == LSBFirst) ? |
| 658 SkCanvas::kBGRA_Unpremul_Config8888 : |
| 659 SkCanvas::kRGBA_Unpremul_Config8888; |
| 660 canvas->writePixels(bitmap, dest_offset.x(), dest_offset.y(), config); |
| 661 } else if (image->bits_per_pixel == 24) { |
| 662 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; |
| 663 return false; |
| 664 } |
| 665 |
| 666 return true; |
| 667 } |
| 668 |
744 bool RootWindowHostLinux::GrabSnapshot( | 669 bool RootWindowHostLinux::GrabSnapshot( |
745 const gfx::Rect& snapshot_bounds, | 670 const gfx::Rect& snapshot_bounds, |
746 std::vector<unsigned char>* png_representation) { | 671 std::vector<unsigned char>* png_representation) { |
747 ui::XScopedImage image(XGetImage( | 672 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(snapshot_bounds)); |
748 xdisplay_, xwindow_, | 673 if (!scoped_image.get()) |
749 snapshot_bounds.x(), snapshot_bounds.y(), | 674 return false; |
750 snapshot_bounds.width(), snapshot_bounds.height(), | |
751 AllPlanes, ZPixmap)); | |
752 | 675 |
753 if (!image.get()) { | 676 XImage* image = scoped_image->get(); |
754 LOG(ERROR) << "XGetImage failed"; | 677 DCHECK(image); |
755 return false; | |
756 } | |
757 | 678 |
758 gfx::PNGCodec::ColorFormat color_format; | 679 gfx::PNGCodec::ColorFormat color_format; |
759 | 680 |
760 if (image->bits_per_pixel == 32) { | 681 if (image->bits_per_pixel == 32) { |
761 color_format = (image->byte_order == LSBFirst) ? | 682 color_format = (image->byte_order == LSBFirst) ? |
762 gfx::PNGCodec::FORMAT_BGRA : gfx::PNGCodec::FORMAT_RGBA; | 683 gfx::PNGCodec::FORMAT_BGRA : gfx::PNGCodec::FORMAT_RGBA; |
763 } else if (image->bits_per_pixel == 24) { | 684 } else if (image->bits_per_pixel == 24) { |
764 // PNGCodec accepts FORMAT_RGB for 3 bytes per pixel: | 685 // PNGCodec accepts FORMAT_RGB for 3 bytes per pixel: |
765 color_format = gfx::PNGCodec::FORMAT_RGB; | 686 color_format = gfx::PNGCodec::FORMAT_RGB; |
766 if (image->byte_order == LSBFirst) { | 687 if (image->byte_order == LSBFirst) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 } | 741 } |
821 | 742 |
822 void RootWindowHostLinux::OnDeviceScaleFactorChanged( | 743 void RootWindowHostLinux::OnDeviceScaleFactorChanged( |
823 float device_scale_factor) { | 744 float device_scale_factor) { |
824 } | 745 } |
825 | 746 |
826 void RootWindowHostLinux::PrepareForShutdown() { | 747 void RootWindowHostLinux::PrepareForShutdown() { |
827 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); | 748 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); |
828 } | 749 } |
829 | 750 |
| 751 bool RootWindowHostLinux::DispatchEventForRootWindow( |
| 752 const base::NativeEvent& event) { |
| 753 switch (event->type) { |
| 754 case ConfigureNotify: |
| 755 DCHECK_EQ(x_root_window_, event->xconfigure.event); |
| 756 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, |
| 757 event->xconfigure.width, event->xconfigure.height); |
| 758 break; |
| 759 |
| 760 case GenericEvent: |
| 761 DispatchXI2Event(event); |
| 762 break; |
| 763 } |
| 764 |
| 765 return true; |
| 766 } |
| 767 |
| 768 void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) { |
| 769 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
| 770 XEvent* xev = event; |
| 771 if (!factory->ShouldProcessXI2Event(xev)) |
| 772 return; |
| 773 |
| 774 ui::EventType type = ui::EventTypeFromNative(xev); |
| 775 XEvent last_event; |
| 776 int num_coalesced = 0; |
| 777 |
| 778 switch (type) { |
| 779 case ui::ET_TOUCH_MOVED: |
| 780 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); |
| 781 if (num_coalesced > 0) |
| 782 xev = &last_event; |
| 783 // fallthrough |
| 784 case ui::ET_TOUCH_PRESSED: |
| 785 case ui::ET_TOUCH_RELEASED: { |
| 786 ui::TouchEvent touchev(xev); |
| 787 #if defined(OS_CHROMEOS) |
| 788 // X maps the touch-surface to the size of the X root-window. In |
| 789 // multi-monitor setup, the X root-window size is a combination of |
| 790 // both the monitor sizes. So it is necessary to remap the location of |
| 791 // the event from the X root-window to the X host-window for the aura |
| 792 // root-window. |
| 793 if (base::chromeos::IsRunningOnChromeOS()) { |
| 794 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); |
| 795 if (!bounds_.Contains(touchev.location())) { |
| 796 // This might still be in the bezel region. |
| 797 gfx::Rect expanded(bounds_); |
| 798 expanded.Inset(-kXRootWindowPaddingLeft, |
| 799 -kXRootWindowPaddingTop, |
| 800 -kXRootWindowPaddingRight, |
| 801 -kXRootWindowPaddingBottom); |
| 802 if (!expanded.Contains(touchev.location())) |
| 803 break; |
| 804 } |
| 805 } |
| 806 #endif // defined(OS_CHROMEOS) |
| 807 delegate_->OnHostTouchEvent(&touchev); |
| 808 break; |
| 809 } |
| 810 case ui::ET_MOUSE_MOVED: |
| 811 case ui::ET_MOUSE_DRAGGED: |
| 812 case ui::ET_MOUSE_PRESSED: |
| 813 case ui::ET_MOUSE_RELEASED: |
| 814 case ui::ET_MOUSE_ENTERED: |
| 815 case ui::ET_MOUSE_EXITED: { |
| 816 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { |
| 817 // If this is a motion event, we want to coalesce all pending motion |
| 818 // events that are at the top of the queue. |
| 819 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); |
| 820 if (num_coalesced > 0) |
| 821 xev = &last_event; |
| 822 } else if (type == ui::ET_MOUSE_PRESSED) { |
| 823 XIDeviceEvent* xievent = |
| 824 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 825 int button = xievent->detail; |
| 826 if (button == kBackMouseButton || button == kForwardMouseButton) { |
| 827 client::UserActionClient* gesture_client = |
| 828 client::GetUserActionClient(delegate_->AsRootWindow()); |
| 829 if (gesture_client) { |
| 830 bool reverse_direction = |
| 831 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); |
| 832 gesture_client->OnUserAction( |
| 833 (button == kBackMouseButton && !reverse_direction) || |
| 834 (button == kForwardMouseButton && reverse_direction) ? |
| 835 client::UserActionClient::BACK : |
| 836 client::UserActionClient::FORWARD); |
| 837 } |
| 838 break; |
| 839 } |
| 840 } |
| 841 ui::MouseEvent mouseev(xev); |
| 842 TranslateAndDispatchMouseEvent(&mouseev); |
| 843 break; |
| 844 } |
| 845 case ui::ET_MOUSEWHEEL: { |
| 846 ui::MouseWheelEvent mouseev(xev); |
| 847 TranslateAndDispatchMouseEvent(&mouseev); |
| 848 break; |
| 849 } |
| 850 case ui::ET_SCROLL_FLING_START: |
| 851 case ui::ET_SCROLL_FLING_CANCEL: |
| 852 case ui::ET_SCROLL: { |
| 853 ui::ScrollEvent scrollev(xev); |
| 854 delegate_->OnHostScrollEvent(&scrollev); |
| 855 break; |
| 856 } |
| 857 case ui::ET_UNKNOWN: |
| 858 break; |
| 859 default: |
| 860 NOTREACHED(); |
| 861 } |
| 862 |
| 863 // If we coalesced an event we need to free its cookie. |
| 864 if (num_coalesced > 0) |
| 865 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
| 866 } |
| 867 |
830 bool RootWindowHostLinux::IsWindowManagerPresent() { | 868 bool RootWindowHostLinux::IsWindowManagerPresent() { |
831 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 869 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
832 // of WM_Sn selections (where n is a screen number). | 870 // of WM_Sn selections (where n is a screen number). |
833 return XGetSelectionOwner( | 871 return XGetSelectionOwner( |
834 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; | 872 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; |
835 } | 873 } |
836 | 874 |
837 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 875 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
838 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 876 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
839 } | 877 } |
840 | 878 |
841 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( | 879 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( |
842 ui::MouseEvent* event) { | 880 ui::MouseEvent* event) { |
843 RootWindow* root = GetRootWindow(); | 881 RootWindow* root = GetRootWindow(); |
844 client::ScreenPositionClient* screen_position_client = | 882 client::ScreenPositionClient* screen_position_client = |
845 GetScreenPositionClient(root); | 883 GetScreenPositionClient(root); |
846 if (screen_position_client && !bounds_.Contains(event->location())) { | 884 if (screen_position_client && !bounds_.Contains(event->location())) { |
847 gfx::Point location(event->location()); | 885 gfx::Point location(event->location()); |
848 screen_position_client->ConvertNativePointToScreen(root, &location); | 886 screen_position_client->ConvertNativePointToScreen(root, &location); |
849 screen_position_client->ConvertPointFromScreen(root, &location); | 887 screen_position_client->ConvertPointFromScreen(root, &location); |
850 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to | 888 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to |
851 // root. | 889 // root. |
852 location = ui::ConvertPointToPixel(root->layer(), location); | 890 location = ui::ConvertPointToPixel(root->layer(), location); |
853 event->set_location(location); | 891 event->set_location(location); |
854 event->set_root_location(location); | 892 event->set_root_location(location); |
855 } | 893 } |
856 delegate_->OnHostMouseEvent(event); | 894 delegate_->OnHostMouseEvent(event); |
857 } | 895 } |
858 | 896 |
| 897 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage( |
| 898 const gfx::Rect& snapshot_bounds) { |
| 899 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( |
| 900 XGetImage(xdisplay_, xwindow_, |
| 901 snapshot_bounds.x(), snapshot_bounds.y(), |
| 902 snapshot_bounds.width(), snapshot_bounds.height(), |
| 903 AllPlanes, ZPixmap))); |
| 904 if (!image->get()) { |
| 905 LOG(ERROR) << "XGetImage failed"; |
| 906 image.reset(); |
| 907 } |
| 908 return image.Pass(); |
| 909 } |
| 910 |
859 // static | 911 // static |
860 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { | 912 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { |
861 return new RootWindowHostLinux(bounds); | 913 return new RootWindowHostLinux(bounds); |
862 } | 914 } |
863 | 915 |
864 // static | 916 // static |
865 gfx::Size RootWindowHost::GetNativeScreenSize() { | 917 gfx::Size RootWindowHost::GetNativeScreenSize() { |
866 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 918 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
867 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 919 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
868 } | 920 } |
869 | 921 |
870 } // namespace aura | 922 } // namespace aura |
OLD | NEW |