summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-05-28 00:40:42 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-05-28 00:40:42 +0800
commit0d12d80380274d2a605423029a0c7034669b9df0 (patch)
treebce3d963fcdfe544e1ac6157975abcc239433b0c /src
parenta39f7e3307c0a5fa3423b1426610860e532529d7 (diff)
downloadmobilebling-0d12d80380274d2a605423029a0c7034669b9df0.tar.gz
mobilebling-0d12d80380274d2a605423029a0c7034669b9df0.tar.bz2
Read the current override redirect state as the client may have
changed it while CreateNotify is being processed and thus we could be reparenting and override redirect window. Also ensure that when unreparenting windows that their parent is still the wrapper window, otherwise don't bother to reparent them back into the root window, this will only cause trouble. Fixes LP#767095
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp45
-rw-r--r--src/screen.cpp2
-rw-r--r--src/window.cpp34
3 files changed, 32 insertions, 49 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 1549964..3976f2f 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1204,7 +1204,7 @@ CompScreen::handleEvent (XEvent *event)
else if (!(event->xreparent.parent == priv->root))
{
bool remove = false;
- Window xid = None;
+ Window xid = event->xreparent.window;
Window root_return;
unsigned int ui;
int x, y;
@@ -1218,47 +1218,12 @@ CompScreen::handleEvent (XEvent *event)
if (event->xreparent.parent != w->priv->wrapper)
{
w->moveInputFocusToOtherWindow ();
-
- /* In the case where someone else reparented one of
- * our windows we are going to get the UnmapNotify first
- * which means that this will start reparenting the
- * window into the root window and interrupt
- * the client's request to reparent into another
- * window, we should handle this case */
- if (!w->priv->frame)
- {
- xid = w->priv->id;
- XGetGeometry (screen->dpy (), xid, &root_return,
- &x, &y, &ui, &ui, &ui, &ui);
- }
w->destroy ();
- remove = true;
- }
- }
- else
- {
- foreach (CoreWindow *cw, screen->priv->createdWindows)
- {
- if (cw->priv->id == event->xreparent.parent)
- {
- screen->priv->createdWindows.remove (cw);
- delete cw;
- remove = true;
- break;
- }
- }
- }
- if (remove)
- {
- XSelectInput (priv->dpy, w->id (), NoEventMask);
- XShapeSelectInput (priv->dpy, w->id (), NoEventMask);
- XUngrabButton (priv->dpy, AnyButton, AnyModifier, w->id ());
-
- /* Reparent the window back where it belongs */
- if (xid)
- XReparentWindow (screen->dpy (), xid, event->xreparent.parent,
- x, y);
+ XSelectInput (priv->dpy, w->id (), NoEventMask);
+ XShapeSelectInput (priv->dpy, w->id (), NoEventMask);
+ XUngrabButton (priv->dpy, AnyButton, AnyModifier, w->id ());
+ }
}
}
break;
diff --git a/src/screen.cpp b/src/screen.cpp
index 4d26c68..40a74b5 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -4406,7 +4406,7 @@ CompScreen::init (const char *name)
CompScreen::checkForError (dpy);
- XGrabServer (dpy);
+ //XGrabServer (dpy);
XSelectInput (dpy, root,
SubstructureRedirectMask |
diff --git a/src/window.cpp b/src/window.cpp
index f3a1402..32429e7 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -5718,7 +5718,6 @@ bool
PrivateWindow::reparent ()
{
XSetWindowAttributes attr;
- XWindowAttributes wa;
XWindowChanges xwc;
int mask;
unsigned int nchildren;
@@ -5730,19 +5729,22 @@ PrivateWindow::reparent ()
Colormap cmap = DefaultColormap (screen->dpy (),
screen->screenNum ());
- if (frame || attrib.override_redirect)
+ if (frame)
return false;
XSync (dpy, false);
XGrabServer (dpy);
- if (!XGetWindowAttributes (dpy, id, &wa))
+ if (!XGetWindowAttributes (dpy, id, &attrib))
{
XUngrabServer (dpy);
XSync (dpy, false);
return false;
}
+ if (attrib.override_redirect)
+ return false;
+
/* Don't ever reparent windows which have ended up
* reparented themselves on the server side but not
* on the client side */
@@ -5823,7 +5825,7 @@ PrivateWindow::reparent ()
XChangeWindowAttributes (dpy, id, CWEventMask | CWDontPropagate, &attr);
- if (wa.map_state == IsViewable || shaded)
+ if (attrib.map_state == IsViewable || shaded)
XMapWindow (dpy, frame);
attr.event_mask = SubstructureRedirectMask | StructureNotifyMask |
@@ -5861,10 +5863,12 @@ PrivateWindow::reparent ()
void
PrivateWindow::unreparent ()
{
- Display *dpy = screen->dpy ();
- XEvent e;
- bool alive = true;
- XWindowChanges xwc;
+ Display *dpy = screen->dpy ();
+ XEvent e;
+ bool alive = true;
+ XWindowChanges xwc;
+ unsigned int nchildren;
+ Window *children = NULL, root_return, parent_return;
if (!frame)
return;
@@ -5877,6 +5881,17 @@ PrivateWindow::unreparent ()
alive = false;
}
+ /* Also don't reparent back into root windows that have ended up
+ * reparented into other windows (and as such we are unmanaging them */
+
+ if (alive)
+ {
+ XQueryTree (dpy, id, &root_return, &parent_return, &children, &nchildren);
+
+ if (parent_return != wrapper)
+ alive = false;
+ }
+
if ((!destroyed) && alive)
{
XGrabServer (dpy);
@@ -5922,6 +5937,9 @@ PrivateWindow::unreparent ()
XMoveWindow (dpy, id, serverGeometry.x (), serverGeometry.y ());
}
+ if (children)
+ XFree (children);
+
XDestroyWindow (dpy, wrapper);
XDestroyWindow (dpy, frame);
wrapper = None;