summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-05-04 16:01:54 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-05-04 16:01:54 +0800
commitb58ba91bbe2719c918e226cd5fe8044bc6b4c6ad (patch)
tree0e1afdfc11935da83db350f478157e7a0181a200 /src
parent32affe04818a82b884ef617bf319b0c9f2189cd9 (diff)
downloadmobileperf-b58ba91bbe2719c918e226cd5fe8044bc6b4c6ad.tar.gz
mobileperf-b58ba91bbe2719c918e226cd5fe8044bc6b4c6ad.tar.bz2
Restack docks primarily when the focus changes to support cases where we
change viewports and dock windows need to be restacked even though the window that we switched to wasn't restacked. Also support always-on-top and fullscreen windows.
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp2
-rw-r--r--src/privatewindow.h5
-rw-r--r--src/window.cpp126
3 files changed, 103 insertions, 30 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 1549964..329a8d9 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1848,7 +1848,7 @@ CompScreen::handleEvent (XEvent *event)
if (w->id () != priv->activeWindow)
{
- CompWindow *active = screen->findWindow (priv->activeWindow);
+ CompWindow *active = screen->findWindow (priv->activeWindow);
w->windowNotify (CompWindowNotifyFocusChange);
priv->activeWindow = w->id ();
diff --git a/src/privatewindow.h b/src/privatewindow.h
index bbbcb71..d1cf73c 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -82,6 +82,11 @@ class PrivateWindow {
void reconfigureXWindow (unsigned int valueMask,
XWindowChanges *xwc);
+ static bool stackDocks (CompWindow *w,
+ CompWindowList &updateList,
+ XWindowChanges *xwc,
+ unsigned int *mask);
+
static bool stackTransients (CompWindow *w,
CompWindow *avoid,
XWindowChanges *xwc,
diff --git a/src/window.cpp b/src/window.cpp
index d62a7f4..1575ec9 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2032,8 +2032,34 @@ CompWindow::moveInputFocusTo ()
}
if (setFocus)
+ {
+ CompWindowList dockWindows;
+ XWindowChanges xwc;
+ unsigned int mask;
+
screen->priv->nextActiveWindow = priv->id;
+ /* Ensure that docks are stacked in the right place
+ *
+ * When a normal window gets the focus and is above a
+ * fullscreen window, restack the docks to be above
+ * the highest level mapped and visible normal window,
+ * otherwise put them above the highest fullscreen window
+ */
+ if (PrivateWindow::stackDocks (this, dockWindows, &xwc, &mask))
+ {
+ Window sibling = xwc.sibling;
+ xwc.stack_mode = Above;
+
+ /* Then update the dock windows */
+ foreach (CompWindow *dw, dockWindows)
+ {
+ xwc.sibling = sibling;
+ dw->configureXWindow (mask, &xwc);
+ }
+ }
+ }
+
if (!setFocus && !modalTransient)
{
CompWindow *ancestor;
@@ -2480,6 +2506,63 @@ PrivateWindow::reconfigureXWindow (unsigned int valueMask,
}
bool
+PrivateWindow::stackDocks (CompWindow *w,
+ CompWindowList &updateList,
+ XWindowChanges *xwc,
+ unsigned int *mask)
+{
+ CompWindow *firstFullscreenWindow = NULL;
+ CompWindow *belowDocks = NULL;
+
+ foreach (CompWindow *dw, screen->windows ())
+ {
+ /* fullscreen window found */
+ if (firstFullscreenWindow)
+ {
+ if (dw->focus () &&
+ !PrivateWindow::isAncestorTo (w, dw) &&
+ !(dw->type () & (CompWindowTypeFullscreenMask |
+ CompWindowTypeDockMask)) &&
+ !dw->overrideRedirect () &&
+ dw->defaultViewport () == screen->vp ())
+ {
+ belowDocks = dw;
+ }
+ }
+ else if (dw->type () & CompWindowTypeFullscreenMask)
+ {
+ firstFullscreenWindow = dw;
+ for (CompWindow *dww = dw->prev; dww; dww = dww->prev)
+ {
+ if (!(dww->type () & (CompWindowTypeFullscreenMask |
+ CompWindowTypeDockMask) &&
+ !dww->overrideRedirect () &&
+ dww->defaultViewport () == screen->vp ()))
+ {
+ belowDocks = dww;
+ break;
+ }
+ }
+ }
+ }
+
+ if (belowDocks)
+ {
+ *mask = CWSibling | CWStackMode;
+ xwc->sibling = ROOTPARENT (belowDocks);
+
+ /* Collect all dock windows first */
+ foreach (CompWindow *dw, screen->windows ())
+ if (dw->priv->type & CompWindowTypeDockMask)
+ updateList.push_front (dw);
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
PrivateWindow::stackTransients (CompWindow *w,
CompWindow *avoid,
XWindowChanges *xwc,
@@ -2592,6 +2675,7 @@ CompWindow::configureXWindow (unsigned int valueMask,
{
CompWindowList transients;
CompWindowList ancestors;
+ CompWindowList docks;
/* Since the window list is being reordered in reconfigureXWindow
the list of windows which need to be restacked must be stored
@@ -2622,6 +2706,19 @@ CompWindow::configureXWindow (unsigned int valueMask,
(*w)->priv->reconfigureXWindow (CWSibling | CWStackMode, xwc);
xwc->sibling = ROOTPARENT (*w);
}
+
+ if (PrivateWindow::stackDocks (this, docks, xwc, &valueMask))
+ {
+ Window sibling = xwc->sibling;
+ xwc->stack_mode = Above;
+
+ /* Then update the dock windows */
+ foreach (CompWindow *dw, docks)
+ {
+ xwc->sibling = sibling;
+ dw->priv->reconfigureXWindow (valueMask, xwc);
+ }
+ }
}
}
else
@@ -3090,35 +3187,6 @@ PrivateWindow::addWindowStackChanges (XWindowChanges *xwc,
}
}
- if (sibling && mask)
- {
- /* a normal window can be stacked above fullscreen windows but we
- don't want normal windows to be stacked above dock window so if
- the sibling we're stacking above is a fullscreen window we also
- update all dock windows. */
- if ((sibling->priv->type & CompWindowTypeFullscreenMask) &&
- (!(type & (CompWindowTypeFullscreenMask |
- CompWindowTypeDockMask))) &&
- !isAncestorTo (window, sibling))
- {
- CompWindow *dw;
-
- for (dw = screen->windows ().back (); dw; dw = dw->prev)
- if (dw == sibling)
- break;
-
- /* Collect all dock windows first */
- CompWindowList dockWindows;
- for (; dw; dw = dw->prev)
- if (dw->priv->type & CompWindowTypeDockMask)
- dockWindows.push_back (dw);
-
- /* Then update the dock windows */
- foreach (CompWindow *dw, dockWindows)
- dw->configureXWindow (mask, xwc);
- }
- }
-
return mask;
}