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

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

Issue 10789018: aura: Add X11 host window management. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Keep ash switches alphabetized. Created 8 years, 5 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/root_window_host_linux.h" 5 #include "ui/aura/root_window_host_linux.h"
6 6
7 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
8 #include <X11/Xcursor/Xcursor.h> 8 #include <X11/Xcursor/Xcursor.h>
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 #include <X11/cursorfont.h> 10 #include <X11/cursorfont.h>
11 #include <X11/extensions/XInput2.h> 11 #include <X11/extensions/XInput2.h>
12 #include <X11/extensions/Xcomposite.h>
12 #include <X11/extensions/Xfixes.h> 13 #include <X11/extensions/Xfixes.h>
13 #include <X11/extensions/Xrandr.h> 14 #include <X11/extensions/Xrandr.h>
15 #include <X11/extensions/shape.h>
14 #include <algorithm> 16 #include <algorithm>
15 17
16 #include "base/command_line.h" 18 #include "base/command_line.h"
17 #include "base/message_pump_aurax11.h" 19 #include "base/message_pump_aurax11.h"
18 #include "base/stl_util.h" 20 #include "base/stl_util.h"
19 #include "base/stringprintf.h" 21 #include "base/stringprintf.h"
20 #include "grit/ui_resources.h" 22 #include "grit/ui_resources.h"
23 #include "ui/aura/aura_switches.h"
21 #include "ui/aura/client/capture_client.h" 24 #include "ui/aura/client/capture_client.h"
22 #include "ui/aura/client/user_action_client.h" 25 #include "ui/aura/client/user_action_client.h"
23 #include "ui/aura/dispatcher_linux.h" 26 #include "ui/aura/dispatcher_linux.h"
24 #include "ui/aura/env.h" 27 #include "ui/aura/env.h"
25 #include "ui/aura/event.h" 28 #include "ui/aura/event.h"
26 #include "ui/aura/root_window.h" 29 #include "ui/aura/root_window.h"
27 #include "ui/base/cursor/cursor.h" 30 #include "ui/base/cursor/cursor.h"
28 #include "ui/base/keycodes/keyboard_codes.h" 31 #include "ui/base/keycodes/keyboard_codes.h"
29 #include "ui/base/resource/resource_bundle.h" 32 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/base/touch/touch_factory.h" 33 #include "ui/base/touch/touch_factory.h"
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 472
470 float scale_factor_; 473 float scale_factor_;
471 474
472 DISALLOW_COPY_AND_ASSIGN(ImageCursors); 475 DISALLOW_COPY_AND_ASSIGN(ImageCursors);
473 }; 476 };
474 477
475 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) 478 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
476 : root_window_(NULL), 479 : root_window_(NULL),
477 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 480 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
478 xwindow_(0), 481 xwindow_(0),
482 x_output_window_(0),
479 x_root_window_(DefaultRootWindow(xdisplay_)), 483 x_root_window_(DefaultRootWindow(xdisplay_)),
480 current_cursor_(ui::kCursorNull), 484 current_cursor_(ui::kCursorNull),
481 cursor_shown_(true), 485 cursor_shown_(true),
482 bounds_(bounds), 486 bounds_(bounds),
483 focus_when_shown_(false), 487 focus_when_shown_(true),
484 pointer_barriers_(NULL), 488 pointer_barriers_(NULL),
485 image_cursors_(new ImageCursors), 489 image_cursors_(new ImageCursors),
486 atom_cache_(xdisplay_, kAtomsToCache) { 490 atom_cache_(xdisplay_, kAtomsToCache) {
487 XSetWindowAttributes swa; 491 XSetWindowAttributes swa;
488 memset(&swa, 0, sizeof(swa)); 492 memset(&swa, 0, sizeof(swa));
489 swa.background_pixmap = None; 493 swa.background_pixmap = None;
490 xwindow_ = XCreateWindow( 494 long output_event_mask = ExposureMask | VisibilityChangeMask;
491 xdisplay_, x_root_window_, 495 long input_event_mask = ButtonPressMask | ButtonReleaseMask |
492 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 496 FocusChangeMask | KeyPressMask | KeyReleaseMask |
493 0, // border width 497 EnterWindowMask | LeaveWindowMask |
494 CopyFromParent, // depth 498 StructureNotifyMask | PropertyChangeMask |
495 InputOutput, 499 PointerMotionMask;
496 CopyFromParent, // visual 500 if (CommandLine::ForCurrentProcess()->HasSwitch(
497 CWBackPixmap, 501 switches::kAuraHostWindowUseFullscreen)) {
498 &swa); 502 x_output_window_ = XCompositeGetOverlayWindow(xdisplay_, x_root_window_);
503 XserverRegion region = XFixesCreateRegion(xdisplay_, NULL, 0);
504 XFixesSetWindowShapeRegion(
505 xdisplay_, x_output_window_, ShapeInput, 0, 0, region);
506 XFixesDestroyRegion(xdisplay_, region);
507 XSelectInput(xdisplay_, x_output_window_, output_event_mask);
508 static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
509 AddDispatcherForWindow(this, x_output_window_);
510 xwindow_ = XCreateWindow(
511 xdisplay_, x_root_window_,
512 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
513 0, // border width
514 CopyFromParent, // depth
515 InputOnly,
516 CopyFromParent, // visual
517 0,
518 0);
519 XSelectInput(xdisplay_, xwindow_, input_event_mask);
520 } else {
521 x_output_window_ = xwindow_ = XCreateWindow(
522 xdisplay_, x_root_window_,
523 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
524 0, // border width
525 CopyFromParent, // depth
526 InputOutput,
527 CopyFromParent, // visual
528 CWBackPixmap,
529 &swa);
530 XSelectInput(xdisplay_, xwindow_, input_event_mask | output_event_mask);
531 }
499 static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> 532 static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
500 AddDispatcherForWindow(this, xwindow_); 533 AddDispatcherForWindow(this, xwindow_);
501 534
502 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); 535 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
503 536
504 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
505 KeyPressMask | KeyReleaseMask |
506 EnterWindowMask | LeaveWindowMask |
507 ExposureMask | VisibilityChangeMask |
508 StructureNotifyMask | PropertyChangeMask |
509 PointerMotionMask;
510 XSelectInput(xdisplay_, xwindow_, event_mask);
511 XFlush(xdisplay_); 537 XFlush(xdisplay_);
512 538
513 if (base::MessagePumpForUI::HasXInput2()) 539 if (base::MessagePumpForUI::HasXInput2())
514 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 540 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
515 541
516 // Initialize invisible cursor. 542 // Initialize invisible cursor.
517 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 543 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
518 XColor black; 544 XColor black;
519 black.red = black.green = black.blue = 0; 545 black.red = black.green = black.blue = 0;
520 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_, 546 Pixmap blank = XCreateBitmapFromData(xdisplay_, x_output_window_,
521 nodata, 8, 8); 547 nodata, 8, 8);
522 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, 548 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank,
523 &black, &black, 0, 0); 549 &black, &black, 0, 0);
524 XFreePixmap(xdisplay_, blank); 550 XFreePixmap(xdisplay_, blank);
525 551
526 if (RootWindow::hide_host_cursor()) 552 if (RootWindow::hide_host_cursor())
527 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); 553 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_);
528 554
529 // TODO(erg): We currently only request window deletion events. We also 555 // TODO(erg): We currently only request window deletion events. We also
530 // should listen for activation events and anything else that GTK+ listens 556 // should listen for activation events and anything else that GTK+ listens
(...skipping 29 matching lines...) Expand all
560 } 586 }
561 587
562 RootWindowHostLinux::~RootWindowHostLinux() { 588 RootWindowHostLinux::~RootWindowHostLinux() {
563 static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> 589 static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
564 RemoveDispatcherForWindow(xwindow_); 590 RemoveDispatcherForWindow(xwindow_);
565 591
566 UnConfineCursor(); 592 UnConfineCursor();
567 593
568 XDestroyWindow(xdisplay_, xwindow_); 594 XDestroyWindow(xdisplay_, xwindow_);
569 595
596 if (CommandLine::ForCurrentProcess()->HasSwitch(
597 switches::kAuraHostWindowUseFullscreen))
598 XCompositeReleaseOverlayWindow(xdisplay_, x_root_window_);
599
570 // Clears XCursorCache. 600 // Clears XCursorCache.
571 ui::GetXCursor(ui::kCursorClearXCursorCache); 601 ui::GetXCursor(ui::kCursorClearXCursorCache);
572 602
573 XFreeCursor(xdisplay_, invisible_cursor_); 603 XFreeCursor(xdisplay_, invisible_cursor_);
574 } 604 }
575 605
576 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { 606 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
577 XEvent* xev = event; 607 XEvent* xev = event;
578 608
579 CheckXEventForConsistency(xev); 609 CheckXEventForConsistency(xev);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 root_window_ = root_window; 811 root_window_ = root_window;
782 // The device scale factor is now accessible, so load cursors now. 812 // The device scale factor is now accessible, so load cursors now.
783 image_cursors_->Reload(root_window_->layer()->device_scale_factor()); 813 image_cursors_->Reload(root_window_->layer()->device_scale_factor());
784 } 814 }
785 815
786 RootWindow* RootWindowHostLinux::GetRootWindow() { 816 RootWindow* RootWindowHostLinux::GetRootWindow() {
787 return root_window_; 817 return root_window_;
788 } 818 }
789 819
790 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { 820 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() {
821 return x_output_window_;
822 }
823
824 gfx::AcceleratedWidget RootWindowHostLinux::
825 GetAcceleratedWidgetUsedForEvents() {
791 return xwindow_; 826 return xwindow_;
792 } 827 }
793 828
794 void RootWindowHostLinux::Show() { 829 void RootWindowHostLinux::Show() {
795 // Before we map the window, set size hints. Otherwise, some window managers 830 // Before we map the window, set size hints. Otherwise, some window managers
796 // will ignore toplevel XMoveWindow commands. 831 // will ignore toplevel XMoveWindow commands.
797 XSizeHints size_hints; 832 XSizeHints size_hints;
798 size_hints.flags = PPosition; 833 size_hints.flags = PPosition;
799 size_hints.x = bounds_.x(); 834 size_hints.x = bounds_.x();
800 size_hints.y = bounds_.y(); 835 size_hints.y = bounds_.y();
(...skipping 17 matching lines...) Expand all
818 float new_scale = 853 float new_scale =
819 gfx::Screen::GetDisplayNearestWindow(root_window_).device_scale_factor(); 854 gfx::Screen::GetDisplayNearestWindow(root_window_).device_scale_factor();
820 bool size_changed = bounds_.size() != bounds.size() || 855 bool size_changed = bounds_.size() != bounds.size() ||
821 current_scale != new_scale; 856 current_scale != new_scale;
822 857
823 if (!size_changed) { 858 if (!size_changed) {
824 root_window_->SchedulePaintInRect(root_window_->bounds()); 859 root_window_->SchedulePaintInRect(root_window_->bounds());
825 return; 860 return;
826 } 861 }
827 862
828 if (bounds.size() != bounds_.size()) 863 if (bounds.size() != bounds_.size()) {
829 XResizeWindow(xdisplay_, xwindow_, bounds.width(), bounds.height()); 864 XResizeWindow(xdisplay_, xwindow_, bounds.width(), bounds.height());
865 if (x_output_window_ != xwindow_)
866 XResizeWindow(
867 xdisplay_, x_output_window_, bounds.width(), bounds.height());
868 }
830 869
831 if (bounds.origin() != bounds_.origin()) 870 if (bounds.origin() != bounds_.origin()) {
832 XMoveWindow(xdisplay_, xwindow_, bounds.x(), bounds.y()); 871 XMoveWindow(xdisplay_, xwindow_, bounds.x(), bounds.y());
872 if (x_output_window_ != xwindow_)
873 XMoveWindow(xdisplay_, x_output_window_, bounds.x(), bounds.y());
874 }
833 875
834 // Assume that the resize will go through as requested, which should be the 876 // Assume that the resize will go through as requested, which should be the
835 // case if we're running without a window manager. If there's a window 877 // case if we're running without a window manager. If there's a window
836 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a 878 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
837 // (possibly synthetic) ConfigureNotify about the actual size and correct 879 // (possibly synthetic) ConfigureNotify about the actual size and correct
838 // |bounds_| later. 880 // |bounds_| later.
839 bounds_ = bounds; 881 bounds_ = bounds;
840 if (size_changed) 882 if (size_changed)
841 root_window_->OnHostResized(bounds.size()); 883 root_window_->OnHostResized(bounds.size());
842 } 884 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 k_NET_WM_USER_TIME, 988 k_NET_WM_USER_TIME,
947 k_NET_WM_USER_TIME, 989 k_NET_WM_USER_TIME,
948 0); 990 0);
949 } 991 }
950 } 992 }
951 993
952 bool RootWindowHostLinux::GrabSnapshot( 994 bool RootWindowHostLinux::GrabSnapshot(
953 const gfx::Rect& snapshot_bounds, 995 const gfx::Rect& snapshot_bounds,
954 std::vector<unsigned char>* png_representation) { 996 std::vector<unsigned char>* png_representation) {
955 XImage* image = XGetImage( 997 XImage* image = XGetImage(
956 xdisplay_, xwindow_, 998 xdisplay_, x_output_window_,
957 snapshot_bounds.x(), snapshot_bounds.y(), 999 snapshot_bounds.x(), snapshot_bounds.y(),
958 snapshot_bounds.width(), snapshot_bounds.height(), 1000 snapshot_bounds.width(), snapshot_bounds.height(),
959 AllPlanes, ZPixmap); 1001 AllPlanes, ZPixmap);
960 1002
961 if (!image) { 1003 if (!image) {
962 LOG(ERROR) << "XGetImage failed"; 1004 LOG(ERROR) << "XGetImage failed";
963 return false; 1005 return false;
964 } 1006 }
965 1007
966 gfx::PNGCodec::ColorFormat color_format; 1008 gfx::PNGCodec::ColorFormat color_format;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 break; 1069 break;
1028 } 1070 }
1029 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); 1071 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
1030 } 1072 }
1031 1073
1032 void RootWindowHostLinux::OnDeviceScaleFactorChanged( 1074 void RootWindowHostLinux::OnDeviceScaleFactorChanged(
1033 float device_scale_factor) { 1075 float device_scale_factor) {
1034 image_cursors_->Reload(device_scale_factor); 1076 image_cursors_->Reload(device_scale_factor);
1035 } 1077 }
1036 1078
1079 bool RootWindowHostLinux::DispatchNativeEvent(
1080 const base::NativeEvent& native_event) {
1081 return Dispatch(native_event);
1082 }
1083
1037 bool RootWindowHostLinux::IsWindowManagerPresent() { 1084 bool RootWindowHostLinux::IsWindowManagerPresent() {
1038 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 1085 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
1039 // of WM_Sn selections (where n is a screen number). 1086 // of WM_Sn selections (where n is a screen number).
1040 return XGetSelectionOwner( 1087 return XGetSelectionOwner(
1041 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 1088 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
1042 } 1089 }
1043 1090
1044 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { 1091 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
1045 ::Cursor xcursor = 1092 ::Cursor xcursor =
1046 image_cursors_->IsImageCursor(cursor) ? 1093 image_cursors_->IsImageCursor(cursor) ?
1047 image_cursors_->ImageCursorFromNative(cursor) : 1094 image_cursors_->ImageCursorFromNative(cursor) :
1048 (cursor == ui::kCursorNone ? invisible_cursor_ : 1095 (cursor == ui::kCursorNone ? invisible_cursor_ :
1049 (cursor == ui::kCursorCustom ? cursor.platform() : 1096 (cursor == ui::kCursorCustom ? cursor.platform() :
1050 ui::GetXCursor(CursorShapeFromNative(cursor)))); 1097 ui::GetXCursor(CursorShapeFromNative(cursor))));
1051 XDefineCursor(xdisplay_, xwindow_, xcursor); 1098 if (x_output_window_ != xwindow_)
1099 XDefineCursor(xdisplay_, x_root_window_, xcursor);
1100 else
1101 XDefineCursor(xdisplay_, xwindow_, xcursor);
1102 GetRootWindow()->OnCursorChanged(xcursor);
1052 } 1103 }
1053 1104
1054 // static 1105 // static
1055 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { 1106 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
1056 return new RootWindowHostLinux(bounds); 1107 return new RootWindowHostLinux(bounds);
1057 } 1108 }
1058 1109
1059 // static 1110 // static
1060 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( 1111 RootWindowHost* RootWindowHost::GetForAcceleratedWidget(
1061 gfx::AcceleratedWidget accelerated_widget) { 1112 gfx::AcceleratedWidget accelerated_widget) {
1062 return reinterpret_cast<RootWindowHost*>( 1113 return reinterpret_cast<RootWindowHost*>(
1063 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); 1114 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey));
1064 } 1115 }
1065 1116
1066 // static 1117 // static
1067 gfx::Size RootWindowHost::GetNativeScreenSize() { 1118 gfx::Size RootWindowHost::GetNativeScreenSize() {
1068 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 1119 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1069 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 1120 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1070 } 1121 }
1071 1122
1072 } // namespace aura 1123 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698