summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2011-01-24 09:12:17 +0800
committerSam Spilsbury <smspillaz@gmail.com>2011-01-24 09:12:17 +0800
commit3136c5ce407b04b363b0edd1fed9772188a87457 (patch)
treef82b98abf78b18d43e103b9b3c1d72865772beba /src
parenta1059c83ebb25e31a8dc67d6dfe6c25bff3fa690 (diff)
downloadmobileperf-3136c5ce407b04b363b0edd1fed9772188a87457.tar.gz
mobileperf-3136c5ce407b04b363b0edd1fed9772188a87457.tar.bz2
Don't make if-statement depend on XWindowAttributes which might be garbage.
The window could have been destroyed by the time we do XGetWindowAttributes on it, so we need to check if that's the case. We still add it to the tree anyways - but only because in between the time when we handle the DestroyNotify for it and the CreateNotify, some windows might have done a ConfigureRequest asking us to stack windows relative to it
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp60
-rw-r--r--src/privatescreen.h2
-rw-r--r--src/privatewindow.h2
-rw-r--r--src/screen.cpp17
-rw-r--r--src/window.cpp37
5 files changed, 73 insertions, 45 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 034ea6a..2cf55b4 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -950,6 +950,34 @@ PrivateScreen::handleActionEvent (XEvent *event)
}
void
+PrivateScreen::setDefaultWindowAttributes (XWindowAttributes *wa)
+{
+ wa->x = 0;
+ wa->y = 0;
+ wa->width = 1;
+ wa->height = 1;
+ wa->border_width = 0;
+ wa->depth = 0;
+ wa->visual = NULL;
+ wa->root = None;
+ wa->c_class = InputOnly;
+ wa->bit_gravity = NorthWestGravity;
+ wa->win_gravity = NorthWestGravity;
+ wa->backing_store = NotUseful;
+ wa->backing_planes = 0;
+ wa->backing_pixel = 0;
+ wa->save_under = false;
+ wa->colormap = None;
+ wa->map_installed = false;
+ wa->map_state = IsUnviewable;
+ wa->all_event_masks = 0;
+ wa->your_event_mask = 0;
+ wa->do_not_propagate_mask = 0;
+ wa->override_redirect = true;
+ wa->screen = NULL;
+}
+
+void
CompScreen::handleCompizEvent (const char *plugin,
const char *event,
CompOption::Vector &options)
@@ -1021,10 +1049,19 @@ CompScreen::handleEvent (XEvent *event)
}
break;
case CreateNotify:
- XGetWindowAttributes (priv->dpy, event->xcreatewindow.window, &wa);
+ {
+ bool failure = false;
+
+ /* Failure means that window has been destroyed. We still have to add
+ * the window to the window list as we might get configure requests
+ * which require us to stack other windows relative to it. Setting
+ * some default values if this is the case. */
+ if (failure = !XGetWindowAttributes (priv->dpy, event->xcreatewindow.window, &wa))
+ priv->setDefaultWindowAttributes (&wa);
+
w = findTopLevelWindow (event->xcreatewindow.window, true);
- if (event->xcreatewindow.parent == wa.root &&
+ if ((event->xcreatewindow.parent == wa.root || failure) &&
(!w || w->frame () != event->xcreatewindow.window))
{
/* Track the window if it was created on this
@@ -1032,15 +1069,16 @@ CompScreen::handleEvent (XEvent *event)
* for FocusChangeMask. Also, we don't want to
* manage it straight away - in reality we want
* that to wait until the map request */
- if (wa.root == priv->root)
+ if (failure || (wa.root == priv->root))
{
- /* Our SubstructurRedirectMask doesn't work on OverrideRedirect
+ /* Our SubstructureRedirectMask doesn't work on OverrideRedirect
* windows so we need to track them directly here */
if (!event->xcreatewindow.override_redirect)
- new CoreWindow (event->xcreatewindow.window);
+ new CoreWindow (event->xcreatewindow.window, wa);
else
{
- CoreWindow *cw = new CoreWindow (event->xcreatewindow.window);
+ CoreWindow *cw =
+ new CoreWindow (event->xcreatewindow.window, wa);
if (cw)
{
@@ -1054,6 +1092,7 @@ CompScreen::handleEvent (XEvent *event)
FocusChangeMask);
}
break;
+ }
case DestroyNotify:
w = findWindow (event->xdestroywindow.window);
if (w)
@@ -1160,7 +1199,14 @@ CompScreen::handleEvent (XEvent *event)
w = findWindow (event->xreparent.window);
if (!w && event->xreparent.parent == priv->root)
{
- CoreWindow *cw = new CoreWindow (event->xreparent.window);
+ /* Failure means that window has been destroyed. We still have to add
+ * the window to the window list as we might get configure requests
+ * which require us to stack other windows relative to it. Setting
+ * some default values if this is the case. */
+ if (!XGetWindowAttributes (priv->dpy, event->xcreatewindow.window, &wa))
+ priv->setDefaultWindowAttributes (&wa);
+
+ CoreWindow *cw = new CoreWindow (event->xreparent.window, wa);
if (cw)
{
diff --git a/src/privatescreen.h b/src/privatescreen.h
index b6975cc..0079243 100644
--- a/src/privatescreen.h
+++ b/src/privatescreen.h
@@ -297,6 +297,8 @@ class PrivateScreen : public CoreOptions {
bool
createFailed ();
+
+ void setDefaultWindowAttributes (XWindowAttributes *);
public:
diff --git a/src/privatewindow.h b/src/privatewindow.h
index ecf6dc3..f2f9609 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -308,7 +308,7 @@ class CoreWindow
{
public:
- CoreWindow (Window id);
+ CoreWindow (Window id, XWindowAttributes &wa);
CompWindow * manage (Window id);
diff --git a/src/screen.cpp b/src/screen.cpp
index 5410f58..96d5416 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -4395,7 +4395,7 @@ CompScreen::init (const char *name)
* on a display level and we need to check
* if the screen we are running on lost focus */
- for (unsigned int i = 0; i <= ScreenCount (dpy) - 1; i++)
+ for (int i = 0; i <= ScreenCount (dpy) - 1; i++)
{
Window rt = XRootWindow (dpy, i);
@@ -4572,7 +4572,20 @@ CompScreen::init (const char *name)
for (unsigned int i = 0; i < nchildren; i++)
{
- CoreWindow *cw = new CoreWindow (children[i]);
+ XWindowAttributes attrib;
+
+ /* Failure means the window has been destroyed, but
+ * still add it to the window list anyways since we
+ * will soon handle the DestroyNotify event for it
+ * and in between CreateNotify time and DestroyNotify
+ * time there might be ConfigureRequests asking us
+ * to stack windows relative to it
+ */
+
+ if (!XGetWindowAttributes (screen->dpy (), children[i], &attrib))
+ priv->setDefaultWindowAttributes (&attrib);
+
+ CoreWindow *cw = new CoreWindow (children[i], attrib);
if (cw)
{
diff --git a/src/window.cpp b/src/window.cpp
index b0749ed..5bd5fd1 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1158,34 +1158,6 @@ CompWindow::updateStruts ()
return false;
}
-static void
-setDefaultWindowAttributes (XWindowAttributes *wa)
-{
- wa->x = 0;
- wa->y = 0;
- wa->width = 1;
- wa->height = 1;
- wa->border_width = 0;
- wa->depth = 0;
- wa->visual = NULL;
- wa->root = None;
- wa->c_class = InputOnly;
- wa->bit_gravity = NorthWestGravity;
- wa->win_gravity = NorthWestGravity;
- wa->backing_store = NotUseful;
- wa->backing_planes = 0;
- wa->backing_pixel = 0;
- wa->save_under = false;
- wa->colormap = None;
- wa->map_installed = false;
- wa->map_state = IsUnviewable;
- wa->all_event_masks = 0;
- wa->your_event_mask = 0;
- wa->do_not_propagate_mask = 0;
- wa->override_redirect = true;
- wa->screen = NULL;
-}
-
void
CompWindow::incrementDestroyReference ()
{
@@ -5136,19 +5108,14 @@ CoreWindow::manage (Window aboveId)
* care about them too)
*/
-CoreWindow::CoreWindow (Window id)
+CoreWindow::CoreWindow (Window id, XWindowAttributes &wa)
{
priv = new PrivateWindow (this);
assert (priv);
screen->priv->createdWindows.push_back (this);
- /* Failure means that window has been destroyed. We still have to add the
- window to the window list as we might get configure requests which
- require us to stack other windows relative to it. Setting some default
- values if this is the case. */
- if (!XGetWindowAttributes (screen->dpy (), id, &priv->attrib))
- setDefaultWindowAttributes (&priv->attrib);
+ priv->attrib = wa;
priv->serverGeometry.set (priv->attrib.x, priv->attrib.y,
priv->attrib.width, priv->attrib.height,