Index: ui/base/x/x11_util.cc |
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
index f36aa0101cebfc17d925b5d7a2c1fd764f98e6c1..a0d10805b897a078ad6e739ee1dee402832638fd 100644 |
--- a/ui/base/x/x11_util.cc |
+++ b/ui/base/x/x11_util.cc |
@@ -14,6 +14,7 @@ |
#include <list> |
#include <map> |
+#include <mutex> |
#include <utility> |
#include <vector> |
@@ -22,6 +23,7 @@ |
#include <X11/Xcursor/Xcursor.h> |
#include "base/bind.h" |
+#include "base/command_line.h" |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/memory/singleton.h" |
@@ -52,6 +54,7 @@ |
#include "ui/gfx/image/image_skia_rep.h" |
#include "ui/gfx/skia_util.h" |
#include "ui/gfx/x/x11_error_tracker.h" |
+#include "ui/gfx/x/x11_switches.h" |
#if defined(OS_FREEBSD) |
#include <sys/sysctl.h> |
@@ -1409,6 +1412,65 @@ void LogErrorEventDescription(XDisplay* dpy, |
<< " (" << request_str << ")"; |
} |
+static void ChooseARGBVisualForWindowOnce(Visual** visual, int* depth) { |
+ XDisplay* display = gfx::GetXDisplay(); |
+ XAtom NET_WM_CM_S0 = XInternAtom(display, "_NET_WM_CM_S0", False); |
+ |
+ // TODO(cwallez) make the switch be a constant again |
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ "enable-transparent-visuals") && |
+ XGetSelectionOwner(display, NET_WM_CM_S0) != None) { |
+ // Choose the first ARGB8888 visual |
+ XVisualInfo visual_template; |
+ visual_template.screen = 0; |
+ |
+ int visuals_len; |
+ gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( |
+ display, 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 |
+ const XVisualInfo& info = visual_list[i]; |
+ if (info.depth == 32 && info.visual->red_mask == 0xff0000 && |
+ info.visual->green_mask == 0x00ff00 && |
+ info.visual->blue_mask == 0x0000ff) { |
+ *visual = info.visual; |
+ *depth = info.depth; |
+ } |
+ } |
+ } else { |
+ XWindowAttributes windowAttribs; |
+ Window root = XDefaultRootWindow(display); |
+ Status status = XGetWindowAttributes(display, root, &windowAttribs); |
+ DCHECK(status != 0); |
+ *visual = windowAttribs.visual; |
+ *depth = windowAttribs.depth; |
+ } |
+} |
+ |
+void ChooseARGBVisualForWindow(Visual** visual, int* depth) { |
+ static std::once_flag init_flag; |
+ static Visual* s_visual = NULL; |
+ static int s_depth = 0; |
+ |
+ std::call_once(init_flag, ChooseARGBVisualForWindowOnce, &s_visual, &s_depth); |
piman
2015/11/20 01:44:41
std::call_once is a c++11 library feature that is
Julien Isorce Samsung
2015/11/20 09:13:55
Acknowledged.
|
+ |
+ DCHECK(s_visual); |
+ DCHECK(s_depth > 0); |
+ |
+ if (visual) |
+ *visual = s_visual; |
+ if (depth) |
+ *depth = s_depth; |
+} |
+ |
// ---------------------------------------------------------------------------- |
// End of x11_util_internal.h |