diff options
author | Erkin Bahceci <erkinbah@gmail.com> | 2009-09-13 23:49:37 -0500 |
---|---|---|
committer | Erkin Bahceci <erkinbah@gmail.com> | 2009-09-13 23:49:37 -0500 |
commit | b74f2cd8f7359edfd01e245efa37224e62ce1446 (patch) | |
tree | 79beaf49307ea17a4778b7c8b7c80efafe1de855 | |
parent | 6008880ec65d4d8fdffab7e00c0d6c84db54237d (diff) | |
download | stackswitch-b74f2cd8f7359edfd01e245efa37224e62ce1446.tar.gz stackswitch-b74f2cd8f7359edfd01e245efa37224e62ce1446.tar.bz2 |
Fix crash when a minimized window closes while switching with "show minimized" on.compiz-0.8
-rw-r--r-- | stackswitch.c | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/stackswitch.c b/stackswitch.c index 496a45d..988d4b3 100644 --- a/stackswitch.c +++ b/stackswitch.c @@ -95,7 +95,8 @@ typedef struct _StackswitchScreen { int nWindows; Window clientLeader; - Window selectedWindow; + + CompWindow *selectedWindow; /* text display support */ CompTextData *textData; @@ -146,6 +147,9 @@ isStackswitchWin (CompWindow *w) { STACKSWITCH_SCREEN (w->screen); + if (w->destroyed) + return FALSE; + if (w->attrib.override_redirect) return FALSE; @@ -251,7 +255,10 @@ stackswitchRenderWindowTitle (CompScreen *s) tA.bgColor[3] = stackswitchGetTitleBackColorAlpha (s); showViewport = ss->type == StackswitchTypeAll; - ss->textData = (sd->textFunc->renderWindowTitle) (s, ss->selectedWindow, + ss->textData = (sd->textFunc->renderWindowTitle) (s, + (ss->selectedWindow ? + ss->selectedWindow->id : + None), showViewport, &tA); } @@ -485,7 +492,7 @@ stackswitchPaintWindow (CompWindow *w, if (sw->slot) { - if (w->id != ss->selectedWindow) + if (w != ss->selectedWindow) fragment.opacity = (float)fragment.opacity * stackswitchGetInactiveOpacity (s) / 100; } @@ -618,12 +625,12 @@ compareStackswitchWindowDepth (const void *elem1, return 1; else { - CompWindow *a1 = (((StackswitchDrawSlot *) elem1)->w); - CompWindow *a2 = (((StackswitchDrawSlot *) elem2)->w); - STACKSWITCH_SCREEN (a1->screen); - if (a1->id == ss->selectedWindow) + CompWindow *w1 = (((StackswitchDrawSlot *) elem1)->w); + CompWindow *w2 = (((StackswitchDrawSlot *) elem2)->w); + STACKSWITCH_SCREEN (w1->screen); + if (w1 == ss->selectedWindow) return 1; - else if (a2->id == ss->selectedWindow) + else if (w2 == ss->selectedWindow) return -1; else return 0; @@ -743,7 +750,7 @@ layoutThumbs (CompScreen *s) continue; } - if (w->id == ss->selectedWindow) + if (w == ss->selectedWindow) hasActive = 1; swi += ww * sw->slot->scale; @@ -855,7 +862,7 @@ switchToWindow (CompScreen *s, for (cur = 0; cur < ss->nWindows; cur++) { - if (ss->windows[cur]->id == ss->selectedWindow) + if (ss->windows[cur] == ss->selectedWindow) break; } @@ -869,10 +876,10 @@ switchToWindow (CompScreen *s, if (w) { - Window old = ss->selectedWindow; + CompWindow *old = ss->selectedWindow; - ss->selectedWindow = w->id; - if (old != w->id) + ss->selectedWindow = w; + if (old != w) { ss->rotateAdjust = TRUE; @@ -961,7 +968,7 @@ adjustStackswitchVelocity (CompWindow *w) y1 = w->attrib.y + w->attrib.height + w->input.bottom; } - if (w->id == ss->selectedWindow) + if (w == ss->selectedWindow) rot = ss->rotation; else rot = 0.0; @@ -1070,7 +1077,7 @@ stackswitchPaintOutput (CompScreen *s, if (ss->drawSlots[i].slot && *(ss->drawSlots[i].slot)) { CompWindow *w = ss->drawSlots[i].w; - if (w->id == ss->selectedWindow) + if (w == ss->selectedWindow) aw = w; (*s->paintWindow) (w, &w->paint, &sTransform, @@ -1139,7 +1146,7 @@ stackswitchPreparePaintScreen (CompScreen *s, sw->scale = sw->slot->scale; sw->tx = sw->slot->x; sw->ty = sw->slot->y; - if (w->id == ss->selectedWindow) + if (w == ss->selectedWindow) sw->rotation = ss->rotation; else sw->rotation = 0.0; @@ -1232,11 +1239,10 @@ stackswitchTerminate (CompDisplay *d, ss->state = StackswitchStateIn; damageScreen (s); - if (!(state & CompActionStateCancel) && ss->selectedWindow) + if (!(state & CompActionStateCancel) && ss->selectedWindow && + !ss->selectedWindow->destroyed) { - w = findWindowAtScreen (s, ss->selectedWindow); - if (w) - sendWindowActivationRequest (s, w->id); + sendWindowActivationRequest (s, ss->selectedWindow->id); } } } @@ -1297,7 +1303,7 @@ stackswitchInitiate (CompScreen *s, if (!stackswitchCreateWindowList (s)) return FALSE; - ss->selectedWindow = ss->windows[0]->id; + ss->selectedWindow = ss->windows[0]; stackswitchRenderWindowTitle (s); for (w = s->windows; w; w = w->next) @@ -1440,16 +1446,13 @@ stackswitchPrevGroup (CompDisplay *d, static void stackswitchWindowRemove (CompDisplay *d, - Window id) + CompWindow *w) { - CompWindow *w; - - w = findWindowAtDisplay (d, id); if (w) { Bool inList = FALSE; int j, i = 0; - Window selected; + CompWindow *selected; STACKSWITCH_SCREEN (w->screen); @@ -1463,18 +1466,19 @@ stackswitchWindowRemove (CompDisplay *d, while (i < ss->nWindows) { - if (w->id == ss->windows[i]->id) + if (w == ss->windows[i]) { inList = TRUE; - if (w->id == selected) + if (w == selected) { if (i < (ss->nWindows - 1)) - selected = ss->windows[i + 1]->id; + selected = ss->windows[i + 1]; else - selected = ss->windows[0]->id; + selected = ss->windows[0]; ss->selectedWindow = selected; + stackswitchRenderWindowTitle (w->screen); } ss->nWindows--; @@ -1502,7 +1506,9 @@ stackswitchWindowRemove (CompDisplay *d, return; } - if (!ss->grabIndex) + // Let the window list be updated to avoid crash + // when a window is closed while ending (StackswitchStateIn). + if (!ss->grabIndex && ss->state != StackswitchStateIn) return; if (stackswitchUpdateWindowList (w->screen)) @@ -1518,6 +1524,18 @@ static void stackswitchHandleEvent (CompDisplay *d, XEvent *event) { + CompWindow *w = NULL; + + switch (event->type) { + case DestroyNotify: + /* We need to get the CompWindow * for event->xdestroywindow.window + here because in the (*d->handleEvent) call below, that CompWindow's + id will become 1, so findWindowAtDisplay won't be able to find the + CompWindow after that. */ + w = findWindowAtDisplay (d, event->xdestroywindow.window); + break; + } + STACKSWITCH_DISPLAY (d); UNWRAP (sd, d, handleEvent); @@ -1528,12 +1546,11 @@ stackswitchHandleEvent (CompDisplay *d, case PropertyNotify: if (event->xproperty.atom == XA_WM_NAME) { - CompWindow *w; w = findWindowAtDisplay (d, event->xproperty.window); if (w) { STACKSWITCH_SCREEN (w->screen); - if (ss->grabIndex && (w->id == ss->selectedWindow)) + if (ss->grabIndex && (w == ss->selectedWindow)) { stackswitchRenderWindowTitle (w->screen); damageScreen (w->screen); @@ -1542,10 +1559,11 @@ stackswitchHandleEvent (CompDisplay *d, } break; case UnmapNotify: - stackswitchWindowRemove (d, event->xunmap.window); + w = findWindowAtDisplay (d, event->xunmap.window); + stackswitchWindowRemove (d, w); break; case DestroyNotify: - stackswitchWindowRemove (d, event->xdestroywindow.window); + stackswitchWindowRemove (d, w); break; } } @@ -1702,7 +1720,7 @@ stackswitchInitScreen (CompPlugin *p, ss->paintingSwitcher = FALSE; - ss->selectedWindow = None; + ss->selectedWindow = NULL; ss->moreAdjust = FALSE; ss->rotateAdjust = FALSE; |