From: Mart Raudsepp Date: Wed, 19 Jul 2006 17:18:12 +0000 (+0000) Subject: Initial wxTLW::(Can)SetTransparent support for wxGTK. The return value of SetTranspar... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/07e497070e5666bf25e0f3616b853399b8b86c48 Initial wxTLW::(Can)SetTransparent support for wxGTK. The return value of SetTransparent is currently very optimistic and doesn't use the EWMH composite manager spec update proposal (_NET_WM_CM_Sn) yet. This is on purpose until the proposal appears in EWMH new version draft and it gets used by more composite managers. See http://www.nabble.com/Interaction-between-applications-and-compositing-managers-t1389248.html and in the future http://standards.freedesktop.org/wm-spec/latest/ for details. Some code reordering is probably in order (helper function to utilsx11?) and testing on non-traditional X servers appreciated. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40192 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/gtk/toplevel.h b/include/wx/gtk/toplevel.h index 304f312de2..de507a0dae 100644 --- a/include/wx/gtk/toplevel.h +++ b/include/wx/gtk/toplevel.h @@ -69,6 +69,9 @@ public: virtual void SetTitle( const wxString &title ); virtual wxString GetTitle() const { return m_title; } + virtual bool SetTransparent(wxByte alpha); + virtual bool CanSetTransparent(); + // Experimental, to allow help windows to be // viewable from within modal dialogs virtual void AddGrab(); diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index a60402b336..508e7d5ee6 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -1300,3 +1300,57 @@ void wxTopLevelWindowGTK::SetWindowStyleFlag( long style ) } #endif // GTK+ 2.2 } + +#include + +/* Get the X Window between child and the root window. + This should usually be the WM managed XID */ +static Window wxGetTopmostWindowX11(Display *dpy, Window child) +{ + Window root, parent; + Window* children; + unsigned int nchildren; + + XQueryTree(dpy, child, &root, &parent, &children, &nchildren); + XFree(children); + + while (parent != root) { + child = parent; + XQueryTree(dpy, child, &root, &parent, &children, &nchildren); + XFree(children); + } + + return child; +} + +bool wxTopLevelWindowGTK::SetTransparent(wxByte alpha) +{ + if (!m_widget || !m_widget->window || !CanSetTransparent()) + return false; + + Display* dpy = GDK_WINDOW_XDISPLAY (m_widget->window); + // We need to get the X Window that has the root window as the immediate parent + // and m_widget->window as a child. This should be the X Window that the WM manages and + // from which the opacity property is checked from. + Window win = wxGetTopmostWindowX11(dpy, GDK_WINDOW_XID (m_widget->window)); + + unsigned int opacity = alpha * 0x1010101; + + // Using pure Xlib to not have a GTK version check mess due to gtk2.0 not having GdkDisplay + if (alpha == 0xff) + XDeleteProperty(dpy, win, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False)); + else + XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False), + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &opacity, 1L); + XSync(dpy, False); + return true; +} + +bool wxTopLevelWindowGTK::CanSetTransparent() +{ + int opcode, event, error; + // Check for the existence of a RGBA visual instead? + return XQueryExtension(gdk_x11_get_default_xdisplay (), + "Composite", &opcode, &event, &error); +}