corps du collage affichéFrom cec902a3c7ca63b64b0af56bb35e2ca0a776d242 Mon Sep 17 00:00:00 2001
From: Danny Baumann <dannybaumann@web.de>
Date: Sun, 29 Jul 2007 14:51:39 +0200
Subject: [PATCH] Restructure grouped resize.
Instead of immediately applying each window size change, listen to the resize plugin's change notification and draw the windows stretched until ungrab.
---
group-internal.h | 10 +++
group.c | 213 +++++++++++++++++++++++++++++++++++++++++++++---------
init.c | 11 +++-
paint.c | 45 ++++++++++--
4 files changed, 237 insertions(+), 42 deletions(-)
diff --git a/group-internal.h b/group-internal.h
index 8900132..ca77661 100644
--- a/group-internal.h
+++ b/group-internal.h
@@ -358,6 +358,11 @@ typedef struct _GroupWindowHideInfo {
int inputRectOrdering;
} GroupWindowHideInfo;
+typedef struct _GroupResizeInfo {
+ CompWindow *resizedWindow;
+ XRectangle origGeometry;
+} GroupResizeInfo;
+
/*
* GroupDisplay structure
*/
@@ -368,11 +373,14 @@ typedef struct _GroupDisplay {
Bool ignoreMode;
+ GroupResizeInfo *resizeInfo;
+
GlowTextureProperties *glowTextureProperties;
GroupSelection *lastRestackedGroup;
Atom groupWinPropertyAtom;
+ Atom resizeNotifyAtom;
} GroupDisplay;
/*
@@ -447,6 +455,8 @@ typedef struct _GroupWindow {
GroupWindowState windowState;
GroupWindowHideInfo *windowHideInfo;
+ XRectangle *resizeGeometry;
+
/* For tab animation */
Bool ungroup;
int animateState;
diff --git a/group.c b/group.c
index 2525f86..512889f 100644
--- a/group.c
+++ b/group.c
@@ -184,6 +184,65 @@ groupUpdateWindowProperty (CompWindow *w)
}
}
+static unsigned int
+groupUpdateResizeRectangle (CompWindow *w,
+ XRectangle *masterGeometry)
+{
+ XRectangle newGeometry;
+ unsigned int mask = 0;
+ int newWidth, newHeight;
+
+ GROUP_WINDOW (w);
+ GROUP_DISPLAY (w->screen->display);
+
+ if (!gw->resizeGeometry || !gd->resizeInfo)
+ return 0;
+
+ newGeometry.x = WIN_X (w) + (masterGeometry->x -
+ gd->resizeInfo->origGeometry.x);
+ newGeometry.y = WIN_Y (w) + (masterGeometry->y -
+ gd->resizeInfo->origGeometry.y);
+ newGeometry.width = WIN_WIDTH (w) + (masterGeometry->width -
+ gd->resizeInfo->origGeometry.width);
+ newGeometry.height = WIN_HEIGHT (w) + (masterGeometry->height -
+ gd->resizeInfo->origGeometry.height);
+
+ constrainNewWindowSize (w,
+ newGeometry.width, newGeometry.height,
+ &newWidth, &newHeight);
+
+ if (constrainNewWindowSize (w,
+ newGeometry.width, newGeometry.height,
+ &newWidth, &newHeight))
+ {
+ newGeometry.width = newWidth;
+ newGeometry.height = newHeight;
+ }
+
+ if (newGeometry.x != gw->resizeGeometry->x)
+ {
+ gw->resizeGeometry->x = newGeometry.x;
+ mask |= CWX;
+ }
+ if (newGeometry.y != gw->resizeGeometry->y)
+ {
+ gw->resizeGeometry->y = newGeometry.y;
+ mask |= CWY;
+ }
+ if (newGeometry.width != gw->resizeGeometry->width)
+ {
+ gw->resizeGeometry->width = newGeometry.width;
+ mask |= CWWidth;
+ }
+ if (newGeometry.height != gw->resizeGeometry->height)
+ {
+ gw->resizeGeometry->height = newGeometry.height;
+ mask |= CWHeight;
+ }
+
+ return mask;
+}
+
/*
* groupGrabScreen
*
@@ -1398,7 +1457,42 @@ groupHandleEvent (CompDisplay *d,
}
case ClientMessage:
- if (event->xclient.message_type == d->winActiveAtom)
+ if (event->xclient.message_type == gd->resizeNotifyAtom)
+ {
+ CompWindow *w;
+ w = findWindowAtDisplay (d, event->xclient.window);
+
+ if (w && gd->resizeInfo && (w == gd->resizeInfo->resizedWindow))
+ {
+ GROUP_WINDOW (w);
+ GROUP_SCREEN (w->screen);
+
+ if (gw->group)
+ {
+ int i;
+ XRectangle rect;
+
+ rect.x = event->xclient.data.l[0];
+ rect.y = event->xclient.data.l[1];
+ rect.width = event->xclient.data.l[2];
+ rect.height = event->xclient.data.l[3];
+
+ for (i = 0; i < gw->group->nWins; i++)
+ {
+ CompWindow *cw = gw->group->windows[i];
+ GroupWindow *gcw;
+
+ gcw = GET_GROUP_WINDOW (cw, gs);
+ if (gcw->resizeGeometry)
+ {
+ if (groupUpdateResizeRectangle (cw, &rect))
+ addWindowDamage (cw);
+ }
+ }
+ }
+ }
+ }
+ else if (event->xclient.message_type == d->winActiveAtom)
{
CompWindow *w;
w = findWindowAtDisplay (d, event->xclient.window);
@@ -1645,40 +1739,12 @@ groupWindowResizeNotify (CompWindow *w,
maximizeWindow (cw, w->state & MAXIMIZE_STATE);
}
}
- else if ((gw->group->grabWindow == w->id) &&
- groupGetResizeAll (w->screen))
- {
- int i;
- for (i = 0; i < gw->group->nWins; i++)
- {
- CompWindow *cw = gw->group->windows[i];
- int nx, ny, nwidth, nheight;
- XWindowChanges xwc;
- if (!cw)
- continue;
-
- if (cw->state & MAXIMIZE_STATE)
- continue;
-
- if (cw->id == w->id)
- continue;
-
- nx = cw->serverX + dx;
- ny = cw->serverY + dy;
-
- nwidth = cw->serverWidth + dwidth;
- nheight = cw->serverHeight + dheight;
-
- constrainNewWindowSize (cw, nwidth, nheight, &nwidth, &nheight);
-
- xwc.x = nx;
- xwc.y = ny;
- xwc.width = nwidth;
- xwc.height = nheight;
+ }
- configureXWindow (cw, CWX | CWY | CWWidth | CWHeight, &xwc);
- }
- }
+ if (gw->resizeGeometry)
+ {
+ free (gw->resizeGeometry);
+ gw->resizeGeometry = NULL;
}
UNWRAP (gs, w->screen, windowResizeNotify);
@@ -1806,6 +1872,10 @@ groupWindowGrabNotify(CompWindow *w,
if (gw->group && !gd->ignoreMode && !gs->queued)
{
+ Bool doResizeAll;
+ doResizeAll = groupGetResizeAll (w->screen) &&
+ (mask & CompWindowGrabResizeMask);
+
if (gw->group->tabBar)
groupTabSetVisibility (gw->group, FALSE, 0);
else
@@ -1818,7 +1888,39 @@ groupWindowGrabNotify(CompWindow *w,
continue;
if (cw->id != w->id)
+ {
+ GroupWindow *gcw = GET_GROUP_WINDOW (cw, gs);
+
groupEnqueueGrabNotify (cw, x, y, state, mask);
+
+ if (doResizeAll && !(cw->state & MAXIMIZE_STATE))
+ {
+ if (!gcw->resizeGeometry)
+ gcw->resizeGeometry = malloc (sizeof (XRectangle));
+ if (gcw->resizeGeometry)
+ {
+ gcw->resizeGeometry->x = WIN_X (cw);
+ gcw->resizeGeometry->y = WIN_Y (cw);
+ gcw->resizeGeometry->width = WIN_WIDTH (cw);
+ gcw->resizeGeometry->height = WIN_HEIGHT (cw);
+ }
+ }
+ }
+ }
+ }
+
+ if (doResizeAll)
+ {
+ if (!gd->resizeInfo)
+ gd->resizeInfo = malloc (sizeof (GroupResizeInfo));
+
+ if (gd->resizeInfo)
+ {
+ gd->resizeInfo->resizedWindow = w;
+ gd->resizeInfo->origGeometry.x = WIN_X (w);
+ gd->resizeInfo->origGeometry.y = WIN_Y (w);
+ gd->resizeInfo->origGeometry.width = WIN_WIDTH (w);
+ gd->resizeInfo->origGeometry.height = WIN_HEIGHT (w);
}
}
@@ -1842,10 +1944,19 @@ groupWindowUngrabNotify (CompWindow *w)
{
if (!gw->group->tabBar)
{
- int i;
+ int i;
+ XRectangle rect;
groupDequeueMoveNotifies (w->screen);
+ if (gd->resizeInfo)
+ {
+ rect.x = WIN_X (w);
+ rect.y = WIN_Y (w);
+ rect.width = WIN_WIDTH (w);
+ rect.height = WIN_HEIGHT (w);
+ }
+
for (i = 0; i < gw->group->nWins; i++)
{
CompWindow *cw = gw->group->windows[i];
@@ -1856,6 +1967,32 @@ groupWindowUngrabNotify (CompWindow *w)
{
GROUP_WINDOW (cw);
+ if (gw->resizeGeometry)
+ {
+ unsigned int mask;
+
+ gw->resizeGeometry->x = WIN_X (cw);
+ gw->resizeGeometry->y = WIN_Y (cw);
+ gw->resizeGeometry->width = WIN_WIDTH (cw);
+ gw->resizeGeometry->height = WIN_HEIGHT (cw);
+
+ mask = groupUpdateResizeRectangle (cw, &rect);
+ if (mask)
+ {
+ XWindowChanges xwc;
+ xwc.x = gw->resizeGeometry->x;
+ xwc.y = gw->resizeGeometry->y;
+ xwc.width = gw->resizeGeometry->width;
+ xwc.height = gw->resizeGeometry->height;
+
+ configureXWindow (cw, mask, &xwc);
+ }
+ else
+ {
+ free (gw->resizeGeometry);
+ gw->resizeGeometry = NULL;
+ }
+ }
if (gw->needsPosSync)
{
syncWindowPosition (cw);
@@ -1866,6 +2003,12 @@ groupWindowUngrabNotify (CompWindow *w)
}
}
+ if (gd->resizeInfo)
+ {
+ free (gd->resizeInfo);
+ gd->resizeInfo = NULL;
+ }
+
gw->group->grabWindow = None;
gw->group->grabMask = 0;
}
diff --git a/init.c b/init.c
index 90b2185..44999a2 100644
--- a/init.c
+++ b/init.c
@@ -139,10 +139,16 @@ groupInitDisplay (CompPlugin *p,
return FALSE;
}
- gd->glowTextureProperties = (GlowTextureProperties*) glowTextureProperties;
+ gd->glowTextureProperties =
+ (GlowTextureProperties*) glowTextureProperties;
gd->ignoreMode = FALSE;
gd->lastRestackedGroup = NULL;
- gd->groupWinPropertyAtom = XInternAtom (d->display, "_COMPIZ_GROUP", 0);
+ gd->resizeInfo = NULL;
+
+ gd->groupWinPropertyAtom = XInternAtom (d->display,
+ "_COMPIZ_GROUP", 0);
+ gd->resizeNotifyAtom = XInternAtom (d->display,
+ "_COMPIZ_RESIZE_NOTIFY", 0);
WRAP (gd, d, handleEvent, groupHandleEvent);
@@ -384,6 +390,7 @@ static Bool groupInitWindow(CompPlugin * p, CompWindow * w)
gw->destination.y = 0;
gw->windowHideInfo = NULL;
+ gw->resizeGeometry = NULL;
if (w->minimized)
gw->windowState = WindowMinimized;
diff --git a/paint.c b/paint.c
index f29f180..200b4e8 100644
--- a/paint.c
+++ b/paint.c
@@ -983,7 +983,8 @@ groupPaintOutput (CompScreen *s,
GroupSelection *group;
Bool status;
- GROUP_SCREEN(s);
+ GROUP_SCREEN (s);
+ GROUP_DISPLAY (s->display);
gs->painted = FALSE;
gs->vpX = s->x;
@@ -998,8 +999,8 @@ groupPaintOutput (CompScreen *s,
}
}
- if (gs->tabBarVisible)
- mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+ if (gs->tabBarVisible || gd->resizeInfo)
+ mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
UNWRAP (gs, s, paintOutput);
status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
@@ -1452,7 +1453,7 @@ groupPaintWindow (CompWindow *w,
if (gw->windowHideInfo)
mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
- if (gw->inSelection || doRotate || doTabbing || showTabbar)
+ if (gw->inSelection || gw->resizeGeometry || doRotate || doTabbing || showTabbar)
{
WindowPaintAttrib wAttrib = *attrib;
CompTransform wTransform = *transform;
@@ -1506,7 +1507,41 @@ groupPaintWindow (CompWindow *w,
animProgress = 1 - (timeLeft / (2 * animTime));
}
- if (doRotate || doTabbing)
+ if (gw->resizeGeometry)
+ {
+ int xOrigin, yOrigin;
+ float xScale, yScale;
+ float stretchWidth, stretchHeight;
+ int width, height;
+
+ width = w->width + w->input.left + w->input.right;
+ height = w->height + w->input.top + w->input.bottom;
+
+ stretchWidth = gw->resizeGeometry->width +
+ w->serverBorderWidth * 2 +
+ w->input.right + w->input.left;
+ stretchHeight = gw->resizeGeometry->height +
+ w->serverBorderWidth * 2 +
+ w->input.bottom + w->input.top;
+
+ xScale = (width) ? stretchWidth / (float) width : 1.0f;
+ yScale = (height) ? stretchHeight / (float) height : 1.0f;
+
+ xOrigin = w->attrib.x - w->input.left;
+ yOrigin = w->attrib.y - w->input.top;
+
+ matrixTranslate (&wTransform, xOrigin, yOrigin, 0.0f);
+ matrixScale (&wTransform, xScale, yScale, 1.0f);
+ matrixTranslate (&wTransform,
+ (gw->resizeGeometry->x - w->attrib.x) /
+ xScale - xOrigin,
+ (gw->resizeGeometry->y - w->attrib.y) /
+ yScale - yOrigin,
+ 0.0f);
+
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+ }
+ else if (doRotate || doTabbing)
{
float animWidth, animHeight;
float animScaleX, animScaleY;
--
1.5.2.2