This patch adds support for the _NET_FRAME_EXTENTS property as described in the EWMH spec. With it I was able to use the compton compositing manager to draw fully opaque windows with semi-transparent titlebars and resizebars.

I didn't really know what to name the function which does the actual work so I won't object if it gets changed.
>From 0982a3486852f1dac330c48887da5ac86fb76973 Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Wed, 4 Jul 2012 08:31:39 +0100
Subject: [PATCH] Support _NET_FRAME_EXTENTS.

Set the _NET_FRAME_EXTENTS property based on border widths and
titlebar/resizebar heights.

The EWMH spec says:

"_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32

The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of the
window's frame.  left, right, top and bottom are widths of the
respective borders added by the Window Manager."
---
 src/window.c |    3 +++
 src/wmspec.c |   29 +++++++++++++++++++++++++++++
 src/wmspec.h |    1 +
 3 files changed, 33 insertions(+)

diff --git a/src/window.c b/src/window.c
index d6c697e..4de0aac 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2039,6 +2039,9 @@ void wWindowConfigure(WWindow *wwin, int req_x, int 
req_y, int req_width, int re
 
        if (synth_notify)
                wWindowSynthConfigureNotify(wwin);
+
+       wNETFrameExtents(wwin);
+
        XFlush(dpy);
 }
 
diff --git a/src/wmspec.c b/src/wmspec.c
index ae870ea..ad0624d 100644
--- a/src/wmspec.c
+++ b/src/wmspec.c
@@ -120,6 +120,8 @@ 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_frame_extents;
+
 /* Window Manager Protocols */
 static Atom net_wm_ping;       /* TODO */
 
@@ -193,6 +195,8 @@ static atomitem_t atomNames[] = {
        {"_NET_WM_PID", &net_wm_pid},
        {"_NET_WM_HANDLED_ICONS", &net_wm_handled_icons},
 
+       {"_NET_FRAME_EXTENTS", &net_frame_extents},
+
        {"_NET_WM_PING", &net_wm_ping},
 
        {"UTF8_STRING", &utf8_string},
@@ -294,6 +298,8 @@ static void setSupportedHints(WScreen * scr)
        atom[i++] = net_wm_icon;
        atom[i++] = net_wm_handled_icons;
 
+       atom[i++] = net_frame_extents;
+
        atom[i++] = net_wm_name;
        atom[i++] = net_wm_icon_name;
 
@@ -1605,3 +1611,26 @@ static void wsobserver(void *self, WMNotification * 
notif)
                updateWorkspaceNames(scr);
        }
 }
+
+void wNETFrameExtents(WWindow *wwin)
+{
+       long extents[4] = { 0, 0, 0, 0 };
+
+       /* The extents array describes dimensions which are not
+        * part of the client window.  In our case that means
+        * widths of the border and heights of the titlebar and resizebar.
+        *
+        * Index 0 = left
+        *       1 = right
+        *       2 = top
+        *       3 = bottom
+        */
+       if (!wwin->client_flags.no_border)
+               extents[0] = extents[1] = FRAME_BORDER_WIDTH;
+       if (wwin->frame->titlebar)
+               extents[2] = wwin->frame->titlebar->height;
+       if (wwin->frame->resizebar)
+               extents[3] = wwin->frame->resizebar->height;
+
+       XChangeProperty(dpy, wwin->client_win, net_frame_extents, XA_CARDINAL, 
32, PropModeReplace, (unsigned char *) extents, 4);
+}
diff --git a/src/wmspec.h b/src/wmspec.h
index 71f8ee0..47c4c76 100644
--- a/src/wmspec.h
+++ b/src/wmspec.h
@@ -44,4 +44,5 @@ int wNETWMGetPidForWindow(Window window);
 int wNETWMGetCurrentDesktopFromHint(WScreen *scr);
 char *wNETWMGetIconName(Window window);
 char *wNETWMGetWindowName(Window window);
+void wNETFrameExtents(WWindow *wwin);
 #endif
-- 
1.7.10.2

Reply via email to