summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErkin Bahceci <erkinbah@gmail.com>2009-09-13 23:49:37 -0500
committerErkin Bahceci <erkinbah@gmail.com>2009-09-13 23:49:37 -0500
commitb74f2cd8f7359edfd01e245efa37224e62ce1446 (patch)
tree79beaf49307ea17a4778b7c8b7c80efafe1de855
parent6008880ec65d4d8fdffab7e00c0d6c84db54237d (diff)
downloadstackswitch-compiz-0.8.tar.gz
stackswitch-compiz-0.8.tar.bz2
Fix crash when a minimized window closes while switching with "show minimized" on.compiz-0.8
-rw-r--r--stackswitch.c90
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;