summaryrefslogtreecommitdiff
path: root/src/screen.cpp
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2010-02-03 01:56:54 +0800
committerSam Spilsbury <smspillaz@gmail.com>2010-02-03 01:56:54 +0800
commitc0f0ddf1bb670a00f3c41e642e7aad0dcd7bc0c9 (patch)
tree4274432cb3c9289f5e9017fd129286e649acbc58 /src/screen.cpp
parenta8dbc7b20035c5108c38599e2e8d9449563d0622 (diff)
downloadunity-window-decorator-c0f0ddf1bb670a00f3c41e642e7aad0dcd7bc0c9.tar.gz
unity-window-decorator-c0f0ddf1bb670a00f3c41e642e7aad0dcd7bc0c9.tar.bz2
Fix inaccessible windows when reducing num. of viewports.
Forward port of 0b9c5efe8c2b6fe60780b8c3245b4aaa8ecdc943 to master
Diffstat (limited to 'src/screen.cpp')
-rw-r--r--src/screen.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/screen.cpp b/src/screen.cpp
index 0a85e87..f574fa4 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -1690,6 +1690,72 @@ PrivateScreen::setDesktopHints ()
void
PrivateScreen::setVirtualScreenSize (int newh, int newv)
{
+ /* if newh or newv is being reduced */
+ if (newh < screen->vpSize ().width () ||
+ newv < screen->vpSize ().height ())
+ {
+ CompWindow *w;
+ int tx = 0;
+ int ty = 0;
+
+ if (screen->vp ().x () >= newh)
+ tx = screen->vp ().x () - (newh - 1);
+ if (screen->vp ().y () >= newv)
+ ty = screen->vp ().y () - (newv - 1);
+
+ if (tx != 0 || ty != 0)
+ screen->moveViewport (tx, ty, TRUE);
+
+ /* Move windows that were in one of the deleted viewports into the
+ closest viewport */
+ foreach (CompWindow *w, screen->windows ())
+ {
+ int moveX = 0;
+ int moveY = 0;
+
+ if (w->onAllViewports ())
+ continue;
+
+ /* Find which viewport the (inner) window's top-left corner falls
+ in, and check if it's outside the new viewport horizontal and
+ vertical index range */
+ if (newh < screen->vpSize ().width ())
+ {
+ int vpX; /* x index of a window's vp */
+
+ vpX = w->serverX () / screen->width ();
+ if (w->serverX () < 0)
+ vpX -= 1;
+
+ vpX += screen->vp ().x (); /* Convert relative to absolute vp index */
+
+ /* Move windows too far right to left */
+ if (vpX >= newh)
+ moveX = ((newh - 1) - vpX) * screen->width ();
+ }
+ if (newv < screen->vpSize ().height ())
+ {
+ int vpY; /* y index of a window's vp */
+
+ vpY = w->serverY () / screen->height ();
+ if (w->serverY () < 0)
+ vpY -= 1;
+
+ vpY += screen->vp ().y (); /* Convert relative to absolute vp index */
+
+ /* Move windows too far right to left */
+ if (vpY >= newv)
+ moveY = ((newv - 1) - vpY) * screen->height ();
+ }
+
+ if (moveX != 0 || moveY != 0)
+ {
+ w->move (moveX, moveY, true);
+ w->syncPosition ();
+ }
+ }
+ }
+
vpSize.setWidth (newh);
vpSize.setHeight (newv);