The attached patch adds client windows' depth, visual and colormap
to the associated frame window rather than always using the root
window's depth, visual and colormap.
I wrote the patch after reading the FAQ for urxvt, which says,
regarding transparency support:
"3. Use an ARGB visual:
urxvt -depth 32 -fg grey90 -bg rgba:0000/0000/4444/cccc
This requires XFT support, and the support of your X-server. If that
doesn't work for you, blame Xorg and Keith Packard. ARGB visuals
aren't there yet, no matter what they claim. Rxvt-Unicode contains the
necessary bugfixes and workarounds for Xft and Xlib to make it work,
but that doesn't mean that your WM has the required kludges in place."
In conjunction with a compositing manager (I tested compton) it
does work and urxvt draws a semi-transparent background with fully
opaque foreground text and scrollbars; much prettier than applying a
blanket transparency value over the whole window with the compositing
manager. Other application windows I tested were, as expected, drawn
the same as before.
I verified that urxvt is drawn in the same way when using xfwm4
(with builtin compositing). Since Window Maker doesn't (at time of
writing) have its own compositing manager I should clarify that one is
required to see any benefit from this patch.
Whether or not this feature is useful for any application other
than urxvt I don't know, though I assume that an application which
chose an ARGB visual in the same way would be able to draw itself
prettily.
On a display without RENDER things work just as they do without the
patch. I have, however, only been able to test on a fairly standard
TrueColor display supporting multiple colour depths with 24bpp being
the default. Testing with more ... exotic ... display types would
probably be advisable.
>From 2c012ec59498172f26243a26cfc81d319eea5f5c Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Mon, 20 Aug 2012 15:18:21 +0100
Subject: [PATCH] Allow windows to specify their own depth.
Accept windows' depth, visual and colormap instead of always using those
of the root window. Internal windows such as menus behave as before.
In conjunction with a compositing manager on a display supporting the
RENDER extension windows can now manage their own opacity.
---
src/framewin.c | 9 +++++++--
src/framewin.h | 6 +++++-
src/icon.c | 2 +-
src/menu.c | 3 ++-
src/wcore.c | 12 +++++-------
src/wcore.h | 3 ++-
src/window.c | 6 ++++--
7 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/framewin.c b/src/framewin.c
index 2d3c009..448d204 100644
--- a/src/framewin.c
+++ b/src/framewin.c
@@ -62,7 +62,8 @@ WFrameWindow *wFrameWindowCreate(WScreen * scr, int wlevel,
int x, int y,
int width, int height, int *clearance,
int *title_min, int *title_max, int flags,
WTexture ** title_texture, WTexture **
resize_texture,
- WMColor ** color, WMFont ** font)
+ WMColor ** color, WMFont ** font,
+ int depth, Visual *visual, Colormap colormap)
{
WFrameWindow *fwin;
@@ -84,8 +85,12 @@ WFrameWindow *wFrameWindowCreate(WScreen * scr, int wlevel,
int x, int y,
fwin->last_languagemode = XkbGroup2Index;
#endif
+ fwin->depth = depth;
+ fwin->visual = visual;
+ fwin->colormap = colormap;
+
fwin->core = wCoreCreateTopLevel(scr, x, y, width, height, (flags &
WFF_BORDER)
- ? FRAME_BORDER_WIDTH : 0);
+ ? FRAME_BORDER_WIDTH : 0, fwin->depth,
fwin->visual, fwin->colormap);
if (wPreferences.use_saveunders) {
unsigned long vmask;
XSetWindowAttributes attribs;
diff --git a/src/framewin.h b/src/framewin.h
index 24b438c..27e6518 100644
--- a/src/framewin.h
+++ b/src/framewin.h
@@ -147,6 +147,9 @@ typedef struct WFrameWindow {
unsigned int incomplete_title:1;
} flags;
+ int depth;
+ Visual *visual;
+ Colormap colormap;
} WFrameWindow;
@@ -156,7 +159,8 @@ wFrameWindowCreate(WScreen *scr, int wlevel, int x, int y,
int *title_min, int *title_max, int flags,
union WTexture **title_texture,
union WTexture **resize_texture,
- WMColor **color, WMFont **font);
+ WMColor **color, WMFont **font,
+ int depth, Visual *visual, Colormap colormap);
void wFrameWindowUpdateBorders(WFrameWindow *fwin, int flags);
diff --git a/src/icon.c b/src/icon.c
index c479890..d929a8c 100644
--- a/src/icon.c
+++ b/src/icon.c
@@ -187,7 +187,7 @@ static WIcon *wIconCreateCore(WScreen *scr, int coord_x,
int coord_y)
coord_y,
wPreferences.icon_size,
wPreferences.icon_size,
- 0);
+ 0, scr->w_depth, scr->w_visual,
scr->w_colormap);
if (wPreferences.use_saveunders) {
vmask = CWSaveUnder;
diff --git a/src/menu.c b/src/menu.c
index 6231e06..7bb0639 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -164,7 +164,8 @@ WMenu *wMenuCreate(WScreen * screen, char *title, int
main_menu)
&wPreferences.menu_title_max_height,
flags,
screen->menu_title_texture, NULL,
- screen->menu_title_color,
&screen->menu_title_font);
+ screen->menu_title_color,
&screen->menu_title_font,
+ screen->w_depth, screen->w_visual,
screen->w_colormap);
menu->frame->core->descriptor.parent = menu;
menu->frame->core->descriptor.parent_type = WCLASS_MENU;
diff --git a/src/wcore.c b/src/wcore.c
index ac896a5..241ede4 100644
--- a/src/wcore.c
+++ b/src/wcore.c
@@ -46,7 +46,7 @@ extern XContext wWinContext;
* The created window.
*----------------------------------------------------------------------
*/
-WCoreWindow *wCoreCreateTopLevel(WScreen * screen, int x, int y, int width,
int height, int bwidth)
+WCoreWindow *wCoreCreateTopLevel(WScreen * screen, int x, int y, int width,
int height, int bwidth, int depth, Visual *visual, Colormap colormap)
{
WCoreWindow *core;
int vmask;
@@ -67,10 +67,10 @@ WCoreWindow *wCoreCreateTopLevel(WScreen * screen, int x,
int y, int width, int
| ButtonReleaseMask | ButtonMotionMask | ExposureMask |
EnterWindowMask | LeaveWindowMask;
vmask |= CWColormap;
- attribs.colormap = screen->w_colormap;
+ attribs.colormap = colormap;
core->window = XCreateWindow(dpy, screen->root_win, x, y, width, height,
- bwidth, screen->w_depth, CopyFromParent,
screen->w_visual, vmask, &attribs);
+ bwidth, depth, CopyFromParent, visual,
vmask, &attribs);
core->width = width;
core->height = height;
core->screen_ptr = screen;
@@ -115,10 +115,8 @@ WCoreWindow *wCoreCreate(WCoreWindow * parent, int x, int
y, int width, int heig
attribs.background_pixel = parent->screen_ptr->black_pixel;
attribs.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | ButtonMotionMask | ExposureMask |
EnterWindowMask | LeaveWindowMask;
- /*
- vmask |= CWColormap;
- attribs.colormap = parent->screen_ptr->w_colormap;
- */
+ vmask |= CWColormap;
+ attribs.colormap = parent->screen_ptr->w_colormap;
core->window =
XCreateWindow(dpy, parent->window, x, y, width, height, 0,
parent->screen_ptr->w_depth, CopyFromParent,
diff --git a/src/wcore.h b/src/wcore.h
index 8209ba6..3452227 100644
--- a/src/wcore.h
+++ b/src/wcore.h
@@ -43,7 +43,8 @@ typedef struct _WCoreWindow {
WCoreWindow *wCoreCreateTopLevel(WScreen *screen, int x, int y, int width,
- int height, int bwidth);
+ int height, int bwidth,
+ int depth, Visual *visual, Colormap colormap);
WCoreWindow *wCoreCreate(WCoreWindow *parent, int x, int y,
int width, int height);
diff --git a/src/window.c b/src/window.c
index 50962f7..e7b1036 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1094,7 +1094,8 @@ WWindow *wManageWindow(WScreen *scr, Window window)
&wPreferences.window_title_max_height,
foo,
scr->window_title_texture,
- scr->resizebar_texture,
scr->window_title_color, &scr->title_font);
+ scr->resizebar_texture,
scr->window_title_color, &scr->title_font,
+ wattribs.depth, wattribs.visual,
wattribs.colormap);
wwin->frame->flags.is_client_window_frame = 1;
wwin->frame->flags.justification = wPreferences.title_justification;
@@ -1373,7 +1374,8 @@ WWindow *wManageInternalWindow(WScreen *scr, Window
window, Window owner,
&wPreferences.window_title_max_height,
foo,
scr->window_title_texture,
- scr->resizebar_texture,
scr->window_title_color, &scr->title_font);
+ scr->resizebar_texture,
scr->window_title_color, &scr->title_font,
+ scr->w_depth, scr->w_visual,
scr->w_colormap);
XSaveContext(dpy, window, wWinContext, (XPointer) &
wwin->client_descriptor);
--
1.7.10.4