| Index: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
|
| diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
|
| index d1695c136ca7b252851725800e2da4193303303d..b1f5ac609277d6e65bb2aabf592f78de3e38ca09 100644
|
| --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
|
| +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
|
| @@ -11,6 +11,7 @@
|
| #include <X11/Xutil.h>
|
|
|
| #include "base/basictypes.h"
|
| +#include "base/command_line.h"
|
| #include "base/debug/trace_event.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| @@ -40,6 +41,7 @@
|
| #include "ui/views/ime/input_method.h"
|
| #include "ui/views/linux_ui/linux_ui.h"
|
| #include "ui/views/views_delegate.h"
|
| +#include "ui/views/views_switches.h"
|
| #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
|
| #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
|
| #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
|
| @@ -75,6 +77,7 @@ const char* kAtomsToCache[] = {
|
| "WM_DELETE_WINDOW",
|
| "WM_PROTOCOLS",
|
| "WM_S0",
|
| + "_NET_WM_CM_S0",
|
| "_NET_WM_ICON",
|
| "_NET_WM_NAME",
|
| "_NET_WM_PID",
|
| @@ -131,6 +134,7 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11(
|
| is_fullscreen_(false),
|
| is_always_on_top_(false),
|
| use_native_frame_(false),
|
| + use_argb_visual_(false),
|
| drag_drop_client_(NULL),
|
| current_cursor_(ui::kCursorNull),
|
| native_widget_delegate_(native_widget_delegate),
|
| @@ -247,6 +251,8 @@ void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
|
| x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
|
| aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get());
|
|
|
| + SetWindowTransparency();
|
| +
|
| native_widget_delegate_->OnNativeWidgetCreated(true);
|
| }
|
|
|
| @@ -948,15 +954,41 @@ void DesktopWindowTreeHostX11::InitX11Window(
|
| if (swa.override_redirect)
|
| attribute_mask |= CWOverrideRedirect;
|
|
|
| + // Detect whether we're running inside a compositing manager. If so, try to
|
| + // use the ARGB visual. Otherwise, just use our parent's visual.
|
| + Visual* visual = CopyFromParent;
|
| + int depth = CopyFromParent;
|
| + if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableTransparentVisuals) &&
|
| + XGetSelectionOwner(xdisplay_,
|
| + atom_cache_.GetAtom("_NET_WM_CM_S0")) != None) {
|
| + Visual* rgba_visual = GetARGBVisual();
|
| + if (rgba_visual) {
|
| + visual = rgba_visual;
|
| + depth = 32;
|
| +
|
| + attribute_mask |= CWColormap;
|
| + swa.colormap = XCreateColormap(xdisplay_, x_root_window_, visual,
|
| + AllocNone);
|
| +
|
| + // x.org will BadMatch if we don't set a border when the depth isn't the
|
| + // same as the parent depth.
|
| + attribute_mask |= CWBorderPixel;
|
| + swa.border_pixel = 0;
|
| +
|
| + use_argb_visual_ = true;
|
| + }
|
| + }
|
| +
|
| bounds_ = params.bounds;
|
| xwindow_ = XCreateWindow(
|
| xdisplay_, x_root_window_,
|
| bounds_.x(), bounds_.y(),
|
| bounds_.width(), bounds_.height(),
|
| 0, // border width
|
| - CopyFromParent, // depth
|
| + depth,
|
| InputOutput,
|
| - CopyFromParent, // visual
|
| + visual,
|
| attribute_mask,
|
| &swa);
|
| if (ui::PlatformEventSource::GetInstance())
|
| @@ -1238,6 +1270,39 @@ void DesktopWindowTreeHostX11::SerializeImageRepresentation(
|
| data->push_back(bitmap.getColor(x, y));
|
| }
|
|
|
| +Visual* DesktopWindowTreeHostX11::GetARGBVisual() {
|
| + XVisualInfo visual_template;
|
| + visual_template.screen = 0;
|
| + Visual* to_return = NULL;
|
| +
|
| + int visuals_len;
|
| + XVisualInfo* visual_list = XGetVisualInfo(xdisplay_,
|
| + VisualScreenMask,
|
| + &visual_template, &visuals_len);
|
| + for (int i = 0; i < visuals_len; ++i) {
|
| + // Why support only 8888 ARGB? Because it's all that GTK+ supports. In
|
| + // gdkvisual-x11.cc, they look for this specific visual and use it for all
|
| + // their alpha channel using needs.
|
| + //
|
| + // TODO(erg): While the following does find a valid visual, some GL drivers
|
| + // don't believe that this has an alpha channel. According to marcheu@,
|
| + // this should work on open source driver though. (It doesn't work with
|
| + // NVidia's binaries currently.) http://crbug.com/369209
|
| + if (visual_list[i].depth == 32 &&
|
| + visual_list[i].visual->red_mask == 0xff0000 &&
|
| + visual_list[i].visual->green_mask == 0x00ff00 &&
|
| + visual_list[i].visual->blue_mask == 0x0000ff) {
|
| + to_return = visual_list[i].visual;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (visual_list)
|
| + XFree(visual_list);
|
| +
|
| + return to_return;
|
| +}
|
| +
|
| std::list<XID>& DesktopWindowTreeHostX11::open_windows() {
|
| if (!open_windows_)
|
| open_windows_ = new std::list<XID>();
|
| @@ -1291,6 +1356,12 @@ void DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState show_state) {
|
| window_mapped_ = true;
|
| }
|
|
|
| +void DesktopWindowTreeHostX11::SetWindowTransparency() {
|
| + compositor()->SetHostHasTransparentBackground(use_argb_visual_);
|
| + window()->SetTransparent(use_argb_visual_);
|
| + content_window_->SetTransparent(use_argb_visual_);
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation:
|
|
|
|
|