diff --git a/xcompmgr.c b/xcompmgr.c index 5a38cf1..c177a7e 100644 --- a/xcompmgr.c +++ b/xcompmgr.c @@ -43,6 +43,7 @@ #include #include #include +#include #if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2 #define HAS_NAME_WINDOW_PIXMAP 1 @@ -82,6 +83,7 @@ typedef struct _win { unsigned int opacity; Atom windowType; unsigned long damage_sequence; /* sequence when damage was created */ + Bool shaped; /* for drawing translucent windows */ XserverRegion borderClip; @@ -125,6 +127,7 @@ static int xfixes_event, xfixes_error; static int damage_event, damage_error; static int composite_event, composite_error; static int render_event, render_error; +static int xshape_event, xshape_error; static Bool synchronize; static int composite_opcode; @@ -997,7 +1000,7 @@ paint_all (Display *dpy, XserverRegion region) w->borderSize = border_size (dpy, w); if (!w->extents) w->extents = win_extents (dpy, w); - if (w->mode == WINDOW_SOLID) + if (w->mode == WINDOW_SOLID || w->shaped) { int x, y, wid, hei; #if HAS_NAME_WINDOW_PIXMAP @@ -1071,7 +1074,7 @@ paint_all (Display *dpy, XserverRegion region) if (w->opacity != OPAQUE && !w->alphaPict) w->alphaPict = solid_picture (dpy, False, (double) w->opacity / OPAQUE, 0, 0, 0); - if (w->mode == WINDOW_TRANS) + if (w->mode == WINDOW_TRANS && !w->shaped) { int x, y, wid, hei; #if HAS_NAME_WINDOW_PIXMAP @@ -1090,7 +1093,7 @@ paint_all (Display *dpy, XserverRegion region) 0, 0, 0, 0, x, y, wid, hei); } - else if (w->mode == WINDOW_ARGB) + else if (w->mode == WINDOW_ARGB && !w->shaped) { int x, y, wid, hei; #if HAS_NAME_WINDOW_PIXMAP @@ -1458,6 +1461,7 @@ add_win (Display *dpy, Window id, Window prev) { new->damage_sequence = NextRequest (dpy); new->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty); + XShapeSelectInput (dpy, id, ShapeNotifyMask); } new->alphaPict = None; new->shadowPict = None; @@ -1737,6 +1741,54 @@ damage_win (Display *dpy, XDamageNotifyEvent *de) repair_win (dpy, w); } +static const char * +shape_kind(int kind) +{ + static char buf[128]; + + switch(kind){ + case ShapeBounding: + return "ShapeBounding"; + case ShapeClip: + return "ShapeClip"; + case ShapeInput: + return "ShapeInput"; + default: + sprintf (buf, "Shape %d", kind); + return buf; + } +} + +static void +shape_win (Display *dpy, XShapeEvent *se) +{ + win *w = find_win (dpy, se->window); + + printf("win 0x%lx %s:%s %ux%u+%d+%d\n", + (unsigned long) se->window, + shape_kind(se->kind), + (se->shaped == True) ? "true" : "false", + se->width, se->height, + se->x, se->y); + + if (!w) + return; + + if (se->kind == ShapeClip || se->kind == ShapeBounding) + { + clipChanged = True; + + if (se->shaped == True) + { + w->shaped = True; + } else { + w->shaped = False; + } + + paint_all (dpy, 0); + } +} + static int error (Display *dpy, XErrorEvent *ev) { @@ -1814,7 +1866,13 @@ ev_name (XEvent *ev) return "Circulate"; default: if (ev->type == damage_event + XDamageNotify) + { return "Damage"; + } + else if (ev->type == xshape_event + ShapeNotify) + { + return "Shape"; + } sprintf (buf, "Event %d", ev->type); return buf; } @@ -1836,7 +1894,13 @@ ev_window (XEvent *ev) return ev->xcirculate.window; default: if (ev->type == damage_event + XDamageNotify) + { return ((XDamageNotifyEvent *) ev)->drawable; + } + else if (ev->type == xshape_event + ShapeNotify) + { + return ((XShapeEvent *) ev)->window; + } return 0; } } @@ -2005,6 +2069,11 @@ main (int argc, char **argv) fprintf (stderr, "No XFixes extension\n"); exit (1); } + if (!XShapeQueryExtension (dpy, &xshape_event, &xshape_error)) + { + fprintf (stderr, "No XShape extension\n"); + exit (1); + } register_cm(); @@ -2052,6 +2121,8 @@ main (int argc, char **argv) ExposureMask| StructureNotifyMask| PropertyChangeMask); + XShapeSelectInput (dpy, root, ShapeNotifyMask); + 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); @@ -2180,7 +2251,13 @@ main (int argc, char **argv) break; default: if (ev.type == damage_event + XDamageNotify) - damage_win (dpy, (XDamageNotifyEvent *) &ev); + { + damage_win (dpy, (XDamageNotifyEvent *) &ev); + } + else if (ev.type == xshape_event + ShapeNotify) + { + shape_win (dpy, (XShapeEvent *) &ev); + } break; } } while (QLength (dpy));