composite: Copy the window contents back from the pixmap
Since extra expose events are no longer generated during window unredirection, the window contents must be preserved by the server. So copy the window contents back from the pixmap. The copy can only be done after the clips have been recomputed, so delay the copy and the pixmap destruction until ValidateTree is done. Window borders are restored by HandleExposures and thus don't need to be copied back. Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com> Reviewed-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
parent
193ecc8b45
commit
74663e6152
|
@ -239,6 +239,34 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
|
WindowPtr pParent = pWin->parent;
|
||||||
|
|
||||||
|
if (pParent->drawable.depth == pWin->drawable.depth) {
|
||||||
|
GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
|
||||||
|
int bw = (int) pWin->borderWidth;
|
||||||
|
int x = bw;
|
||||||
|
int y = bw;
|
||||||
|
int w = pWin->drawable.width;
|
||||||
|
int h = pWin->drawable.height;
|
||||||
|
|
||||||
|
if (pGC) {
|
||||||
|
ChangeGCVal val;
|
||||||
|
val.val = IncludeInferiors;
|
||||||
|
ChangeGC (NullClient, pGC, GCSubwindowMode, &val);
|
||||||
|
ValidateGC(&pWin->drawable, pGC);
|
||||||
|
(*pGC->ops->CopyArea) (&pPixmap->drawable,
|
||||||
|
&pWin->drawable,
|
||||||
|
pGC,
|
||||||
|
x, y, w, h, 0, 0);
|
||||||
|
FreeScratchGC (pGC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free one of the per-client per-window resources, clearing
|
* Free one of the per-client per-window resources, clearing
|
||||||
* redirect and the per-window pointer as appropriate
|
* redirect and the per-window pointer as appropriate
|
||||||
|
@ -246,10 +274,12 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
|
||||||
void
|
void
|
||||||
compFreeClientWindow (WindowPtr pWin, XID id)
|
compFreeClientWindow (WindowPtr pWin, XID id)
|
||||||
{
|
{
|
||||||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
CompWindowPtr cw = GetCompWindow (pWin);
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
CompClientWindowPtr ccw, *prev;
|
CompClientWindowPtr ccw, *prev;
|
||||||
Bool anyMarked = FALSE;
|
Bool anyMarked = FALSE;
|
||||||
WindowPtr pLayerWin;
|
WindowPtr pLayerWin;
|
||||||
|
PixmapPtr pPixmap = NULL;
|
||||||
|
|
||||||
if (!cw)
|
if (!cw)
|
||||||
return;
|
return;
|
||||||
|
@ -268,8 +298,10 @@ compFreeClientWindow (WindowPtr pWin, XID id)
|
||||||
{
|
{
|
||||||
anyMarked = compMarkWindows (pWin, &pLayerWin);
|
anyMarked = compMarkWindows (pWin, &pLayerWin);
|
||||||
|
|
||||||
if (pWin->redirectDraw != RedirectDrawNone)
|
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||||
compFreePixmap (pWin);
|
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
compSetParentPixmap (pWin);
|
||||||
|
}
|
||||||
|
|
||||||
if (cw->damage)
|
if (cw->damage)
|
||||||
DamageDestroy (cw->damage);
|
DamageDestroy (cw->damage);
|
||||||
|
@ -290,6 +322,11 @@ compFreeClientWindow (WindowPtr pWin, XID id)
|
||||||
|
|
||||||
if (anyMarked)
|
if (anyMarked)
|
||||||
compHandleMarkedWindows (pWin, pLayerWin);
|
compHandleMarkedWindows (pWin, pLayerWin);
|
||||||
|
|
||||||
|
if (pPixmap) {
|
||||||
|
compRestoreWindow (pWin, pPixmap);
|
||||||
|
(*pScreen->DestroyPixmap) (pPixmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -621,10 +658,10 @@ compAllocPixmap (WindowPtr pWin)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compFreePixmap (WindowPtr pWin)
|
compSetParentPixmap (WindowPtr pWin)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
PixmapPtr pRedirectPixmap, pParentPixmap;
|
PixmapPtr pParentPixmap;
|
||||||
CompWindowPtr cw = GetCompWindow (pWin);
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
|
||||||
if (cw->damageRegistered)
|
if (cw->damageRegistered)
|
||||||
|
@ -640,11 +677,9 @@ compFreePixmap (WindowPtr pWin)
|
||||||
* parent exposed area; regions beyond the parent cause crashes
|
* parent exposed area; regions beyond the parent cause crashes
|
||||||
*/
|
*/
|
||||||
RegionCopy(&pWin->borderClip, &cw->borderClip);
|
RegionCopy(&pWin->borderClip, &cw->borderClip);
|
||||||
pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
|
||||||
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
|
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
|
||||||
pWin->redirectDraw = RedirectDrawNone;
|
pWin->redirectDraw = RedirectDrawNone;
|
||||||
compSetPixmap (pWin, pParentPixmap);
|
compSetPixmap (pWin, pParentPixmap);
|
||||||
(*pScreen->DestroyPixmap) (pRedirectPixmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -215,7 +215,10 @@ Bool
|
||||||
compAllocPixmap (WindowPtr pWin);
|
compAllocPixmap (WindowPtr pWin);
|
||||||
|
|
||||||
void
|
void
|
||||||
compFreePixmap (WindowPtr pWin);
|
compSetParentPixmap (WindowPtr pWin);
|
||||||
|
|
||||||
|
void
|
||||||
|
compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap);
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
compReallocPixmap (WindowPtr pWin, int x, int y,
|
compReallocPixmap (WindowPtr pWin, int x, int y,
|
||||||
|
|
|
@ -164,8 +164,13 @@ compCheckRedirect (WindowPtr pWin)
|
||||||
{
|
{
|
||||||
if (should)
|
if (should)
|
||||||
return compAllocPixmap (pWin);
|
return compAllocPixmap (pWin);
|
||||||
else
|
else {
|
||||||
compFreePixmap (pWin);
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
compSetParentPixmap (pWin);
|
||||||
|
compRestoreWindow (pWin, pPixmap);
|
||||||
|
(*pScreen->DestroyPixmap) (pPixmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -583,8 +588,11 @@ compDestroyWindow (WindowPtr pWin)
|
||||||
while ((csw = GetCompSubwindows (pWin)))
|
while ((csw = GetCompSubwindows (pWin)))
|
||||||
FreeResource (csw->clients->id, RT_NONE);
|
FreeResource (csw->clients->id, RT_NONE);
|
||||||
|
|
||||||
if (pWin->redirectDraw != RedirectDrawNone)
|
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||||
compFreePixmap (pWin);
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
compSetParentPixmap (pWin);
|
||||||
|
(*pScreen->DestroyPixmap) (pPixmap);
|
||||||
|
}
|
||||||
ret = (*pScreen->DestroyWindow) (pWin);
|
ret = (*pScreen->DestroyWindow) (pWin);
|
||||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||||
pScreen->DestroyWindow = compDestroyWindow;
|
pScreen->DestroyWindow = compDestroyWindow;
|
||||||
|
|
Loading…
Reference in New Issue