summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErkin Bahceci <erkinbah@gmail.com>2009-10-19 23:56:52 -0500
committerErkin Bahceci <erkinbah@gmail.com>2009-10-19 23:56:52 -0500
commit39265dfc78e633f350c83a62f4a549e7b1892764 (patch)
tree992390024a500ae2c39f4dfb43b51953deb4dc21
parentd8ae6fea739d918d3f07c61fd7673a3d3b34848e (diff)
downloadcompiz-with-glib-mainloop-39265dfc78e633f350c83a62f4a549e7b1892764.tar.gz
compiz-with-glib-mainloop-39265dfc78e633f350c83a62f4a549e7b1892764.tar.bz2
switcher: Fix crash when a minimized window closes while switching with "show minimized" on.
(Forward port of 354adbe10a18509e9ea736cb3ec37916524cf8c3).
-rw-r--r--plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h6
-rw-r--r--plugins/compiztoolbox/src/compiztoolbox.cpp54
-rw-r--r--plugins/switcher/src/switcher.cpp65
-rw-r--r--plugins/switcher/src/switcher.h4
4 files changed, 71 insertions, 58 deletions
diff --git a/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h b/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
index bf14888..6c8b3e4 100644
--- a/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
+++ b/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
@@ -78,7 +78,7 @@ class BaseSwitchScreen
static Visual *findArgbVisual (Display *dpy, int scr);
virtual bool shouldShowIcon () { return false; }
- virtual void windowRemove (Window id) {}
+ virtual void windowRemove (CompWindow *w) {}
virtual void doWindowDamage (CompWindow *w);
virtual void handleSelectionChange (bool toNext, int nextIdx) {}
virtual void getMinimizedAndMatch (bool &minimizedOption,
@@ -93,7 +93,7 @@ class BaseSwitchScreen
CompWindowList windows;
Window popupWindow;
- Window selectedWindow;
+ CompWindow *selectedWindow;
unsigned int lastActiveNum;
CompScreen::GrabHandle grabIndex;
@@ -142,7 +142,7 @@ class BaseSwitchWindow
float width,
float height) {}
bool damageRect (bool, const CompRect &);
- bool isSwitchWin ();
+ bool isSwitchWin (bool removing = false);
BaseSwitchScreen *baseScreen;
GLWindow *gWindow;
diff --git a/plugins/compiztoolbox/src/compiztoolbox.cpp b/plugins/compiztoolbox/src/compiztoolbox.cpp
index 553914e..f8d1144 100644
--- a/plugins/compiztoolbox/src/compiztoolbox.cpp
+++ b/plugins/compiztoolbox/src/compiztoolbox.cpp
@@ -103,9 +103,14 @@ getXDGUserDir (XDGUserDir userDir)
void
BaseSwitchScreen::setSelectedWindowHint ()
{
+ Window selectedWindowId = None;
+
+ if (selectedWindow && !selectedWindow->destroyed ())
+ selectedWindowId = selectedWindow->id ();
+
XChangeProperty (::screen->dpy (), popupWindow, selectWinAtom,
XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &selectedWindow, 1);
+ (unsigned char *) &selectedWindowId, 1);
}
void
@@ -117,13 +122,16 @@ BaseSwitchScreen::getMinimizedAndMatch (bool &minimizedOption,
}
bool
-BaseSwitchWindow::isSwitchWin ()
+BaseSwitchWindow::isSwitchWin (bool removing)
{
bool minimizedOption;
CompMatch *matchOption;
baseScreen->getMinimizedAndMatch (minimizedOption, matchOption);
- if (!window->isViewable () || !window->isMapped ())
+ if (!removing && window->destroyed ())
+ return false;
+
+ if (!removing && (!window->isViewable () || !window->isMapped ()))
{
if (minimizedOption)
{
@@ -160,10 +168,9 @@ BaseSwitchWindow::isSwitchWin ()
if (matchOption && !matchOption->evaluate (window))
return false;
-
}
- if (baseScreen->selection == CurrentViewport)
+ if (!removing && baseScreen->selection == CurrentViewport)
{
if (!window->mapNum () || !window->isViewable ())
{
@@ -226,7 +233,7 @@ BaseSwitchScreen::switchToWindow (bool toNext,
for (it = windows.begin (); it != windows.end (); it++, cur++)
{
- if ((*it)->id () == selectedWindow)
+ if (*it == selectedWindow)
break;
}
@@ -253,7 +260,7 @@ BaseSwitchScreen::switchToWindow (bool toNext,
if (w)
{
- Window old = selectedWindow;
+ CompWindow *old = selectedWindow;
if (selection == AllViewports && autoChangeVPOption)
{
@@ -279,9 +286,9 @@ BaseSwitchScreen::switchToWindow (bool toNext,
}
lastActiveNum = w->activeNum ();
- selectedWindow = w->id ();
+ selectedWindow = w;
- if (old != w->id ())
+ if (old != w)
handleSelectionChange (toNext, nextIdx);
if (popupWindow)
@@ -297,12 +304,8 @@ BaseSwitchScreen::switchToWindow (bool toNext,
doWindowDamage (w);
- if (old)
- {
- w = ::screen->findWindow (old);
- if (w)
- doWindowDamage (w);
- }
+ if (old && !old->destroyed ())
+ doWindowDamage (old);
}
return w;
@@ -574,14 +577,29 @@ BaseSwitchScreen::updateForegroundColor ()
void
BaseSwitchScreen::handleEvent (XEvent *event)
{
+ CompWindow *w = NULL;
+
+ switch (event->type) {
+ case DestroyNotify:
+ /* We need to get the CompWindow * for event->xdestroywindow.window
+ here because in the ::screen->handleEvent call below, that
+ CompWindow's id will become 1, so findWindowAtDisplay won't be
+ able to find the CompWindow after that. */
+ w = ::screen->findWindow (event->xdestroywindow.window);
+ break;
+ default:
+ break;
+ }
+
::screen->handleEvent (event);
switch (event->type) {
case UnmapNotify:
- windowRemove (event->xunmap.window);
+ w = ::screen->findWindow (event->xunmap.window);
+ windowRemove (w);
break;
case DestroyNotify:
- windowRemove (event->xdestroywindow.window);
+ windowRemove (w);
break;
case PropertyNotify:
if (event->xproperty.atom == selectFgColorAtom)
@@ -600,7 +618,7 @@ BaseSwitchScreen::BaseSwitchScreen (CompScreen *screen) :
gScreen (GLScreen::get (screen)),
windows (),
popupWindow (None),
- selectedWindow (None),
+ selectedWindow (NULL),
lastActiveNum (0),
grabIndex (NULL),
moreAdjust (false),
diff --git a/plugins/switcher/src/switcher.cpp b/plugins/switcher/src/switcher.cpp
index d0d29f9..57c1f1f 100644
--- a/plugins/switcher/src/switcher.cpp
+++ b/plugins/switcher/src/switcher.cpp
@@ -66,7 +66,7 @@ SwitchScreen::updateWindowList (int count)
pos = ((count >> 1) - (int)windows.size ()) * WIDTH;
move = 0;
- selectedWindow = windows.front ()->id ();
+ selectedWindow = windows.front ();
x = screen->currentOutputDev ().x1 () +
screen->currentOutputDev ().width () / 2;
@@ -196,7 +196,7 @@ SwitchScreen::initiate (SwitchWindowSelection selection,
return;
this->selection = selection;
- selectedWindow = None;
+ selectedWindow = NULL;
count = countWindows ();
if (count < 1)
@@ -362,16 +362,12 @@ switchTerminate (CompAction *action,
if (state & CompAction::StateCancel)
{
- ss->selectedWindow = None;
- ss->zoomedWindow = None;
+ ss->selectedWindow = NULL;
+ ss->zoomedWindow = NULL;
}
- if (state && ss->selectedWindow)
- {
- w = screen->findWindow (ss->selectedWindow);
- if (w)
- screen->sendWindowActivationRequest (w->id ());
- }
+ if (state && ss->selectedWindow && !ss->selectedWindow->destroyed ())
+ screen->sendWindowActivationRequest (ss->selectedWindow->id ());
screen->removeGrab (ss->grabIndex, 0);
ss->grabIndex = NULL;
@@ -381,8 +377,8 @@ switchTerminate (CompAction *action,
if (!ss->zooming)
{
- ss->selectedWindow = None;
- ss->zoomedWindow = None;
+ ss->selectedWindow = NULL;
+ ss->zoomedWindow = NULL;
ss->activateEvent (false);
}
@@ -391,7 +387,7 @@ switchTerminate (CompAction *action,
ss->moreAdjust = true;
}
- ss->selectedWindow = None;
+ ss->selectedWindow = NULL;
ss->setSelectedWindowHint ();
ss->lastActiveNum = 0;
@@ -439,20 +435,19 @@ switchInitiateCommon (CompAction *action,
}
void
-SwitchScreen::windowRemove (Window id)
+SwitchScreen::windowRemove (CompWindow *w)
{
- CompWindow *w;
-
- w = screen->findWindow (id);
if (w)
{
bool inList = false;
int count;
- Window selected, old;
+
+ CompWindow *selected;
+ CompWindow *old;
SWITCH_WINDOW (w);
- if (!sw->isSwitchWin ())
+ if (!sw->isSwitchWin (true))
return;
sw->cWindow->damageRectSetEnabled (sw, false);
@@ -467,13 +462,13 @@ SwitchScreen::windowRemove (Window id)
{
inList = true;
- if (w->id () == selected)
+ if (w == selected)
{
it++;
if (it == windows.end ())
- selected = windows.front ()->id ();
+ selected = windows.front ();
else
- selected = (*it)->id ();
+ selected = *it;
it--;
}
@@ -523,7 +518,7 @@ SwitchScreen::windowRemove (Window id)
foreach (CompWindow *w, windows)
{
- selectedWindow = w->id ();
+ selectedWindow = w;
if (selectedWindow == selected)
break;
@@ -546,13 +541,13 @@ SwitchScreen::windowRemove (Window id)
if (old != selectedWindow)
{
- CompositeWindow::get (w)->addDamage ();
+ zoomedWindow = selectedWindow;
- w = screen->findWindow (old);
- if (w)
- CompositeWindow::get (w)->addDamage ();
+ CompositeWindow::get (selectedWindow)->addDamage ();
+ CompositeWindow::get (w)->addDamage ();
- moreAdjust = true;
+ if (old && !old->destroyed ())
+ CompositeWindow::get (old)->addDamage ();
}
}
}
@@ -661,8 +656,8 @@ SwitchScreen::preparePaint (int msSinceLastPaint)
translate = 0.0f;
sTranslate = zoom;
- selectedWindow = None;
- zoomedWindow = None;
+ selectedWindow = NULL;
+ zoomedWindow = NULL;
if (grabIndex)
{
@@ -734,8 +729,8 @@ SwitchScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
if (optionGetBringToFront ())
{
- zoomed = screen->findWindow (zoomedWindow);
- if (zoomed)
+ zoomed = zoomedWindow;
+ if (zoomed && !zoomed->destroyed ())
{
CompWindow *w;
@@ -1015,7 +1010,7 @@ SwitchWindow::glPaint (const GLWindowPaintAttrib &attrib,
glDisable (GL_BLEND);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
- else if (window->id () == sScreen->selectedWindow)
+ else if (window == sScreen->selectedWindow)
{
if (sScreen->optionGetBringToFront () &&
sScreen->selectedWindow == sScreen->zoomedWindow)
@@ -1049,7 +1044,7 @@ SwitchWindow::glPaint (const GLWindowPaintAttrib &attrib,
}
if (sScreen->optionGetBringToFront () &&
- window->id () == sScreen->zoomedWindow)
+ window == sScreen->zoomedWindow)
zoomType = ZOOMED_WINDOW_MASK;
if (!(sScreen->zoomMask & zoomType))
@@ -1089,7 +1084,7 @@ SwitchScreen::setZoom ()
SwitchScreen::SwitchScreen (CompScreen *screen) :
BaseSwitchScreen (screen),
PluginClassHandler<SwitchScreen,CompScreen> (screen),
- zoomedWindow (None),
+ zoomedWindow (NULL),
switching (false),
zoomMask (~0),
mVelocity (0.0),
diff --git a/plugins/switcher/src/switcher.h b/plugins/switcher/src/switcher.h
index 13283c6..c0bc93c 100644
--- a/plugins/switcher/src/switcher.h
+++ b/plugins/switcher/src/switcher.h
@@ -71,11 +71,11 @@ class SwitchScreen :
void handleEvent (XEvent *event);
void initiate (SwitchWindowSelection selection,
bool showPopup);
- void windowRemove (Window id);
+ void windowRemove (CompWindow *w);
bool adjustVelocity ();
- Window zoomedWindow;
+ CompWindow *zoomedWindow;
float zoom;