Index: group.h =================================================================== --- group.h (Revision 1861) +++ group.h (Arbeitskopie) @@ -98,8 +98,8 @@ #define WIN_X(w) (w->attrib.x) #define WIN_Y(w) (w->attrib.y) -#define WIN_WIDTH(w) (w->attrib.width) -#define WIN_HEIGHT(w) (w->attrib.height) +#define WIN_WIDTH(w) (w->width + 2 * w->attrib.border_width) +#define WIN_HEIGHT(w) (w->height + 2 * w->attrib.border_width) #define WIN_BORDER(w) (w->attrib.border_width) #define NUM_OPTIONS(s) (sizeof ( (s)->opt) / sizeof (CompOption)) @@ -231,6 +231,25 @@ } GroupTabBar; /* + * GroupGlow + */ + +typedef struct _GlowQuad { + BoxRec box; + CompMatrix matrix; +} GlowQuad; + +#define GLOWQUAD_TOPLEFT 0 +#define GLOWQUAD_TOPRIGHT 1 +#define GLOWQUAD_BOTTOMLEFT 2 +#define GLOWQUAD_BOTTOMRIGHT 3 +#define GLOWQUAD_TOP 4 +#define GLOWQUAD_BOTTOM 5 +#define GLOWQUAD_LEFT 6 +#define GLOWQUAD_RIGHT 7 +#define NUM_GLOWQUADS 8 + +/* * GroupSelection */ typedef struct _GroupSelection GroupSelection; @@ -334,7 +353,8 @@ int oldX; int oldY; - GLushort oldOpacity; + GlowQuad *glowQuads; + GLushort oldOpacity; // for tab animation Bool animate; @@ -400,6 +420,8 @@ /* * paint.c */ +void groupRecomputeGlow(CompScreen *s); +void groupComputeGlowQuads(CompWindow *w, CompMatrix *matrix); void groupHandleChanges(CompScreen* s); void groupDrawTabAnimation(CompScreen * s); void groupTabBarVertices(CompScreen *s, int x, int y, int width, int height); Index: init.c =================================================================== --- init.c (Revision 1861) +++ init.c (Arbeitskopie) @@ -177,7 +177,6 @@ Bool groupInitWindow(CompPlugin * p, CompWindow * w) { GroupWindow *gw; - GROUP_SCREEN(w->screen); gw = malloc(sizeof(GroupWindow)); @@ -201,9 +200,11 @@ gw->destinationY = 0; //gw->offscreen = FALSE; - w->privates[gs->windowPrivateIndex].ptr = gw; + gw->glowQuads = NULL; + groupComputeGlowQuads (w, &gs->glowTexture.matrix); + return TRUE; } @@ -215,6 +216,9 @@ { GROUP_WINDOW(w); + if (gw->glowQuads) + free (gw->glowQuads); + free(gw); } Index: option.c =================================================================== --- option.c (Revision 1861) +++ option.c (Arbeitskopie) @@ -482,8 +482,11 @@ glowTextureProperties[gs->glowType].textureData, glowTextureProperties[gs->glowType].textureSize, glowTextureProperties[gs->glowType].textureSize); - if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b && gd->groups) + + if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b && gd->groups) { + groupRecomputeGlow (s); damageScreen (s); + } } return TRUE; } @@ -506,14 +509,18 @@ case GROUP_SCREEN_OPTION_GLOW_SIZE: if (compSetIntOption(o, value)) { - if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b && gd->groups) - damageScreen (s); + if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b) { + groupRecomputeGlow (s); + if (gd->groups) + damageScreen (s); + } return TRUE; } break; case GROUP_SCREEN_OPTION_GLOW: if (compSetBoolOption(o, value)) { + groupRecomputeGlow (s); if (gd->groups) damageScreen (s); return TRUE; Index: paint.c =================================================================== --- paint.c (Revision 1861) +++ paint.c (Arbeitskopie) @@ -496,194 +496,209 @@ } } -/* - * groupDrawWindow - * - */ -Bool -groupDrawWindow(CompWindow * w, - const WindowPaintAttrib * attrib, - Region region, unsigned int mask) +void groupRecomputeGlow (CompScreen *s) { - Bool status; - GROUP_WINDOW(w); - GROUP_SCREEN(w->screen); + GROUP_SCREEN(s); + CompWindow *w; - if (!(mask & PAINT_WINDOW_SOLID_MASK) && - gw->inGroup && gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b) { + for (w = s->windows; w; w = w->next) + groupComputeGlowQuads (w, &gs->glowTexture.matrix); +} - if (mask & PAINT_WINDOW_TRANSFORMED_MASK) - region = getInfiniteRegion(); +void +groupComputeGlowQuads (CompWindow *w, CompMatrix *matrix) +{ + GROUP_WINDOW(w); + GROUP_SCREEN(w->screen); - if (region->numRects) { - REGION box; - CompMatrix matrix = gs->glowTexture.matrix;; + BoxRec *box; + CompMatrix *quadMatrix; - box.rects = &box.extents; - box.numRects = 1; + if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b) { + if (!gw->glowQuads) + gw->glowQuads = malloc (NUM_GLOWQUADS * sizeof(GlowQuad)); + if (!gw->glowQuads) + return; + } else { + if (gw->glowQuads) { + free (gw->glowQuads); + gw->glowQuads = NULL; + } + return; + } - w->vCount = 0; + int glowSize = gs->opt[GROUP_SCREEN_OPTION_GLOW_SIZE].value.i; + int glowOffset = (glowSize * glowTextureProperties[gs->glowType].glowOffset / + glowTextureProperties[gs->glowType].textureSize) + 1; - int glowSize = gs->opt[GROUP_SCREEN_OPTION_GLOW_SIZE].value.i; - int glowOffset = (glowSize * glowTextureProperties[gs->glowType].glowOffset / - glowTextureProperties[gs->glowType].textureSize) + 1; + /* Top left corner */ + box = &gw->glowQuads[GLOWQUAD_TOPLEFT].box; + gw->glowQuads[GLOWQUAD_TOPLEFT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_TOPLEFT].matrix; - // Top left - box.extents.x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; - box.extents.y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; - box.extents.x2 = WIN_X(w) - w->input.left + glowOffset; - box.extents.y2 = WIN_Y(w) - w->input.top + glowOffset; + box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; + box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; + box->x2 = MIN(WIN_X(w) - w->input.left + glowOffset, + WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2)); + box->y2 = MIN(WIN_Y(w) - w->input.top + glowOffset, + WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2)); - matrix.xx = 1.0f / glowSize; - matrix.yy = -1.0f / glowSize; - matrix.x0 = -(box.extents.x1 * matrix.xx); - matrix.y0 = 1.0 -(box.extents.y1 * matrix.yy); + quadMatrix->xx = 1.0f / glowSize; + quadMatrix->yy = -1.0f / glowSize; + quadMatrix->x0 = -(box->x1 * quadMatrix->xx); + quadMatrix->y0 = 1.0 -(box->y1 * quadMatrix->yy); - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + /* Top right corner */ + box = &gw->glowQuads[GLOWQUAD_TOPRIGHT].box; + gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix; - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + box->x1 = MAX(WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset, + WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2)); + box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; + box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; + box->y2 = MIN(WIN_Y(w) - w->input.top + glowOffset, + WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2)); - // Top right - box.extents.x1 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; - box.extents.y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; - box.extents.x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; - box.extents.y2 = WIN_Y(w) - w->input.top + glowOffset; + quadMatrix->xx = -1.0f / glowSize; + quadMatrix->yy = -1.0f / glowSize; + quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx); + quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy); - matrix = gs->glowTexture.matrix; - matrix.xx = -1.0f / glowSize; - matrix.yy = -1.0f / glowSize; - matrix.x0 = 1.0 - (box.extents.x1 * matrix.xx); - matrix.y0 = 1.0 - (box.extents.y1 * matrix.yy); + /* Bottom left corner */ + box = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].box; + gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix; - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; + box->y1 = MAX(WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset, + WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2)); + box->x2 = MIN(WIN_X(w) - w->input.left + glowOffset, + WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2)); + box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + quadMatrix->xx = 1.0f / glowSize; + quadMatrix->yy = 1.0f / glowSize; + quadMatrix->x0 = -(box->x1 * quadMatrix->xx); + quadMatrix->y0 = -(box->y1 * quadMatrix->yy); - // Bottom left - box.extents.x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; - box.extents.y1 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; - box.extents.x2 = WIN_X(w) - w->input.left + glowOffset; - box.extents.y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; + /* Bottom right corner */ + box = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].box; + gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix; - matrix.xx = 1.0f / glowSize; - matrix.yy = 1.0f / glowSize; - matrix.x0 = -(box.extents.x1 * matrix.xx); - matrix.y0 = -(box.extents.y1 * matrix.yy); + box->x1 = MAX(WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset, + WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2)); + box->y1 = MAX(WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset, + WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2)); + box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; + box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + quadMatrix->xx = -1.0f / glowSize; + quadMatrix->yy = 1.0f / glowSize; + quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx); + quadMatrix->y0 = -(box->y1 * quadMatrix->yy); - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + /* Top edge */ + box = &gw->glowQuads[GLOWQUAD_TOP].box; + gw->glowQuads[GLOWQUAD_TOP].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_TOP].matrix; - // Bottom right - box.extents.x1 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; - box.extents.y1 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; - box.extents.x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; - box.extents.y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; + box->x1 = WIN_X(w) - w->input.left + glowOffset; + box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; + box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; + box->y2 = WIN_Y(w) - w->input.top + glowOffset; - matrix = gs->glowTexture.matrix; - matrix.xx = -1.0f / glowSize; - matrix.yy = 1.0f / glowSize; - matrix.x0 = 1.0 - (box.extents.x1 * matrix.xx); - matrix.y0 = -(box.extents.y1 * matrix.yy); + quadMatrix->xx = 0.0f; + quadMatrix->yy = -1.0f / glowSize; + quadMatrix->x0 = 1.0; + quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy); - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + /* Bottom edge */ + box = &gw->glowQuads[GLOWQUAD_BOTTOM].box; + gw->glowQuads[GLOWQUAD_BOTTOM].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOM].matrix; - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + box->x1 = WIN_X(w) - w->input.left + glowOffset; + box->y1 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; + box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; + box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; - // top - box.extents.x1 = WIN_X(w) - w->input.left + glowOffset; - box.extents.y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset; - box.extents.x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; - box.extents.y2 = WIN_Y(w) - w->input.top + glowOffset; + quadMatrix->xx = 0.0f; + quadMatrix->yy = 1.0f / glowSize; + quadMatrix->x0 = 1.0; + quadMatrix->y0 = -(box->y1 * quadMatrix->yy); - matrix = gs->glowTexture.matrix; - matrix.xx = 0.0f; - matrix.yy = -1.0f / glowSize; - matrix.x0 = 1.0; - matrix.y0 = 1.0 - (box.extents.y1 * matrix.yy); + /* Left edge */ + box = &gw->glowQuads[GLOWQUAD_LEFT].box; + gw->glowQuads[GLOWQUAD_LEFT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_LEFT].matrix; - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; + box->y1 = WIN_Y(w) - w->input.top + glowOffset; + box->x2 = WIN_X(w) - w->input.left + glowOffset; + box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + quadMatrix->xx = 1.0f / glowSize; + quadMatrix->yy = 0.0f; + quadMatrix->x0 = -(box->x1 * quadMatrix->xx); + quadMatrix->y0 = 0.0; - // bottom - box.extents.x1 = WIN_X(w) - w->input.left + glowOffset; - box.extents.y1 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; - box.extents.x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; - box.extents.y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset; + /* Right edge */ + box = &gw->glowQuads[GLOWQUAD_RIGHT].box; + gw->glowQuads[GLOWQUAD_RIGHT].matrix = *matrix; + quadMatrix = &gw->glowQuads[GLOWQUAD_RIGHT].matrix; - matrix = gs->glowTexture.matrix; - matrix.xx = 0.0f; - matrix.yy = 1.0f / glowSize; - matrix.x0 = 1.0; - matrix.y0 = -(box.extents.y1 * matrix.yy); + box->x1 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; + box->y1 = WIN_Y(w) - w->input.top + glowOffset; + box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; + box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + quadMatrix->xx = -1.0f / glowSize; + quadMatrix->yy = 0.0f; + quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx); + quadMatrix->y0 = 0.0; +} - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); +/* + * groupDrawWindow + * + */ +Bool +groupDrawWindow(CompWindow * w, + const WindowPaintAttrib * attrib, + Region region, unsigned int mask) +{ + Bool status; + GROUP_WINDOW(w); + GROUP_SCREEN(w->screen); - // left - box.extents.x1 = WIN_X(w) - w->input.left - glowSize + glowOffset; - box.extents.y1 = WIN_Y(w) - w->input.top + glowOffset; - box.extents.x2 = WIN_X(w) - w->input.left + glowOffset; - box.extents.y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; + if (!(mask & PAINT_WINDOW_SOLID_MASK) && gw->inGroup && gw->glowQuads) { - matrix.xx = 1.0f / glowSize; - matrix.yy = 0.0f; - matrix.x0 = -(box.extents.x1 * matrix.xx); - matrix.y0 = 0.0; + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + region = getInfiniteRegion(); - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); - } + if (region->numRects) { + REGION box; + int i; - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); + box.rects = &box.extents; + box.numRects = 1; - // right - box.extents.x1 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset; - box.extents.y1 = WIN_Y(w) - w->input.top + glowOffset; - box.extents.x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset; - box.extents.y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset; + w->vCount = 0; - matrix.xx = -1.0f / glowSize; - matrix.yy = 0.0f; - matrix.x0 = 1.0 - (box.extents.x1 * matrix.xx); - matrix.y0 = 0.0; + for (i = 0; i < NUM_GLOWQUADS; i++) { + box.extents = gw->glowQuads[i].box; - if (box.extents.x1 < box.extents.x2 && - box.extents.y1 < box.extents.y2) { - (*w->screen->addWindowGeometry) (w, &matrix, 1, &box, region); + if (box.extents.x1 < box.extents.x2 && + box.extents.y1 < box.extents.y2) { + (*w->screen->addWindowGeometry) (w, + &gw->glowQuads[i].matrix, 1, &box, region); + } + + if (attrib->opacity != gw->oldOpacity) + damageScreenRegion (w->screen, &box); } - - if (attrib->opacity != gw->oldOpacity) - damageScreenRegion (w->screen, &box); - gw->oldOpacity = attrib->opacity; if (w->vCount) { Index: group.c =================================================================== --- group.c (Revision 1861) +++ group.c (Arbeitskopie) @@ -1004,6 +1004,9 @@ (*w->screen->windowResizeNotify) (w); WRAP(gs, w->screen, windowResizeNotify, groupWindowResizeNotify); + if (gw->glowQuads) + groupComputeGlowQuads (w, &gs->glowTexture.matrix); + if (gw->inGroup && !gd->ignoreMode && !gs->queued && gs->opt[GROUP_SCREEN_OPTION_RESIZE].value.b) { int rw = WIN_WIDTH(w) - gw->oldWidth; @@ -1069,6 +1072,8 @@ WRAP(gs, w->screen, windowMoveNotify, groupWindowMoveNotify); groupUpdatePosBuffer(w, WIN_X(w) + dx, WIN_Y(w) + dy, WIN_WIDTH(w), WIN_HEIGHT(w)); + if (gw->glowQuads) + groupComputeGlowQuads (w, &gs->glowTexture.matrix); if(gs->queued) {