summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2008-11-26 10:40:22 +0100
committerDanny Baumann <dannybaumann@web.de>2008-11-26 10:40:22 +0100
commit60d1b5f9b03d9fb84b649f6f67d298375a0b3c17 (patch)
tree3de747e74d83706c0dffe6dddc9d27fffa7ac29e
parent21f418bc156dd105baf2882645ceb1e2c0ffe456 (diff)
Try to keep windows on their viewports on screen size changes.
-rw-r--r--plugins/place.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/plugins/place.c b/plugins/place.c
index 4dec9268..5bff58a5 100644
--- a/plugins/place.c
+++ b/plugins/place.c
@@ -32,6 +32,8 @@ static int displayPrivateIndex;
typedef struct _PlaceDisplay {
int screenPrivateIndex;
+
+ HandleEventProc handleEvent;
} PlaceDisplay;
#define PLACE_MODE_CASCADE 0
@@ -1453,6 +1455,95 @@ placePlaceWindow (CompWindow *w,
return TRUE;
}
+static void
+placeHandleScreenSizeChange (CompScreen *s,
+ int width,
+ int height)
+{
+ CompWindow *w;
+ int vpX, vpY, shiftX, shiftY;
+ XRectangle extents;
+ unsigned int mask;
+ XWindowChanges xwc;
+
+ for (w = s->windows; w; w = w->next)
+ {
+ if (!w->managed)
+ continue;
+
+ if (w->wmType & (CompWindowTypeDockMask |
+ CompWindowTypeDesktopMask))
+ continue;
+
+ mask = 0;
+ getWindowExtentsRect (w, &extents);
+
+ vpX = extents.x / s->width;
+ if (extents.x < 0)
+ vpX -= 1;
+ vpY = extents.y / s->height;
+ if (extents.y < 0)
+ vpY -= 1;
+
+ shiftX = vpX * (width - s->width);
+ shiftY = vpY * (height - s->height);
+
+ extents.x = extents.x % s->width;
+ if (extents.x < 0)
+ extents.x += s->width;
+ extents.y = extents.y % s->height;
+ if (extents.y < 0)
+ extents.y += s->height;
+
+ if (extents.x + extents.width > width)
+ shiftX += width - extents.x - extents.width;
+ if (extents.y + extents.height > height)
+ shiftY += height - extents.y - extents.height;
+
+ if (shiftX)
+ {
+ mask |= CWX;
+ xwc.x = w->serverX + shiftX;
+ }
+
+ if (shiftY)
+ {
+ mask |= CWY;
+ xwc.y = w->serverY + shiftY;
+ }
+
+ if (mask)
+ configureXWindow (w, mask, &xwc);
+ }
+}
+
+static void
+placeHandleEvent (CompDisplay *d,
+ XEvent *event)
+{
+ PLACE_DISPLAY (d);
+
+ switch (event->type) {
+ case ConfigureNotify:
+ {
+ CompScreen *s;
+
+ s = findScreenAtDisplay (d, event->xconfigure.window);
+ if (s)
+ placeHandleScreenSizeChange (s,
+ event->xconfigure.width,
+ event->xconfigure.height);
+ }
+ break;
+ default:
+ break;
+ }
+
+ UNWRAP (pd, d, handleEvent);
+ (*d->handleEvent) (d, event);
+ WRAP (pd, d, handleEvent, placeHandleEvent);
+}
+
static Bool
placeInitDisplay (CompPlugin *p,
CompDisplay *d)
@@ -1475,6 +1566,8 @@ placeInitDisplay (CompPlugin *p,
d->base.privates[displayPrivateIndex].ptr = pd;
+ WRAP (pd, d, handleEvent, placeHandleEvent);
+
return TRUE;
}
@@ -1484,6 +1577,8 @@ placeFiniDisplay (CompPlugin *p,
{
PLACE_DISPLAY (d);
+ UNWRAP (pd, d, handleEvent);
+
freeScreenPrivateIndex (d, pd->screenPrivateIndex);
free (pd);