diff --git a/include/cube.h b/include/cube.h
index e8ce02a..4e0da0c 100644
--- a/include/cube.h
+++ b/include/cube.h
@@ -65,7 +65,8 @@ typedef struct _CubeDisplay {
#define CUBE_SCREEN_OPTION_FADE_TIME 17
#define CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY 18
#define CUBE_SCREEN_OPTION_MULTIOUTPUT_MODE 19
-#define CUBE_SCREEN_OPTION_NUM 20
+#define CUBE_SCREEN_OPTION_STUCK_TO_SCREEN 20
+#define CUBE_SCREEN_OPTION_NUM 21
typedef void (*CubeGetRotationProc) (CompScreen *s,
float *x,
@@ -182,6 +183,8 @@ typedef struct _CubeScreen {
int moMode;
Bool recalcOutput;
+
+ Bool finalPaint;
} CubeScreen;
#define GET_CUBE_DISPLAY(d) \
diff --git a/metadata/cube.xml.in b/metadata/cube.xml.in
index 6a9fba4..e659ee1 100644
--- a/metadata/cube.xml.in
+++ b/metadata/cube.xml.in
@@ -182,6 +182,11 @@
<_name>On big cube
+
diff --git a/plugins/cube.c b/plugins/cube.c
index c7ef08c..a1b298c 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -63,6 +63,15 @@ v[1] /= v[3]; \
v[2] /= v[3]; \
v[3] /= v[3];
+static const CompTransform identity = {
+ {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ }
+};
+
static CompMetadata cubeMetadata;
static int cubeDisplayPrivateIndex;
@@ -914,12 +923,17 @@ cubePaintOutput (CompScreen *s,
CUBE_SCREEN (s);
+ cs->finalPaint = TRUE;
+
if (cs->grabIndex || cs->desktopOpacity != OPAQUE)
{
mask &= ~PAINT_SCREEN_REGION_MASK;
mask |= PAINT_SCREEN_TRANSFORMED_MASK;
}
+ if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
+ cs->finalPaint = !(cs->opt[CUBE_SCREEN_OPTION_STUCK_TO_SCREEN].value.b);
+
cs->srcOutput = (output->id != ~0) ? output->id : 0;
/* Always use BTF painting on non-transformed screen */
cs->paintOrder = BTF;
@@ -928,6 +942,35 @@ cubePaintOutput (CompScreen *s,
status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
WRAP (cs, s, paintOutput, cubePaintOutput);
+ if (!cs->finalPaint)
+ {
+ CompWindow * w;
+ CompTransform sTransform = *transform;
+
+ glPushMatrix ();
+ transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
+ glLoadMatrixf (sTransform.m);
+
+ cs->finalPaint = TRUE;
+ for (w = s->reverseWindows; w; w = w->prev)
+ {
+ if ((w->type & CompWindowTypeDockMask) ||
+ (w->state & CompWindowStateStickyMask &&
+ !(w->state & CompWindowStateBelowMask)) ||
+ w->attrib.override_redirect)
+ {
+ if (w->mapNum && w->attrib.map_state == IsViewable &&
+ !w->minimized && !(w->state & CompWindowStateHiddenMask))
+ {
+ (*s->paintWindow) (w, &w->paint, &identity,
+ &infiniteRegion, 0);
+ }
+ }
+ }
+
+ glPopMatrix ();
+ }
+
return status;
}
@@ -1026,11 +1069,13 @@ cubeMoveViewportAndPaint (CompScreen *s,
PaintOrder paintOrder,
int dx)
{
- Bool ftb;
+ Bool ftb, lastFinalPaint;
int output;
CUBE_SCREEN (s);
+ lastFinalPaint = cs->finalPaint;
+
float vPoints[3][3] = { { -0.5, 0.0, cs->invert * cs->distance},
{ 0.0, 0.5, cs->invert * cs->distance},
{ 0.0, 0.0, cs->invert * cs->distance}};
@@ -1069,6 +1114,10 @@ cubeMoveViewportAndPaint (CompScreen *s,
/* translate back to compiz output */
output = cs->srcOutput = cs->output[cubeOutput];
+ if (dView != 0)
+ cs->finalPaint =
+ !(cs->opt[CUBE_SCREEN_OPTION_STUCK_TO_SCREEN].value.b);
+
moveScreenViewport (s, -dView, 0, FALSE);
(*s->paintTransformedOutput) (s, sAttrib, transform,
&s->outputDev[output].region,
@@ -1077,6 +1126,10 @@ cubeMoveViewportAndPaint (CompScreen *s,
}
else
{
+ if (dx != 0)
+ cs->finalPaint =
+ !(cs->opt[CUBE_SCREEN_OPTION_STUCK_TO_SCREEN].value.b);
+
moveScreenViewport (s, dx, 0, FALSE);
if (cs->moMode == CUBE_MOMODE_MULTI)
(*s->paintTransformedOutput) (s, sAttrib, transform,
@@ -1087,6 +1140,7 @@ cubeMoveViewportAndPaint (CompScreen *s,
outputPtr, mask);
moveScreenViewport (s, -dx, 0, FALSE);
}
+ cs->finalPaint = lastFinalPaint;
}
static void
@@ -1382,6 +1436,9 @@ cubePaintTransformedOutput (CompScreen *s,
cubeUpdateGeometry (s, s->hsize, cs->invert);
}
+ if (sAttrib->zCamera != -DEFAULT_Z_CAMERA)
+ cs->finalPaint = !(cs->opt[CUBE_SCREEN_OPTION_STUCK_TO_SCREEN].value.b);
+
hsize = s->hsize * cs->nOutput;
size = hsize;
@@ -1734,6 +1791,12 @@ cubePaintWindow (CompWindow *w,
if (w->type & CompWindowTypeDesktopMask)
wa.opacity = cs->desktopOpacity;
+ if (!cs->finalPaint &&
+ ((w->type & CompWindowTypeDockMask) ||
+ (w->state & CompWindowStateStickyMask &&
+ !(w->state & CompWindowStateBelowMask))))
+ return FALSE;
+
UNWRAP (cs, s, paintWindow);
status = (*s->paintWindow) (w, &wa, transform, region, mask);
WRAP (cs, s, paintWindow, cubePaintWindow);
@@ -2071,7 +2134,8 @@ static const CompMetadataOptionInfo cubeScreenOptionInfo[] = {
{ "inactive_opacity", "float", "0.0100.0", 0, 0 },
{ "fade_time", "float", "0.0", 0, 0 },
{ "transparent_manual_only", "bool", 0, 0, 0 },
- { "multioutput_mode", "int", "02", 0, 0 }
+ { "multioutput_mode", "int", "02", 0, 0 },
+ { "stuck_to_screen", "bool", 0, 0, 0 }
};
static Bool