summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/display.c5
-rw-r--r--src/event.c15
-rw-r--r--src/screen.c9
-rw-r--r--src/window.c87
4 files changed, 103 insertions, 13 deletions
diff --git a/src/display.c b/src/display.c
index dd4676e1..176f769f 100644
--- a/src/display.c
+++ b/src/display.c
@@ -2154,11 +2154,14 @@ addDisplay (const char *name)
d->wmDeleteWindowAtom = XInternAtom (dpy, "WM_DELETE_WINDOW", 0);
d->wmTakeFocusAtom = XInternAtom (dpy, "WM_TAKE_FOCUS", 0);
d->wmPingAtom = XInternAtom (dpy, "_NET_WM_PING", 0);
- d->wmSyncRequestAtom = XInternAtom (dpy, "_NET_WM_SYNC_REQUEST", 0);
+ d->wmSyncRequestAtom = XInternAtom (dpy, "_NET_WM_SYNC_REQUEST", 0);
d->wmSyncRequestCounterAtom =
XInternAtom (dpy, "_NET_WM_SYNC_REQUEST_COUNTER", 0);
+ d->wmFullscreenMonitorsAtom =
+ XInternAtom (dpy, "_NET_WM_FULLSCREEN_MONITORS", 0);
+
d->closeWindowAtom = XInternAtom (dpy, "_NET_CLOSE_WINDOW", 0);
d->wmMoveResizeAtom = XInternAtom (dpy, "_NET_WM_MOVERESIZE", 0);
d->moveResizeWindowAtom = XInternAtom (dpy, "_NET_MOVERESIZE_WINDOW", 0);
diff --git a/src/event.c b/src/event.c
index 1f34243b..76c4f06a 100644
--- a/src/event.c
+++ b/src/event.c
@@ -1971,6 +1971,21 @@ handleEvent (CompDisplay *d,
if (w)
setDesktopForWindow (w, event->xclient.data.l[0]);
}
+ else if (event->xclient.message_type == d->wmFullscreenMonitorsAtom)
+ {
+ w = findWindowAtDisplay (d, event->xclient.window);
+ if (w)
+ {
+ CompFullscreenMonitorSet monitors;
+
+ monitors.top = event->xclient.data.l[0];
+ monitors.bottom = event->xclient.data.l[1];
+ monitors.left = event->xclient.data.l[2];
+ monitors.right = event->xclient.data.l[3];
+
+ setWindowFullscreenMonitors (w, &monitors);
+ }
+ }
break;
case MappingNotify:
updateModifierMappings (d);
diff --git a/src/screen.c b/src/screen.c
index 5a463b27..b157ffe4 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -271,6 +271,7 @@ updateOutputDevices (CompScreen *s)
unsigned int width, height;
int x1, y1, x2, y2;
Region region;
+ CompWindow *w;
for (i = 0; i < list->nValue; i++)
{
@@ -373,6 +374,12 @@ updateOutputDevices (CompScreen *s)
setCurrentOutput (s, s->currentOutputDev);
+ /* clear out fullscreen monitor hints of all windows as
+ suggested on monitor layout changes in EWMH */
+ for (w = s->windows; w; w = w->next)
+ if (w->fullscreenMonitorsSet)
+ setWindowFullscreenMonitors (w, NULL);
+
updateWorkareaForScreen (s);
setDefaultViewport (s);
@@ -1199,6 +1206,8 @@ setSupported (CompScreen *s)
data[i++] = d->moveResizeWindowAtom;
data[i++] = d->restackWindowAtom;
+ data[i++] = d->wmFullscreenMonitorsAtom;
+
XChangeProperty (d->display, s->root, d->supportedAtom, XA_ATOM, 32,
PropModeReplace, (unsigned char *) data, i);
}
diff --git a/src/window.c b/src/window.c
index 0a217d2f..8ee080fa 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1353,6 +1353,62 @@ updateWindowOutputExtents (CompWindow *w)
}
}
+void
+setWindowFullscreenMonitors (CompWindow *w,
+ CompFullscreenMonitorSet *monitors)
+{
+ CompScreen *s = w->screen;
+ CompDisplay *d = s->display;
+ Region region = NULL;
+ long data[4];
+
+ /* sanity check monitor numbers */
+ if (monitors->left >= s->nOutputDev || monitors->right >= s->nOutputDev ||
+ monitors->top >= s->nOutputDev || monitors->bottom >= s->nOutputDev)
+ {
+ monitors = NULL;
+ }
+
+ if (monitors)
+ region = XCreateRegion ();
+
+ if (!monitors || !region)
+ {
+ if (w->fullscreenMonitorsSet)
+ {
+ w->fullscreenMonitorsSet = FALSE;
+ XDeleteProperty (d->display, w->id, d->wmFullscreenMonitorsAtom);
+ }
+
+ return;
+ }
+
+ XUnionRegion (region, &s->outputDev[monitors->top].region, region);
+ XUnionRegion (region, &s->outputDev[monitors->bottom].region, region);
+ XUnionRegion (region, &s->outputDev[monitors->left].region, region);
+ XUnionRegion (region, &s->outputDev[monitors->right].region, region);
+
+ w->fullscreenMonitorsSet = TRUE;
+ w->fullscreenMonitorRect.x = region->extents.x1;
+ w->fullscreenMonitorRect.y = region->extents.y1;
+ w->fullscreenMonitorRect.width = region->extents.x2 - region->extents.x1;
+ w->fullscreenMonitorRect.height = region->extents.y2 - region->extents.y1;
+
+ XDestroyRegion (region);
+
+ data[0] = monitors->top;
+ data[1] = monitors->bottom;
+ data[2] = monitors->left;
+ data[3] = monitors->right;
+
+ XChangeProperty (d->display, w->id, d->wmFullscreenMonitorsAtom,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 4);
+
+ if (w->state & CompWindowStateFullscreenMask)
+ updateWindowAttributes (w, CompStackingUpdateModeNone);
+}
+
static void
setWindowMatrix (CompWindow *w)
{
@@ -2046,7 +2102,8 @@ addWindow (CompScreen *screen,
w->closeRequests = 0;
w->lastCloseRequestTime = 0;
- w->overlayWindow = FALSE;
+ w->fullscreenMonitorsSet = FALSE;
+ w->overlayWindow = FALSE;
if (screen->windowPrivateLen)
{
@@ -3588,11 +3645,24 @@ addWindowSizeChanges (CompWindow *w,
{
saveWindowGeometry (w, CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
- xwc->width = w->screen->outputDev[output].width;
- xwc->height = w->screen->outputDev[output].height;
+ if (w->fullscreenMonitorsSet)
+ {
+ xwc->x = x + w->fullscreenMonitorRect.x;
+ xwc->y = y + w->fullscreenMonitorRect.y;
+ xwc->width = w->fullscreenMonitorRect.width;
+ xwc->height = w->fullscreenMonitorRect.height;
+ }
+ else
+ {
+ xwc->x = x + w->screen->outputDev[output].region.extents.x1;
+ xwc->y = y + w->screen->outputDev[output].region.extents.y1;
+ xwc->width = w->screen->outputDev[output].width;
+ xwc->height = w->screen->outputDev[output].height;
+ }
+
xwc->border_width = 0;
- mask |= CWWidth | CWHeight | CWBorderWidth;
+ mask |= CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
}
else
{
@@ -3657,14 +3727,7 @@ addWindowSizeChanges (CompWindow *w,
if (mask & (CWWidth | CWHeight))
{
- if (w->type & CompWindowTypeFullscreenMask)
- {
- xwc->x = x + w->screen->outputDev[output].region.extents.x1;
- xwc->y = y + w->screen->outputDev[output].region.extents.y1;
-
- mask |= CWX | CWY;
- }
- else
+ if (!(w->type & CompWindowTypeFullscreenMask))
{
int width, height, max;