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