--- paint.c 2007-04-05 01:11:50.000000000 +0300 +++ paint.c-new 2007-04-05 03:39:01.000000000 +0300 @@ -157,7 +157,9 @@ 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) { @@ -179,10 +181,29 @@ 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 @@ 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 @@ (*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->prev: w->next) { if (w->destroyed) continue; @@ -231,9 +257,22 @@ (*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); + } }