Index: ui/aura/root_window_host_linux.cc |
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc |
index 9cdef7c07418010704470f472f9c032d3aca53be..ca2d60e30916f6f1f3ac69336ea34c7cc811feac 100644 |
--- a/ui/aura/root_window_host_linux.cc |
+++ b/ui/aura/root_window_host_linux.cc |
@@ -9,8 +9,10 @@ |
#include <X11/Xlib.h> |
#include <X11/cursorfont.h> |
#include <X11/extensions/XInput2.h> |
+#include <X11/extensions/Xcomposite.h> |
#include <X11/extensions/Xfixes.h> |
#include <X11/extensions/Xrandr.h> |
+#include <X11/extensions/shape.h> |
#include <algorithm> |
#include "base/command_line.h" |
@@ -18,6 +20,7 @@ |
#include "base/stl_util.h" |
#include "base/stringprintf.h" |
#include "grit/ui_resources.h" |
+#include "ui/aura/aura_switches.h" |
#include "ui/aura/client/capture_client.h" |
#include "ui/aura/client/user_action_client.h" |
#include "ui/aura/dispatcher_linux.h" |
@@ -476,38 +479,61 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
: root_window_(NULL), |
xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), |
xwindow_(0), |
+ x_output_window_(0), |
x_root_window_(DefaultRootWindow(xdisplay_)), |
current_cursor_(ui::kCursorNull), |
cursor_shown_(true), |
bounds_(bounds), |
- focus_when_shown_(false), |
+ focus_when_shown_(true), |
pointer_barriers_(NULL), |
image_cursors_(new ImageCursors), |
atom_cache_(xdisplay_, kAtomsToCache) { |
XSetWindowAttributes swa; |
memset(&swa, 0, sizeof(swa)); |
swa.background_pixmap = None; |
- xwindow_ = XCreateWindow( |
- xdisplay_, x_root_window_, |
- bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
- 0, // border width |
- CopyFromParent, // depth |
- InputOutput, |
- CopyFromParent, // visual |
- CWBackPixmap, |
- &swa); |
+ long output_event_mask = ExposureMask | VisibilityChangeMask; |
+ long input_event_mask = ButtonPressMask | ButtonReleaseMask | |
+ FocusChangeMask | KeyPressMask | KeyReleaseMask | |
+ EnterWindowMask | LeaveWindowMask | |
+ StructureNotifyMask | PropertyChangeMask | |
+ PointerMotionMask; |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAuraHostWindowUseFullscreen)) { |
+ x_output_window_ = XCompositeGetOverlayWindow(xdisplay_, x_root_window_); |
+ XserverRegion region = XFixesCreateRegion(xdisplay_, NULL, 0); |
+ XFixesSetWindowShapeRegion( |
+ xdisplay_, x_output_window_, ShapeInput, 0, 0, region); |
+ XFixesDestroyRegion(xdisplay_, region); |
+ XSelectInput(xdisplay_, x_output_window_, output_event_mask); |
+ static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> |
+ AddDispatcherForWindow(this, x_output_window_); |
+ xwindow_ = XCreateWindow( |
+ xdisplay_, x_root_window_, |
+ bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
+ 0, // border width |
+ CopyFromParent, // depth |
+ InputOnly, |
+ CopyFromParent, // visual |
+ 0, |
+ 0); |
+ XSelectInput(xdisplay_, xwindow_, input_event_mask); |
+ } else { |
+ x_output_window_ = xwindow_ = XCreateWindow( |
+ xdisplay_, x_root_window_, |
+ bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
+ 0, // border width |
+ CopyFromParent, // depth |
+ InputOutput, |
+ CopyFromParent, // visual |
+ CWBackPixmap, |
+ &swa); |
+ XSelectInput(xdisplay_, xwindow_, input_event_mask | output_event_mask); |
+ } |
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> |
AddDispatcherForWindow(this, xwindow_); |
prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); |
- long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
- KeyPressMask | KeyReleaseMask | |
- EnterWindowMask | LeaveWindowMask | |
- ExposureMask | VisibilityChangeMask | |
- StructureNotifyMask | PropertyChangeMask | |
- PointerMotionMask; |
- XSelectInput(xdisplay_, xwindow_, event_mask); |
XFlush(xdisplay_); |
if (base::MessagePumpForUI::HasXInput2()) |
@@ -517,7 +543,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
XColor black; |
black.red = black.green = black.blue = 0; |
- Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_, |
+ Pixmap blank = XCreateBitmapFromData(xdisplay_, x_output_window_, |
nodata, 8, 8); |
invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, |
&black, &black, 0, 0); |
@@ -567,6 +593,10 @@ RootWindowHostLinux::~RootWindowHostLinux() { |
XDestroyWindow(xdisplay_, xwindow_); |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAuraHostWindowUseFullscreen)) |
+ XCompositeReleaseOverlayWindow(xdisplay_, x_root_window_); |
+ |
// Clears XCursorCache. |
ui::GetXCursor(ui::kCursorClearXCursorCache); |
@@ -788,6 +818,11 @@ RootWindow* RootWindowHostLinux::GetRootWindow() { |
} |
gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
+ return x_output_window_; |
+} |
+ |
+gfx::AcceleratedWidget RootWindowHostLinux:: |
+ GetAcceleratedWidgetUsedForEvents() { |
return xwindow_; |
} |
@@ -825,11 +860,18 @@ void RootWindowHostLinux::SetBounds(const gfx::Rect& bounds) { |
return; |
} |
- if (bounds.size() != bounds_.size()) |
+ if (bounds.size() != bounds_.size()) { |
XResizeWindow(xdisplay_, xwindow_, bounds.width(), bounds.height()); |
+ if (x_output_window_ != xwindow_) |
+ XResizeWindow( |
+ xdisplay_, x_output_window_, bounds.width(), bounds.height()); |
+ } |
- if (bounds.origin() != bounds_.origin()) |
+ if (bounds.origin() != bounds_.origin()) { |
XMoveWindow(xdisplay_, xwindow_, bounds.x(), bounds.y()); |
+ if (x_output_window_ != xwindow_) |
+ XMoveWindow(xdisplay_, x_output_window_, bounds.x(), bounds.y()); |
+ } |
// Assume that the resize will go through as requested, which should be the |
// case if we're running without a window manager. If there's a window |
@@ -953,7 +995,7 @@ bool RootWindowHostLinux::GrabSnapshot( |
const gfx::Rect& snapshot_bounds, |
std::vector<unsigned char>* png_representation) { |
XImage* image = XGetImage( |
- xdisplay_, xwindow_, |
+ xdisplay_, x_output_window_, |
snapshot_bounds.x(), snapshot_bounds.y(), |
snapshot_bounds.width(), snapshot_bounds.height(), |
AllPlanes, ZPixmap); |
@@ -1034,6 +1076,11 @@ void RootWindowHostLinux::OnDeviceScaleFactorChanged( |
image_cursors_->Reload(device_scale_factor); |
} |
+bool RootWindowHostLinux::DispatchNativeEvent( |
+ const base::NativeEvent& native_event) { |
+ return Dispatch(native_event); |
+} |
+ |
bool RootWindowHostLinux::IsWindowManagerPresent() { |
// Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
// of WM_Sn selections (where n is a screen number). |
@@ -1048,7 +1095,11 @@ void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
(cursor == ui::kCursorNone ? invisible_cursor_ : |
(cursor == ui::kCursorCustom ? cursor.platform() : |
ui::GetXCursor(CursorShapeFromNative(cursor)))); |
- XDefineCursor(xdisplay_, xwindow_, xcursor); |
+ if (x_output_window_ != xwindow_) |
+ XDefineCursor(xdisplay_, x_root_window_, xcursor); |
+ else |
+ XDefineCursor(xdisplay_, xwindow_, xcursor); |
+ GetRootWindow()->OnCursorChanged(xcursor); |
} |
// static |