rendered paste bodydiff --git a/include/compiz.h b/include/compiz.h
index 496bfaf..62544fc 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -1154,6 +1154,12 @@ typedef void (*DonePaintScreenProc) (CompScreen *screen);
#define PAINT_SCREEN_TRANSFORMED_MASK (1 << 2)
#define PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK (1 << 3)
#define PAINT_SCREEN_CLEAR_MASK (1 << 4)
+#define PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK (1 << 5)
+#define PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK (1 << 6)
+/* A plugin that sets PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK will get reversed painting.
+ A plugin that sets both PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK and PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK
+ will get both normal and reversed painting one after the other,
+ and will check paint window mask to avoid painting the window twice. This allows more complex drawing order.*/
typedef Bool (*PaintScreenProc) (CompScreen *screen,
const ScreenPaintAttrib *sAttrib,
@@ -1219,6 +1225,13 @@ typedef void (*ApplyScreenTransformProc) (CompScreen *screen,
*/
#define PAINT_WINDOW_BLEND_MASK (1 << 19)
+/*
+ flags that indicate the painting order which is used
+ in paintScreen when drawing the window.
+*/
+#define PAINT_WINDOW_BACK_TO_FRONT_MASK (1 << 20)
+#define PAINT_WINDOW_FRONT_TO_BACK_MASK (1 << 21)
+
typedef Bool (*PaintWindowProc) (CompWindow *window,
const WindowPaintAttrib *attrib,
diff --git a/src/paint.c b/src/paint.c
index a618328..9facc66 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -157,7 +157,10 @@ paintScreenRegion (CompScreen *screen,
static Region tmpRegion = NULL;
CompWindow *w;
CompCursor *c;
- int count, windowMask, backgroundMask;
+ int count, windowMask, backgroundMask, occlusionMask;
+ Bool ftb = (mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) &&
+ !(mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK); // Do FTB drawing only if FTB flag is set and BTF flag isn't
+
if (!tmpRegion)
{
@@ -178,11 +181,29 @@ paintScreenRegion (CompScreen *screen,
windowMask = 0;
count = 0;
}
+
+ if (ftb)
+ {
+ windowMask |= PAINT_WINDOW_FRONT_TO_BACK_MASK;
+ occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK |
+ PAINT_WINDOW_FRONT_TO_BACK_MASK;
+ }
+ else
+ {
+ windowMask |= PAINT_WINDOW_BACK_TO_FRONT_MASK;
+ occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK |
+ PAINT_WINDOW_BACK_TO_FRONT_MASK;
+ }
XSubtractRegion (region, &emptyRegion, tmpRegion);
- /* detect occlusions */
- for (w = screen->reverseWindows; w; w = w->prev)
+ /* detect occlusions (order is reversed from true painting order). */
+ if (ftb)
+ w = screen->windows;
+ else
+ w = screen->reverseWindows;
+
+ for (; w; w = (ftb)? w->next: w->prev)
{
if (w->destroyed)
continue;
@@ -197,7 +218,7 @@ paintScreenRegion (CompScreen *screen,
XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
if ((*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
- PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
+ occlusionMask))
{
/* unredirect top most fullscreen windows. */
if (count == 0 &&
@@ -216,8 +237,13 @@ paintScreenRegion (CompScreen *screen,
(*screen->paintBackground) (screen, tmpRegion, backgroundMask);
- /* paint all windows from bottom to top */
- for (w = screen->windows; w; w = w->next)
+ /* paint all windows with the order specified by the masks. */
+ if (ftb)
+ w = screen->reverseWindows;
+ else
+ w = screen->windows;
+
+ for (; w; w = (ftb)? w->next: w->prev)
{
if (w->destroyed)
continue;
@@ -231,9 +257,22 @@ paintScreenRegion (CompScreen *screen,
(*screen->paintWindow) (w, &w->paint, transform, w->clip, windowMask);
}
- /* paint cursors */
- for (c = screen->cursors; c; c = c->next)
- (*screen->paintCursor) (c, transform, tmpRegion, 0);
+ if ((mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) &&
+ (mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK))
+ {
+ /* when both modes are set, we first paint in Back-To-Front mode (already done),
+ and after that we paint the screen in Front-To-Back mode, by removing the
+ Back-To-Front mask.
+ Painting the cursors will be done after the Front-To-Back drawing*/
+ paintScreenRegion (screen, transform, region, output,
+ mask & (~PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK));
+ }
+ else
+ {
+ /* paint cursors */
+ for (c = screen->cursors; c; c = c->next)
+ (*screen->paintCursor) (c, transform, tmpRegion, 0);
+ }
}