XserverRegion allDamage;
int root_height, root_width;
-#define WINDOW_PLAIN 0
-#define WINDOW_DROP 1
-#define WINDOW_TRANS 2
+#define BACKGROUND_PROP "_XROOTPMAP_ID"
+
+#define WINDOW_SOLID 0
+#define WINDOW_TRANS 1
+#define WINDOW_ARGB 2
+
#define TRANS_OPACITY 0.75
#define SHADOW_RADIUS 15
#define SHADOW_OPACITY 0.75
Bool fill;
XRenderPictureAttributes pa;
- if (XGetWindowProperty (dpy, root, XInternAtom (dpy, "_XROOTPMAP_ID", False),
+ if (XGetWindowProperty (dpy, root, XInternAtom (dpy, BACKGROUND_PROP, False),
0, 4, False, AnyPropertyType,
&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success &&
actual_type == XInternAtom (dpy, "PIXMAP", False) && actual_format == 32 && nitems == 1)
{
XRectangle r;
- if (!w->shadow)
+ if (w->mode == WINDOW_ARGB)
{
- double opacity = SHADOW_OPACITY;
- if (w->mode == WINDOW_TRANS)
- opacity = opacity * TRANS_OPACITY;
- w->shadow = shadow_picture (dpy, opacity, SHADOW_RADIUS,
- w->a.width, w->a.height,
- &w->shadow_width, &w->shadow_height);
- w->shadow_dx = SHADOW_OFFSET_X;
- w->shadow_dy = SHADOW_OFFSET_Y;
+ r.x = w->a.x;
+ r.y = w->a.y;
+ r.width = w->a.width + w->a.border_width * 2;
+ r.height = w->a.height + w->a.border_width * 2;
+ }
+ else
+ {
+ if (!w->shadow)
+ {
+ double opacity = SHADOW_OPACITY;
+ if (w->mode == WINDOW_TRANS)
+ opacity = opacity * TRANS_OPACITY;
+ w->shadow = shadow_picture (dpy, opacity, SHADOW_RADIUS,
+ w->a.width, w->a.height,
+ &w->shadow_width, &w->shadow_height);
+ w->shadow_dx = SHADOW_OFFSET_X;
+ w->shadow_dy = SHADOW_OFFSET_Y;
+ }
+ r.x = w->a.x + w->a.border_width + w->shadow_dx;
+ r.y = w->a.y + w->a.border_width + w->shadow_dy;
+ r.width = w->shadow_width;
+ r.height = w->shadow_height;
}
- r.x = w->a.x + w->a.border_width + w->shadow_dx;
- r.y = w->a.y + w->a.border_width + w->shadow_dy;
- r.width = w->shadow_width;
- r.height = w->shadow_height;
return XFixesCreateRegion (dpy, &r, 1);
}
if (w->extents)
XFixesDestroyRegion (dpy, w->extents);
w->extents = win_extents (dpy, w);
- if (w->mode != WINDOW_TRANS)
+ if (w->mode == WINDOW_SOLID)
{
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
XFixesSubtractRegion (dpy, region, region, 0, 0, w->borderSize, 0, 0);
w->a.y + w->a.border_width,
w->a.width,
w->a.height);
+ else if (w->mode == WINDOW_ARGB)
+ XRenderComposite (dpy, PictOpOver, w->picture, None, rootBuffer,
+ 0, 0, 0, 0,
+ w->a.x + w->a.border_width,
+ w->a.y + w->a.border_width,
+ w->a.width,
+ w->a.height);
XFixesDestroyRegion (dpy, w->borderClip);
w->borderClip = None;
}
void
add_win (Display *dpy, Window id, Window prev)
{
- win *new = malloc (sizeof (win));
- win **p;
- XWindowAttributes a;
- XRenderPictureAttributes pa;
+ win *new = malloc (sizeof (win));
+ win **p;
+ XWindowAttributes a;
+ XRenderPictureAttributes pa;
+ XRenderPictFormat *format;
if (!new)
return;
new->damage = None;
pa.subwindow_mode = IncludeInferiors;
if (new->a.class == InputOnly)
+ {
new->picture = 0;
+ format = 0;
+ }
else
{
+ format = XRenderFindVisualFormat (dpy, new->a.visual);
new->picture = XRenderCreatePicture (dpy, id,
- XRenderFindVisualFormat (dpy,
- new->a.visual),
+ format,
CPSubwindowMode,
&pa);
}
new->shadow = None;
new->borderSize = None;
new->extents = None;
- if (new->a.override_redirect)
+ if (format && format->type == PictTypeDirect && format->direct.alphaMask)
+ new->mode = WINDOW_ARGB;
+ else if (new->a.override_redirect)
new->mode = WINDOW_TRANS;
else
- new->mode = WINDOW_DROP;
+ new->mode = WINDOW_SOLID;
new->next = *p;
*p = new;
if (new->a.map_state == IsViewable)
add_damage (dpy, region);
}
+int
+time_in_millis ()
+{
+ struct timeval tp;
+
+ gettimeofday (&tp, 0);
+ return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+
+#define INTERVAL 30
+
main ()
{
XEvent ev;
int n_expose = 0;
struct pollfd ufd;
int n;
+ int last_update;
+ int now;
+ int timeout;
dpy = XOpenDisplay (0);
if (!dpy)
allDamage = None;
XGrabServer (dpy);
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
- paint_all (dpy, None);
- XSelectInput (dpy, root, SubstructureNotifyMask|ExposureMask|StructureNotifyMask);
+ XSelectInput (dpy, root,
+ SubstructureNotifyMask|
+ ExposureMask|
+ StructureNotifyMask|
+ PropertyChangeMask);
XQueryTree (dpy, root, &root_return, &parent_return, &children, &nchildren);
for (i = 0; i < nchildren; i++)
add_win (dpy, children[i], i ? children[i-1] : None);
XFree (children);
XUngrabServer (dpy);
+ paint_all (dpy, None);
+ last_update = time_in_millis ();
for (;;)
{
/* dump_wins (); */
}
}
break;
+ case PropertyNotify:
+ if (ev.xproperty.atom == XInternAtom (dpy, BACKGROUND_PROP, False))
+ {
+ if (rootTile)
+ {
+ XClearArea (dpy, root, 0, 0, 0, 0, True);
+ XRenderFreePicture (dpy, rootTile);
+ rootTile = None;
+ }
+ }
+ break;
default:
if (ev.type == damage_event + XDamageNotify)
damage_win (dpy, (XDamageNotifyEvent *) &ev);
break;
}
} while (XEventsQueued (dpy, QueuedAfterReading));
- ufd.fd = ConnectionNumber (dpy);
- ufd.events = POLLIN;
- n = poll (&ufd, 1, 30);
- if (n > 0 && (ufd.revents & POLLIN) && XEventsQueued (dpy, QueuedAfterReading))
- continue;
+ now = time_in_millis ();
+ timeout = INTERVAL - (now - last_update);
+ if (timeout > 0)
+ {
+ ufd.fd = ConnectionNumber (dpy);
+ ufd.events = POLLIN;
+ n = poll (&ufd, 1, timeout);
+ if (n > 0 && (ufd.revents & POLLIN) && XEventsQueued (dpy, QueuedAfterReading))
+ continue;
+ }
+ last_update = time_in_millis();
if (allDamage)
{
paint_all (dpy, allDamage);