Tous les collages #637944 Brut Modifier

Unbenannt

public text v1 · immuable
#637944 ·publié 2007-07-29 11:56 UTC
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