summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-05-26 21:50:00 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-05-26 21:50:00 +0800
commita39f7e3307c0a5fa3423b1426610860e532529d7 (patch)
treeb8892f7d677a0e6a7d84fbb5b0bb79ad0097e1ee /src
parent3ea8ae7436af890ee82f1855e1a8ca4c6a76407f (diff)
downloadmobilebling-a39f7e3307c0a5fa3423b1426610860e532529d7.tar.gz
mobilebling-a39f7e3307c0a5fa3423b1426610860e532529d7.tar.bz2
XSync right after configureXWindow in cases where we
need to immediately reorder the window stack. This isn't a real fix, but at least fixes the following situation without breaking the API and ABI Windows stacked A, B, C Plugin does: C->raise (), B->raise (), A->raise () Window list should read at this point: ... C, B, A ... (screen->windows ()) However, the output buffer hasn't been flushed at this point so server side we will have A, B, C. Now if a sneaky client tries to restack A above C, we will get the ConfigureRequest for that, and instead of getting B, C, A like the client expects, we'll actually get C, B, A. The real solution is to have a list of windows last sent to the server and a list of windows last recieved by it. That way plugins can mess with the internal stack all they want, but when recieving events for X as to the actual state of things, they can restack relative to the server list.
Diffstat (limited to 'src')
-rw-r--r--src/window.cpp95
1 files changed, 72 insertions, 23 deletions
diff --git a/src/window.cpp b/src/window.cpp
index 4e222ab..f3a1402 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2413,19 +2413,6 @@ PrivateWindow::reconfigureXWindow (unsigned int valueMask,
if (valueMask & CWBorderWidth)
serverGeometry.setBorder (xwc->border_width);
- /* Compiz's window list is immediately restacked on reconfigureXWindow
- in order to ensure correct operation of the raise, lower and restacking
- functions. This function should only recieve stack_mode == Above
- but warn incase something else does get through, to make the cause
- of any potential misbehaviour obvious. */
- if (valueMask & (CWSibling | CWStackMode))
- {
- if (xwc->stack_mode == Above)
- restack (xwc->sibling);
- else
- compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
- }
-
if (frame)
{
XWindowChanges wc = *xwc;
@@ -2447,6 +2434,36 @@ PrivateWindow::reconfigureXWindow (unsigned int valueMask,
}
XConfigureWindow (screen->dpy (), id, valueMask, xwc);
+
+ /* Compiz's window list is immediately restacked on reconfigureXWindow
+ in order to ensure correct operation of the raise, lower and restacking
+ functions. This function should only recieve stack_mode == Above
+ but warn incase something else does get through, to make the cause
+ of any potential misbehaviour obvious. */
+ if (valueMask & (CWSibling | CWStackMode))
+ {
+ if (xwc->stack_mode == Above)
+ {
+ /* FIXME: We shouldn't need to sync here, however
+ * considering the fact that we are immediately
+ * restacking the windows, we need to ensure
+ * that when a client tries to restack a window
+ * relative to this window that the window
+ * actually goes where the client expects it to go
+ * and not anywhere else
+ *
+ * The real solution here is to have a list of windows
+ * last sent to server and a list of windows last
+ * received from server or to have a sync () function
+ * on the stack which looks through the last recieved
+ * window stack and the current window stack then
+ * sends the changes */
+ XSync (screen->dpy (), false);
+ restack (xwc->sibling);
+ }
+ else
+ compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
+ }
}
bool
@@ -3039,8 +3056,24 @@ PrivateWindow::addWindowStackChanges (XWindowChanges *xwc,
XLowerWindow (screen->dpy (), frame);
/* Restacking of compiz's window list happens
- immediately and since this path doesn't call
- reconfigureXWindow, restack must be called here. */
+ * immediately and since this path doesn't call
+ * reconfigureXWindow, restack must be called here.
+ *
+ * FIXME: We shouldn't need to sync here, however
+ * considering the fact that we are immediately
+ * restacking the windows, we need to ensure
+ * that when a client tries to restack a window
+ * relative to this window that the window
+ * actually goes where the client expects it to go
+ * and not anywhere else
+ *
+ * The real solution here is to have a list of windows
+ * last sent to server and a list of windows last
+ * received from server or to have a sync () function
+ * on the stack which looks through the last recieved
+ * window stack and the current window stack then
+ * sends the changes */
+ XSync (screen->dpy (), false);
restack (0);
}
else if (sibling->priv->id != window->prev->priv->id)
@@ -3330,6 +3363,14 @@ CompWindow::updateAttributes (CompStackingUpdateMode stackingMode)
mask |= priv->addWindowStackChanges (&xwc, sibling);
}
+ mask |= priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
+
+ if (priv->mapNum && (mask & (CWWidth | CWHeight)))
+ sendSyncRequest ();
+
+ if (mask)
+ configureXWindow (mask, &xwc);
+
if ((stackingMode == CompStackingUpdateModeInitialMap) ||
(stackingMode == CompStackingUpdateModeInitialMapDeniedFocus))
{
@@ -3340,18 +3381,26 @@ CompWindow::updateAttributes (CompStackingUpdateMode stackingMode)
it was created */
if (mask & CWStackMode)
{
+ /* FIXME: We shouldn't need to sync here, however
+ * considering the fact that we are immediately
+ * restacking the windows, we need to ensure
+ * that when a client tries to restack a window
+ * relative to this window that the window
+ * actually goes where the client expects it to go
+ * and not anywhere else
+ *
+ * The real solution here is to have a list of windows
+ * last sent to server and a list of windows last
+ * received from server or to have a sync () function
+ * on the stack which looks through the last recieved
+ * window stack and the current window stack then
+ * sends the changes */
+ XSync (screen->dpy (), false);
+
Window above = (mask & CWSibling) ? xwc.sibling : 0;
priv->restack (above);
}
}
-
- mask |= priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
-
- if (priv->mapNum && (mask & (CWWidth | CWHeight)))
- sendSyncRequest ();
-
- if (mask)
- configureXWindow (mask, &xwc);
}
void