summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-03-23 22:36:30 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-03-23 22:36:30 +0800
commite4489612952606501869d63b8119bed61d8ee4ed (patch)
tree21b641fe58a581bc62c3b2b1786d46ed54a8234b /src
parent89c2611d0b9e956ddb437cf8a4155110da4903a1 (diff)
downloadmobilebling-e4489612952606501869d63b8119bed61d8ee4ed.tar.gz
mobilebling-e4489612952606501869d63b8119bed61d8ee4ed.tar.bz2
Don't treat synthetic UnmapNotify the same as the real UnmapNotify
ICCCM section 4.1.4 says that applications need to send us a synthetic UnmapNotify to tell us that the window has been withdrawn in all cases to cover the case where a window is already unmapped and then withdrawn. In this case we should handle the UnmapNotify as a request to withdraw the window, but we should only handle the *real* UnmapNotify request as a request to actually process the window being unmapped and withdraw it there, rather than processing both twice and withdrawing the window twice
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp38
-rw-r--r--src/privatewindow.h2
-rw-r--r--src/window.cpp11
3 files changed, 37 insertions, 14 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 5c0769d..b27e8b5 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1122,7 +1122,7 @@ CompScreen::handleEvent (XEvent *event)
* and then bypassing MapRequest because it *is* override-redirect
* at XMapWindow time, so we need to catch this case and make
* sure that windows are tracked here */
-
+
foreach (CoreWindow *cw, priv->createdWindows)
{
if (cw->priv->id == event->xmap.window)
@@ -1184,30 +1184,40 @@ CompScreen::handleEvent (XEvent *event)
}
else /* X -> Withdrawn */
{
- /* Iconic -> Withdrawn */
+ /* Iconic -> Withdrawn:
+ *
+ * The window is already unmapped so we need to check the
+ * synthetic UnmapNotify that comes and withdraw the window here */
if (w->state () & CompWindowStateHiddenMask)
{
w->priv->minimized = false;
-
w->changeState (w->state () & ~CompWindowStateHiddenMask);
priv->updateClientList ();
+ w->priv->withdraw ();
}
- else /* Closing */
+ /* Closing:
+ *
+ * ICCCM Section 4.1.4 says that clients need to send
+ * a synthetic UnmapNotify for every real unmap
+ * in order to reflect the change in state, but
+ * since we already withdraw the window on the real
+ * UnmapNotify, no need to do it again on the synthetic
+ * one. */
+ else if (!event->xunmap.send_event)
+ {
w->windowNotify (CompWindowNotifyClose);
-
- if (!w->overrideRedirect ())
- priv->setWmState (WithdrawnState, w->id ());
-
- w->priv->placed = false;
- w->priv->unmanaging = w->priv->managed;
- w->priv->managed = false;
+ w->priv->withdraw ();
+ }
}
- w->unmap ();
+ if (!event->xunmap.send_event)
+ {
+ w->unmap ();
- if (!w->shaded () && !w->priv->pendingMaps)
- w->moveInputFocusToOtherWindow ();
+ if (!w->shaded () && !w->priv->pendingMaps)
+ w->moveInputFocusToOtherWindow ();
+ }
}
break;
case ReparentNotify:
diff --git a/src/privatewindow.h b/src/privatewindow.h
index 4bed1bc..2b2d6a4 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -137,6 +137,8 @@ class PrivateWindow {
void show ();
+ void withdraw ();
+
bool handlePingTimeout (unsigned int lastPing);
void handlePing (int lastPing);
diff --git a/src/window.cpp b/src/window.cpp
index 53fe4d8..7ea63ba 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1365,6 +1365,17 @@ CompWindow::unmap ()
windowNotify (CompWindowNotifyUnmap);
}
+void
+PrivateWindow::withdraw ()
+{
+ if (!attrib.override_redirect)
+ screen->priv->setWmState (WithdrawnState, id);
+
+ placed = false;
+ unmanaging = managed;
+ managed = false;
+}
+
bool
PrivateWindow::restack (Window aboveId)
{