While we don't provide compositing ourselves, add-on compositors such as
xcompmgr need us to copy the _NET_WM_WINDOW_OPACITY property from the
client window to the frame window.

We can do this easily enough.
---
 src/window.c |  2 ++
 src/wmspec.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/wmspec.h |  1 +
 3 files changed, 45 insertions(+)

diff --git a/src/window.c b/src/window.c
index 3c76d6a..9a6adbd 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1079,6 +1079,8 @@ WWindow *wManageWindow(WScreen *scr, Window window)
        wwin->frame->flags.is_client_window_frame = 1;
        wwin->frame->flags.justification = wPreferences.title_justification;
 
+       wNETWMCheckInitialFrameState(wwin);
+
        /* setup button images */
        wWindowUpdateButtonImages(wwin);
 
diff --git a/src/wmspec.c b/src/wmspec.c
index d6851d7..2e5ec3f 100644
--- a/src/wmspec.c
+++ b/src/wmspec.c
@@ -115,6 +115,7 @@ static Atom net_wm_icon_geometry;   /* FIXME: should work 
together with net_wm_han
 static Atom net_wm_icon;
 static Atom net_wm_pid;                /* TODO */
 static Atom net_wm_handled_icons;      /* FIXME: see net_wm_icon_geometry */
+static Atom net_wm_window_opacity;
 
 static Atom net_frame_extents;
 
@@ -190,6 +191,7 @@ static atomitem_t atomNames[] = {
        {"_NET_WM_ICON", &net_wm_icon},
        {"_NET_WM_PID", &net_wm_pid},
        {"_NET_WM_HANDLED_ICONS", &net_wm_handled_icons},
+       {"_NET_WM_WINDOW_OPACITY", &net_wm_window_opacity},
 
        {"_NET_FRAME_EXTENTS", &net_frame_extents},
 
@@ -292,6 +294,7 @@ static void setSupportedHints(WScreen *scr)
        atom[i++] = net_wm_icon_geometry;
        atom[i++] = net_wm_icon;
        atom[i++] = net_wm_handled_icons;
+       atom[i++] = net_wm_window_opacity;
 
        atom[i++] = net_frame_extents;
 
@@ -472,6 +475,34 @@ static void updateIconImage(WWindow *wwin)
        }
 }
 
+static void updateWindowOpacity(WWindow *wwin)
+{
+       Atom type;
+       int format;
+       unsigned long items, rest;
+       unsigned long *property;
+
+       if (!wwin->frame)
+               return;
+
+       /* We don't care about this ourselves, but other programs need us to 
copy
+        * this to the frame window. */
+       if (XGetWindowProperty(dpy, wwin->client_win, net_wm_window_opacity, 
0L, 1L,
+                               False, XA_CARDINAL, &type, &format, &items, 
&rest,
+                               (unsigned char **)&property) != Success)
+               return;
+
+       if (type == None) {
+               XDeleteProperty(dpy, wwin->frame->core->window, 
net_wm_window_opacity);
+       } else if (type == XA_CARDINAL && format == 32 && items == 1 && 
property) {
+               XChangeProperty(dpy, wwin->frame->core->window, 
net_wm_window_opacity,
+                               XA_CARDINAL, 32, PropModeReplace, (unsigned 
char *)property, 1L);
+       }
+
+       if (property)
+               XFree(property);
+}
+
 static void updateShowDesktop(WScreen *scr, Bool show)
 {
        long foo;
@@ -1300,6 +1331,15 @@ void wNETWMCheckInitialClientState(WWindow *wwin)
        updateIconImage(wwin);
 }
 
+void wNETWMCheckInitialFrameState(WWindow *wwin)
+{
+#ifdef DEBUG_WMSPEC
+       wmessage("wNETWMCheckInitialFrameState");
+#endif
+
+       updateWindowOpacity(wwin);
+}
+
 static void handleDesktopNames(WScreen *scr)
 {
        unsigned long nitems_ret, bytes_after_ret;
@@ -1470,6 +1510,8 @@ void wNETWMCheckClientHintChange(WWindow *wwin, 
XPropertyEvent *event)
                }
        } else if (event->atom == net_wm_icon) {
                updateIconImage(wwin);
+       } else if (event->atom == net_wm_window_opacity) {
+               updateWindowOpacity(wwin);
        }
 }
 
diff --git a/src/wmspec.h b/src/wmspec.h
index 5bb26f0..011a6e9 100644
--- a/src/wmspec.h
+++ b/src/wmspec.h
@@ -33,6 +33,7 @@ void wNETWMCleanup(WScreen *scr);
 void wNETWMUpdateWorkarea(WScreen *scr, WArea usableArea);
 Bool wNETWMGetUsableArea(WScreen *scr, int head, WArea *area);
 void wNETWMCheckInitialClientState(WWindow *wwin);
+void wNETWMCheckInitialFrameState(WWindow *wwin);
 Bool wNETWMProcessClientMessage(XClientMessageEvent *event);
 void wNETWMCheckClientHints(WWindow *wwin, int *layer, int *workspace);
 void wNETWMCheckClientHintChange(WWindow *wwin, XPropertyEvent *event);
-- 
1.9.0.rc3


-- 
To unsubscribe, send mail to [email protected].

Reply via email to