Attatched is a patch to add animation to the maximumization of a window.
The patch also adds structs, init functions and other things in order to
make this possible. It also adds the ability to 'toggle' between a
maximumized state and a non-maximumized state
-- Sam
From fd876af1b29a3a0fbc4207afa1655d57fa7d8e4f Mon Sep 17 00:00:00 2001
From: Sam <[EMAIL PROTECTED]>
Date: Sun, 25 May 2008 00:08:59 +0800
Subject: [PATCH] Add animation to maximumization
---
maximumize.c | 390 ++++++++++++++++++++++++++++++++++++++++++++++++-----
maximumize.xml.in | 9 ++
2 files changed, 366 insertions(+), 33 deletions(-)
diff --git a/maximumize.c b/maximumize.c
index 0f11aa4..30b3251 100644
--- a/maximumize.c
+++ b/maximumize.c
@@ -29,6 +29,65 @@
#include <compiz-core.h>
#include "maximumize_options.h"
+#define GET_MAX_DISPLAY(d) \
+ ((MaximumizeDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
+
+#define MAX_DISPLAY(d) \
+ MaximumizeDisplay *md = GET_MAX_DISPLAY (d)
+
+#define GET_MAX_SCREEN(s, md) \
+ ((MaximumizeScreen *) (s)->base.privates[(md)->screenPrivateIndex].ptr)
+
+#define MAX_SCREEN(s) \
+ MaximumizeScreen *ms = GET_MAX_SCREEN (s, GET_MAX_DISPLAY (s->display))
+
+#define GET_MAX_WINDOW(w, ms) \
+ ((MaximumizeWindow *) (w)->base.privates[(ms)->windowPrivateIndex].ptr)
+
+#define MAX_WINDOW(w) \
+ MaximumizeWindow *mw = GET_MAX_WINDOW (w, \
+ GET_MAX_SCREEN (w->screen, \
+ GET_MAX_DISPLAY (w->screen->display)))
+
+static int displayPrivateIndex;
+
+typedef enum _MaximumizeStage
+{
+ stageZoomOut = 0,
+ stageResize,
+ stageZoomIn,
+ stageNone
+} MaximumizeStage;
+
+typedef struct _MaximumizeDisplay
+{
+ int screenPrivateIndex;
+} MaximumizeDisplay;
+
+
+typedef struct _MaximumizeScreen
+{
+ int windowPrivateIndex;
+ float steps;
+
+ PreparePaintScreenProc preparePaintScreen;
+ PaintWindowProc paintWindow;
+ WindowResizeNotifyProc windowResizeNotify;
+
+} MaximumizeScreen;
+
+typedef struct _MaximumizeWindow
+{
+ MaximumizeStage stage;
+ float scale;
+
+ Bool maximumized;
+ int savedH;
+ int savedW;
+ int savedX;
+ int savedY;
+} MaximumizeWindow;
+
/* Returns true if rectangles a and b intersect by at least 40 in both directions
*/
static Bool
@@ -288,11 +347,168 @@ maximumizeComputeResize(CompWindow *w,
return mask;
}
+static void
+maximumizeResizeWindow (CompWindow *w)
+{
+ if (w)
+ {
+ int width, height;
+ unsigned int mask;
+ XWindowChanges xwc;
+
+ MAX_WINDOW (w);
+
+ mask = maximumizeComputeResize (w, &xwc);
+ if (mask)
+ {
+ if (!mw->maximumized)
+ {
+ if (constrainNewWindowSize (w, xwc.width, xwc.height,
+ &width, &height))
+ {
+ mask |= CWWidth | CWHeight;
+ xwc.width = width;
+ xwc.height = height;
+ mw->savedW = w->attrib.width;
+ mw->savedH = w->attrib.height;
+ mw->savedX = w->attrib.x;
+ mw->savedY = w->attrib.y;
+ }
+ }
+ else
+ {
+ mask |= CWWidth | CWHeight;
+ xwc.width = mw->savedW;
+ xwc.height = mw->savedH;;
+ xwc.x = mw->savedX;
+ xwc.y = mw->savedY;
+ }
+
+ if (w->mapNum && (mask & (CWWidth | CWHeight)))
+ sendSyncRequest (w);
+
+ configureXWindow (w, mask, &xwc);
+
+ }
+
+ mw->stage = stageZoomIn;
+
+ }
+}
+
+/* Wait until compiz tells us that it has resized
+ the window, so that we don't get ugly drawing artifacts
+ when the window 'resizes' when it is zooming in*/
+/*static void
+maximumizeWindowResizeNotify (CompWindow *w,
+ int dx,
+ int dy,
+ int dw,
+ int dh)
+{
+ MAX_WINDOW (w);
+ MAX_SCREEN (w->screen);
+
+ fprintf(stderr, "resizeNotify\n");
+
+ UNWRAP(ms, w->screen, windowResizeNotify);
+ (*w->screen->windowResizeNotify)(w, dx, dy, dw, dh);
+ WRAP(ms, w->screen, windowResizeNotify, maximumizeWindowResizeNotify);
+}*/
+
+/* Animation Prep */
+static void
+maximumizePreparePaintScreen (CompScreen *s,
+ int time)
+{
+ MAX_SCREEN (s);
+
+ float speed = maximumizeGetSpeed (s);
+ ms->steps = (float) time / ((20.1 - speed) * 10);
+
+ if (ms->steps < 0.005)
+ ms->steps = 0.005;
+
+ UNWRAP (ms, s, preparePaintScreen);
+ (*s->preparePaintScreen) (s, time);
+ WRAP (ms, s, preparePaintScreen, maximumizePreparePaintScreen);
+}
+
+static Bool
+maximumizePaintWindow (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform,
+ Region region,
+ unsigned int mask)
+{
+ Bool status;
+ CompScreen *s = w->screen;
+ CompTransform mTransform = *transform;
+
+ MAX_SCREEN (s);
+ MAX_WINDOW (w);
+
+ switch (mw->stage)
+ {
+ case stageZoomOut:
+ {
+ mw->scale += (0.0f - mw->scale) * ms->steps;
+ if (mw->scale < 0.005f)
+ {
+ mw->scale = 0.0f;
+ mw->stage = stageResize;
+ maximumizeResizeWindow (w);
+ }
+ }
+ break;
+ case stageResize:
+ mw->scale = 0.0f; /* Ensure that scale is always 0 when resizing */
+ break;
+ case stageZoomIn:
+ {
+ mw->scale += (1.0f - mw->scale) * ms->steps;
+ if (mw->scale > 0.995f)
+ {
+ mw->scale = 1.0f;
+ mw->stage = stageNone;
+ }
+ }
+ break;
+ case stageNone:
+ {
+ mw->scale = 1.0f;
+ }
+ break;
+ }
+
+ if (mw->scale != 1.0f)
+ {
+
+ matrixTranslate (&mTransform, w->attrib.x + w->attrib.width / 2, w->attrib.y + w->attrib.height / 2, 0);
+ matrixScale (&mTransform, mw->scale, mw->scale, 0);
+ matrixTranslate (&mTransform, -(w->attrib.x + w->attrib.width / 2), -(w->attrib.y + w->attrib.height / 2), 0);
+
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+
+ /* FIXME: should better use DonePaintScreen for that */
+ if (mw->stage != stageNone)
+ addWindowDamage (w);
+
+ }
+
+ UNWRAP (ms, s, paintWindow);
+ status = (*s->paintWindow) (w, attrib, &mTransform, region, mask);
+ WRAP (ms, s, paintWindow, maximumizePaintWindow);
+
+ return status;
+}
+
/*
* Initially triggered keybinding.
* Fetch the window, fetch the resize, constrain it.
*
*/
+
static Bool
maximumizeTrigger(CompDisplay *d,
CompAction *action,
@@ -307,27 +523,14 @@ maximumizeTrigger(CompDisplay *d,
w = findWindowAtDisplay (d, xid);
if (w)
{
- int width, height;
- unsigned int mask;
- XWindowChanges xwc;
-
- mask = maximumizeComputeResize (w, &xwc);
- if (mask)
- {
- if (constrainNewWindowSize (w, xwc.width, xwc.height,
- &width, &height))
- {
- mask |= CWWidth | CWHeight;
- xwc.width = width;
- xwc.height = height;
- }
-
- if (w->mapNum && (mask & (CWWidth | CWHeight)))
- sendSyncRequest (w);
-
- configureXWindow (w, mask, &xwc);
+ MAX_WINDOW (w);
+
+ mw->stage = stageZoomOut;
+ mw->maximumized = !mw->maximumized;
+
+ damageScreen (w->screen);
+
}
- }
return TRUE;
}
@@ -337,23 +540,144 @@ static Bool
maximumizeInitDisplay (CompPlugin *p,
CompDisplay *d)
{
+
+ MaximumizeDisplay *md;
+
+ md = malloc (sizeof(MaximumizeDisplay));
+ if (!md)
+ return FALSE;
+
if (!checkPluginABI ("core", CORE_ABIVERSION))
return FALSE;
-
+
+ md->screenPrivateIndex = allocateScreenPrivateIndex (d);
+ if (md->screenPrivateIndex < 0)
+ {
+ free (md);
+ return FALSE;
+ }
+
maximumizeSetTriggerKeyInitiate (d, maximumizeTrigger);
+
+ d->base.privates[displayPrivateIndex].ptr = md;
+
+ return TRUE;
+}
+
+static Bool
+maximumizeInitScreen (CompPlugin *p,
+ CompScreen *s)
+{
+ MaximumizeScreen *ms;
+
+ MAX_DISPLAY (s->display);
+ ms = malloc (sizeof (MaximumizeScreen));
+ if (!ms)
+ return FALSE;
+
+ ms->windowPrivateIndex = allocateWindowPrivateIndex (s);
+ if (ms->windowPrivateIndex < 0)
+ {
+ free (ms);
+ return FALSE;
+ }
+
+ ms->steps = 0;
+
+ WRAP (ms, s, preparePaintScreen, maximumizePreparePaintScreen);
+ WRAP (ms, s, paintWindow, maximumizePaintWindow);
+ //WRAP (ms, s, damageWindowRect, maximumizeDamageWindowRect);
+ //WRAP(ms, s, windowResizeNotify, maximumizeWindowResizeNotify);
+
+ s->base.privates[md->screenPrivateIndex].ptr = ms;
+
+ return TRUE;
+}
+
+static void
+maximumizeFiniScreen (CompPlugin *p,
+ CompScreen *s)
+{
+ MAX_SCREEN (s);
+
+ UNWRAP (ms, s, preparePaintScreen);
+ UNWRAP (ms, s, paintWindow);
+ //UNWRAP (ms, s, damageWindowRect);
+ //UNWRAP (ms, s, windowResizeNotify);
+
+ freeWindowPrivateIndex (s, ms->windowPrivateIndex);
+
+ free (ms);
+}
+static void
+maximumizeFiniDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ MAX_DISPLAY (d);
+
+ freeScreenPrivateIndex (d, md->screenPrivateIndex);
+
+ free (md);
+}
+
+static Bool
+maximumizeInitWindow (CompPlugin *p,
+ CompWindow *w)
+{
+ MaximumizeWindow *mw;
+
+ MAX_SCREEN (w->screen);
+
+ mw = malloc (sizeof (MaximumizeWindow));
+ if (!mw)
+ return FALSE;
+
+ mw->scale = 1.0f;
+ mw->stage = stageNone;
+ mw->savedW = 0;
+ mw->savedH = 0;
+ mw->savedX = 0;
+ mw->savedY = 0;
+
+ w->base.privates[ms->windowPrivateIndex].ptr = mw;
+
+ return TRUE;
+}
+
+static void
+maximumizeFiniWindow (CompPlugin *p,
+ CompWindow *w)
+{
+ MAX_WINDOW (w);
+
+ free (mw);
+}
+
+static void
+maximumizeFini (CompPlugin *p)
+{
+ freeDisplayPrivateIndex (displayPrivateIndex);
+}
+
+static Bool
+maximumizeInit (CompPlugin *p)
+{
+ displayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (displayPrivateIndex < 0)
+ return FALSE;
return TRUE;
}
static CompBool
maximumizeInitObject (CompPlugin *p,
- CompObject *o)
+ CompObject *o)
{
static InitPluginObjectProc dispTab[] = {
- (InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) maximumizeInitDisplay,
- 0,
- 0
+ (InitPluginObjectProc) 0, /* InitCore */
+ (InitPluginObjectProc) maximumizeInitDisplay,
+ (InitPluginObjectProc) maximumizeInitScreen,
+ (InitPluginObjectProc) maximumizeInitWindow
};
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
@@ -361,13 +685,13 @@ maximumizeInitObject (CompPlugin *p,
static void
maximumizeFiniObject (CompPlugin *p,
- CompObject *o)
+ CompObject *o)
{
static FiniPluginObjectProc dispTab[] = {
- (FiniPluginObjectProc) 0, /* FiniCore */
- 0,
- 0,
- 0
+ (FiniPluginObjectProc) 0, /* InitCore */
+ (FiniPluginObjectProc) maximumizeFiniDisplay,
+ (FiniPluginObjectProc) maximumizeFiniScreen,
+ (FiniPluginObjectProc) maximumizeFiniWindow
};
DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
@@ -376,8 +700,8 @@ maximumizeFiniObject (CompPlugin *p,
CompPluginVTable maximumizeVTable = {
"maximumize",
0,
- 0,
- 0,
+ maximumizeInit,
+ maximumizeFini,
maximumizeInitObject,
maximumizeFiniObject,
0,
diff --git a/maximumize.xml.in b/maximumize.xml.in
index 4787ebd..6538bcc 100644
--- a/maximumize.xml.in
+++ b/maximumize.xml.in
@@ -25,5 +25,14 @@
</option>
</group>
</display>
+ <screen>
+ <option name="speed" type="float">
+ <_short>Speed</_short>
+ <_long>Animation Speed</_long>
+ <default>1.0</default>
+ <min>0.1</min>
+ <max>10.0</max>
+ </option>
+ </screen>
</plugin>
</compiz>
--
1.5.2.4
_______________________________________________
Dev mailing list
[email protected]
http://lists.compiz-fusion.org/mailman/listinfo/dev