summaryrefslogtreecommitdiffstats
path: root/twin
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-05-05 03:46:01 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-05-05 03:46:01 -0500
commit9804217b51b058fed43a060a746f543da044b2a5 (patch)
treeba646daf2376d2b39d4f6346a0e416f81f69d30f /twin
parent2b6bc47289c47d4c5322ac25b688d0b3027a31d0 (diff)
downloadtdebase-9804217b51b058fed43a060a746f543da044b2a5.tar.gz
tdebase-9804217b51b058fed43a060a746f543da044b2a5.zip
Fix OpenGL screensaver background when ARGB mode is enabled
Diffstat (limited to 'twin')
-rw-r--r--twin/kompmgr/kompmgr.c137
1 files changed, 121 insertions, 16 deletions
diff --git a/twin/kompmgr/kompmgr.c b/twin/kompmgr/kompmgr.c
index 34ebb86e1..55c1bebd1 100644
--- a/twin/kompmgr/kompmgr.c
+++ b/twin/kompmgr/kompmgr.c
@@ -163,6 +163,9 @@ typedef struct _win {
/* setting whether a window will be transparent to the desktop or the windows below it */
Bool show_root_tile;
+
+ /* setting whether a window will be transparent to a black background or something else */
+ Bool show_black_background;
} win;
typedef struct _conv {
@@ -228,6 +231,7 @@ Atom dimAtom;
Atom deskChangeAtom;
Atom winTypeAtom;
Atom winTDETTDAtom;
+Atom winTDETTBAtom;
Atom winType[NUM_WINTYPES];
double winTypeOpacity[NUM_WINTYPES];
Bool winTypeShadow[NUM_WINTYPES];
@@ -1081,6 +1085,12 @@ static char *backgroundProps[] = {
0,
};
+static Bool
+determine_window_transparent_to_black(Display *dpy, Window w);
+
+static Bool
+determine_window_transparent_to_desktop(Display *dpy, Window w);
+
static Picture
root_tile (Display *dpy)
{
@@ -1596,7 +1606,18 @@ paint_all (Display *dpy, XserverRegion region)
background pixmap entirely here is the place to do it; simply
draw the new background onto rootBuffer before continuing! */
if (w->isInFade == False) {
- if (w->show_root_tile == True) {
+ // HACK
+ // For an unknown reason the PropertyNotify event handler is not
+ // fired when either the show_black_background or show_root_tile
+ // control atoms are changed. This works around the problem but
+ // causes an unquantified, likely relatively low, performance loss.
+ w->show_black_background = determine_window_transparent_to_black(dpy, w->id);
+ if (w->show_black_background == True) {
+ XRenderComposite (dpy, PictOpSrc, blackPicture, None, rootBuffer,
+ x, y, x, y,
+ x, y, wid, hei);
+ }
+ else if (w->show_root_tile == True) {
XRenderComposite (dpy, PictOpSrc, rootTile, None, rootBuffer,
x, y, x, y,
x, y, wid, hei);
@@ -1807,8 +1828,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
win *w = find_win (dpy, id);
Drawable back;
- if (!w)
+ if (!w) {
return;
+ }
w->a.map_state = IsViewable;
@@ -1817,6 +1839,8 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
/* This needs to be here since we don't get PropertyNotify when unmapped */
w->opacity = get_opacity_prop (dpy, w, OPAQUE);
+ w->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
+ w->show_black_background = determine_window_transparent_to_black(dpy, id);
determine_mode (dpy, w);
w->windowType = determine_wintype (dpy, w->id, w->id);
@@ -1846,8 +1870,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
#endif
w->a_prev = w->a;
- if (fade && winTypeFade[w->windowType])
+ if (fade && winTypeFade[w->windowType]) {
set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
+ }
}
static void
@@ -2175,6 +2200,28 @@ get_window_transparent_to_desktop(Display * dpy, Window w)
return False;
}
+static Bool
+get_window_transparent_to_black(Display * dpy, Window w)
+{
+ Atom actual;
+ int format;
+ unsigned long n, left;
+
+ unsigned char *data;
+ int result = XGetWindowProperty (dpy, w, winTDETTBAtom, 0L, 1L, False,
+ XA_ATOM, &actual, &format,
+ &n, &left, &data);
+
+ if (result == Success && data != None && format == 32 )
+ {
+ Atom a;
+ a = *(long*)data;
+ XFree ( (void *) data);
+ return True;
+ }
+ return False;
+}
+
static void
determine_mode(Display *dpy, win *w)
{
@@ -2235,8 +2282,9 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
Bool type;
type = get_window_transparent_to_desktop (dpy, w);
- if (type == True)
+ if (type == True) {
return True;
+ }
if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
&nchildren))
@@ -2260,6 +2308,41 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
return False;
}
+static Bool
+determine_window_transparent_to_black (Display *dpy, Window w)
+{
+ Window root_return, parent_return;
+ Window *children = NULL;
+ unsigned int nchildren, i;
+ Bool type;
+
+ type = get_window_transparent_to_black (dpy, w);
+ if (type == True) {
+ return True;
+ }
+
+ if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
+ &nchildren))
+ {
+ /* XQueryTree failed. */
+ if (children)
+ XFree ((void *)children);
+ return False;
+ }
+
+ for (i = 0;i < nchildren;i++)
+ {
+ type = determine_window_transparent_to_black (dpy, children[i]);
+ if (type == True)
+ return True;
+ }
+
+ if (children)
+ XFree ((void *)children);
+
+ return False;
+}
+
static void
add_win (Display *dpy, Window id, Window prev)
{
@@ -2330,6 +2413,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadowSize = 100;
new->decoHash = 0;
new->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
+ new->show_black_background = determine_window_transparent_to_black(dpy, id);
new->windowType = determine_wintype (dpy, new->id, new->id);
if ((new->windowType < 0) || (new->windowType > NUM_WINTYPES)) new->windowType = WINTYPE_NORMAL;
@@ -3400,6 +3484,7 @@ main (int argc, char **argv)
deskChangeAtom = XInternAtom (dpy, DESKCHANGE_PROP, False);
winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False);
winTDETTDAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_DESKTOP", False);
+ winTDETTBAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_BLACK", False);
winType[WINTYPE_DESKTOP] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
winType[WINTYPE_DOCK] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
winType[WINTYPE_TOOLBAR] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
@@ -3464,8 +3549,9 @@ main (int argc, char **argv)
allDamage = None;
clipChanged = True;
XGrabServer (dpy);
- if (autoRedirect)
+ if (autoRedirect) {
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic);
+ }
else
{
int dummy;
@@ -3489,8 +3575,9 @@ main (int argc, char **argv)
XUngrabServer (dpy);
ufd.fd = ConnectionNumber (dpy);
ufd.events = POLLIN;
- if (!autoRedirect)
+ if (!autoRedirect) {
paint_all (dpy, None);
+ }
/* Under no circumstances should these two lines EVER be moved earlier in main() than this point */
atexit(delete_pid_file);
@@ -3500,8 +3587,9 @@ main (int argc, char **argv)
{
/* dump_wins (); */
do {
- if (autoRedirect)
+ if (autoRedirect) {
XFlush (dpy);
+ }
if (!QLength (dpy))
{
if (poll (&ufd, 1, fade_timeout()) == 0)
@@ -3512,8 +3600,9 @@ main (int argc, char **argv)
}
XNextEvent (dpy, &ev);
- if ((ev.type & 0x7f) != KeymapNotify)
+ if ((ev.type & 0x7f) != KeymapNotify) {
discard_ignore (dpy, ev.xany.serial);
+ }
#if DEBUG_EVENTS
printf ("event %10.10s serial 0x%08x window 0x%08x\n",
ev_name(&ev), ev_serial (&ev), ev_window (&ev));
@@ -3711,14 +3800,30 @@ main (int argc, char **argv)
w->extents = win_extents (dpy, w);
}
}
- }
- else if (ev.xproperty.atom == deskChangeAtom)
- {
- /*just set global variable*/
- unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
- printf("desk change, state:%d\n",tmp);
- }
- break;
+ }
+ else if (ev.xproperty.atom == deskChangeAtom)
+ {
+ /*just set global variable*/
+ unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
+ printf("desk change, state:%d\n",tmp);
+ }
+ else if (ev.xproperty.atom == winTDETTDAtom)
+ {
+ win * w = find_win(dpy, ev.xproperty.window);
+ if (w)
+ {
+ w->show_root_tile = determine_window_transparent_to_desktop(dpy, ev.xproperty.window);
+ }
+ }
+ else if (ev.xproperty.atom == winTDETTBAtom)
+ {
+ win * w = find_win(dpy, ev.xproperty.window);
+ if (w)
+ {
+ w->show_black_background = determine_window_transparent_to_black(dpy, ev.xproperty.window);
+ }
+ }
+ break;
default:
if (ev.type == damage_event + XDamageNotify)
{