summaryrefslogtreecommitdiffstats
path: root/kwin
diff options
context:
space:
mode:
Diffstat (limited to 'kwin')
-rw-r--r--kwin/kompmgr/kompmgr.c141
1 files changed, 130 insertions, 11 deletions
diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c
index 53aacc148..1cbae52eb 100644
--- a/kwin/kompmgr/kompmgr.c
+++ b/kwin/kompmgr/kompmgr.c
@@ -122,7 +122,10 @@ typedef struct _win {
unsigned int shadowSize;
Atom windowType;
unsigned long damage_sequence; /* sequence when damage was created */
- Bool shapable; /* this will allow window managers to exclude windows if just the deco is tqshaped*/
+ Bool shapable; /* this will allow window managers to exclude windows if just the deco is shaped*/
+ Bool shaped;
+ XRectangle shape_bounds;
+ XRectangle shape_bounds_prev;
unsigned int decoHash;
Picture dimPicture;
@@ -177,12 +180,13 @@ int xfixes_event, xfixes_error;
int damage_event, damage_error;
int composite_event, composite_error;
int render_event, render_error;
+int xshape_event, xshape_error;
Bool synchronize;
int composite_opcode;
Bool screen_damaged = False;
Bool disable_argb = False;
-int tqshapeEvent;
+int shapeEvent;
/* find these once and be done with it */
Atom opacityAtom;
@@ -1338,6 +1342,7 @@ paint_all (Display *dpy, XserverRegion region)
{
w->borderClip = XFixesCreateRegion (dpy, 0, 0);
XFixesCopyRegion (dpy, w->borderClip, region);
+ XFixesIntersectRegion(dpy, w->borderClip, w->borderClip, w->borderSize);
}
w->prev_trans = t;
t = w;
@@ -1851,10 +1856,10 @@ get_opacity_percent(Display *dpy, win *w, double def)
}
#if 0
static void
-damage_tqshape(Display *dpy, win *w, XRectangle *tqshape_damage)
+damage_shape(Display *dpy, win *w, XRectangle *shape_damage)
{
set_ignore (dpy, NextRequest (dpy));
- XserverRegion region = XFixesCreateRegion (dpy, tqshape_damage, 1);
+ XserverRegion region = XFixesCreateRegion (dpy, shape_damage, 1);
set_ignore (dpy, NextRequest (dpy));
XserverRegion tmpRegion;
add_damage(dpy, region);
@@ -2073,6 +2078,12 @@ add_win (Display *dpy, Window id, Window prev)
free (new);
return;
}
+ new->shaped = False;
+ new->shape_bounds.x = new->a.x;
+ new->shape_bounds.y = new->a.y;
+ new->shape_bounds_prev = new->shape_bounds;
+ new->shape_bounds.width = new->a.width;
+ new->shape_bounds.height = new->a.height;
new->damaged = 0;
#if CAN_DO_USABLE
new->usable = False;
@@ -2090,6 +2101,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->isInFade = False;
new->alphaPict = None;
@@ -2186,6 +2198,8 @@ configure_win (Display *dpy, XConfigureEvent *ce)
if (w->extents != None)
XFixesCopyRegion (dpy, damage, w->extents);
}
+ w->shape_bounds.x -= w->a.x;
+ w->shape_bounds.y -= w->a.y;
w->a.x = ce->x;
w->a.y = ce->y;
if (w->a.width != ce->width || w->a.height != ce->height)
@@ -2220,6 +2234,14 @@ configure_win (Display *dpy, XConfigureEvent *ce)
XFixesDestroyRegion (dpy, extents);
add_damage (dpy, damage);
}
+ w->shape_bounds.x += w->a.x;
+ w->shape_bounds.y += w->a.y;
+ if (!w->shaped)
+ {
+ w->shape_bounds.width = w->a.width;
+ w->shape_bounds.height = w->a.height;
+ }
+
clipChanged = True;
}
@@ -2384,6 +2406,83 @@ 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);
+
+ if (!w)
+ return;
+
+ if (se->kind == ShapeClip || se->kind == ShapeBounding)
+ {
+ XserverRegion region0;
+ XserverRegion region1;
+
+#if 0
+ printf("win 0x%lx %s:%s %ux%u+%d+%d (@%d+%d)\n",
+ (unsigned long) se->window,
+ shape_kind(se->kind),
+ (se->shaped == True) ? "true" : "false",
+ se->width, se->height,
+ se->x, se->y,
+ w->a.x, w->a.y);
+ printf("\told %s %d+%d (@%d+%d)\n",
+ (w->shaped == True) ? "true" : "false",
+ w->shape_bounds_prev.width, w->shape_bounds_prev.height,
+ w->shape_bounds_prev.x, w->shape_bounds_prev.y);
+#endif
+
+ clipChanged = True;
+
+ region0 = XFixesCreateRegion (dpy, &w->shape_bounds_prev, 1);
+
+ if (se->shaped == True)
+ {
+ w->shaped = True;
+ w->shape_bounds.x = w->a.x + se->x;
+ w->shape_bounds.y = w->a.y + se->y;
+ w->shape_bounds.width = se->width;
+ w->shape_bounds.height = se->height;
+ }
+ else
+ {
+ w->shaped = False;
+ w->shape_bounds.x = w->a.x;
+ w->shape_bounds.y = w->a.y;
+ w->shape_bounds.width = w->a.width;
+ w->shape_bounds.height = w->a.height;
+ }
+
+ region1 = XFixesCreateRegion (dpy, &w->shape_bounds, 1);
+ XFixesUnionRegion (dpy, region0, region0, region1);
+ XFixesDestroyRegion (dpy, region1);
+
+ /* ask for repaint of the old and new region */
+ paint_all (dpy, region0);
+ }
+
+ w->shape_bounds_prev = w->shape_bounds;
+}
+
static void
damage_screen (Display *dpy)
{
@@ -2479,8 +2578,13 @@ ev_name (XEvent *ev)
case CirculateNotify:
return "Circulate";
default:
- if (ev->type == damage_event + XDamageNotify)
+ 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;
}
@@ -2501,10 +2605,15 @@ ev_window (XEvent *ev)
case CirculateNotify:
return ev->xcirculate.window;
default:
- if (ev->type == damage_event + XDamageNotify){
- fprintf(stderr, "%d", ev->type);
+ if (ev->type == damage_event + XDamageNotify) {
+// fprintf(stderr, "%d", ev->type);
return ((XDamageNotifyEvent *) ev)->drawable;
}
+ else if (ev->type == xshape_event + ShapeNotify)
+ {
+// fprintf(stderr, "%d", ev->type);
+ return ((XShapeEvent *) ev)->window;
+ }
return 0;
}
}
@@ -2925,6 +3034,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);
+ }
fprintf(stderr, "Started\n");
@@ -3010,8 +3124,9 @@ main (int argc, char **argv)
VisibilityChangeMask);
/*shaping stuff*/
- XShapeQueryExtension(dpy, &tqshapeEvent, &dummy);
+ XShapeQueryExtension(dpy, &shapeEvent, &dummy);
+ 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);
@@ -3255,7 +3370,11 @@ main (int argc, char **argv)
/* printf("damaging win: %u\n",ev.xany.window);*/
damage_win (dpy, (XDamageNotifyEvent *) &ev);
}
- else if (ev.type == tqshapeEvent)
+ if (ev.type == xshape_event + ShapeNotify)
+ {
+ shape_win (dpy, (XShapeEvent *) &ev);
+ }
+ if (ev.type == shapeEvent)
{
win * w = find_win(dpy, ev.xany.window);
#if 1
@@ -3271,7 +3390,7 @@ main (int argc, char **argv)
rect.y = ((XShapeEvent*)&ev)->y;
rect.width = ((XShapeEvent*)&ev)->width;
rect.height = ((XShapeEvent*)&ev)->height;
- damage_tqshape(dpy, w, &rect);
+ damage_shape(dpy, w, &rect);
#endif
#if 0
if (w->shadowSize != 0)
@@ -3286,7 +3405,7 @@ main (int argc, char **argv)
}
#endif
/*this is hardly efficient, but a current workaraound
- shaping support isn't that good so far (e.g. we lack tqshaped shadows)
+ shaping support isn't that good so far (e.g. we lack shaped shadows)
IDEA: use XRender to scale/shift a copy of the window and then blur it*/
#if 1
if (w->picture)