Hi,

> Hiya Compiz list! I am a Linux UI dude for VMware as my day job and am
> working on improving things in Workstation and Player with regards to
> multiple monitors on Linux. Some of my colleagues worked with the
> xdg/wm-spec folks just earlier this year to get the
> _NET_WM_FULLSCREEN_MONITORS hint into the EWMH spec to address the
> needs applications have in needing to be both fullscreen and spanning
> multiple monitors at the same time. Previously, we had some hacks to
> get Window Managers to do this, but it was fragile and brittle to say
> the least. Anyway, _NET_WM_FULLSCREEN_MONITORS is the right solution
> and is very useful for client virtualization software such as VMware,
> and for any other apps that wish to go fullscreen and span more than
> one monitor (i.e. video players, etc.).
> 
> Long story short, last Friday, I had just pulled out a git clone of
> compiz and was getting ready to start looking at patching
> _NET_WM_FULLSCREEN_MONITORS into Compiz and I discovered that Danny
> Baumann had done just that literally the day before. WOOT! Thank you
> Danny!!!

You're welcome :)

> I spent some time Friday in using the simple test application that
> David Trowbridge wrote
> (http://bugzilla.gnome.org/attachment.cgi?id=122703) that exercises
> _NET_WM_FULLSCREEN_MONITORS as well as using the multiple monitor
> feature of Workstation and things look really good! So I just wanted
> to introduce myself, say THANK YOU to Danny for adding the new hint,
> and see if there's anything I can do to help with this hint. 

You can ;-)

- There's one reported regression: URL I will try to see what's
happening there (and if I can reproduce it at all), but if you have any
pointers, let me know.
- What the current compiz code does (which is similar to what kwin and
metacity do) is that the fullscreen rectangle is calculated as the
boundary box of all the specified monitors, no matter at which point
they were specified. Re-reading the spec I think this is not exactly
correct. The spec clearly states that the specified monitors specify
edges, not an arbitrary set. Attached is my take on fixing that and
bringing compiz' behaviour in accordance to the spec.
For an example, imagine a scenario with 2 monitors: a 1280x800 laptop
panel and a 1280x1024 external monitor. The resulting window sizes for
some specified monitor sets are as follows:
(monitor set: left/right/top/bottom - old code - new code)

0000 - 1280x800+0+0     - 1280x800+0+0
1111 - 1280x1024+1280+0 - 1280x1024+1280+0
0001 - 2560x1024+0+0    - 1280x1024+0+0
0100 - 2560x1024+0+0    - 2560x800+0+0
0101 - 2560x1024+0+0    - 2560x1024+0+0

You can also see the difference when trying the test tool with two
differently sized monitors. I think the new version makes much more
sense because it allows greater flexibility (e.g. a video player doesn't
want parts of its window offscreen) and it matches the spec much better.
I wanted to know about your opinion, though.

> Also, I'm not quite familiar with the Compiz release schedule yet...
> does anyone know what released Compiz version will have
> _NET_WM_FULLSCREEN_MONITORS in it and when that will happen? Is there
> any chance it can make it into the next released stable version?

If we can solve the regression above, I see no reason not to pick this
change into the 0.8 branch. I even think we _should_ pick it, because
some distros are likely to stay with 0.8 (once it's released) for a
while.

Regards,

Danny
>From 0816b5fd5e67d3a5a8fe4b4c9f3b24fec0111871 Mon Sep 17 00:00:00 2001
From: Danny Baumann <dannybaum...@web.de>
Date: Wed, 31 Dec 2008 13:01:29 +0100
Subject: [PATCH] Bring fullscreen rectangle calculation in line with EWMH.

---
 src/window.c |   73 +++++++++++++++++++++++++++++----------------------------
 1 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/src/window.c b/src/window.c
index 8ee080f..b65c54a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1359,54 +1359,55 @@ setWindowFullscreenMonitors (CompWindow               *w,
 {
     CompScreen  *s = w->screen;
     CompDisplay *d = s->display;
-    Region      region = NULL;
-    long        data[4];
+    Bool        hadFsMonitors = w->fullscreenMonitorsSet;
 
-    /* sanity check monitor numbers */
-    if (monitors->left >= s->nOutputDev || monitors->right  >= s->nOutputDev ||
-	monitors->top  >= s->nOutputDev || monitors->bottom >= s->nOutputDev)
+    w->fullscreenMonitorsSet = FALSE;
+
+    if (monitors                         &&
+	monitors->left   < s->nOutputDev &&
+	monitors->right  < s->nOutputDev &&
+	monitors->top    < s->nOutputDev &&
+	monitors->bottom < s->nOutputDev)
     {
-	monitors = NULL;
-    }
+	BOX fsBox;
 
-    if (monitors)
-	region = XCreateRegion ();
+	fsBox.x1 = s->outputDev[monitors->left].region.extents.x1;
+	fsBox.y1 = s->outputDev[monitors->top].region.extents.y1;
+	fsBox.x2 = s->outputDev[monitors->right].region.extents.x2;
+	fsBox.y2 = s->outputDev[monitors->bottom].region.extents.y2;
 
-    if (!monitors || !region)
-    {
-	if (w->fullscreenMonitorsSet)
+	if (fsBox.x1 < fsBox.x2 && fsBox.y1 < fsBox.y2)
 	{
-	    w->fullscreenMonitorsSet = FALSE;
-	    XDeleteProperty (d->display, w->id, d->wmFullscreenMonitorsAtom);
-	}
+	    w->fullscreenMonitorsSet = TRUE;
 
-	return;
+	    w->fullscreenMonitorRect.x      = fsBox.x1;
+	    w->fullscreenMonitorRect.y      = fsBox.y1;
+	    w->fullscreenMonitorRect.width  = fsBox.x2 - fsBox.x1;
+	    w->fullscreenMonitorRect.height = fsBox.y2 - fsBox.y1;
+	}
     }
 
-    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);
+    if (w->fullscreenMonitorsSet)
+    {
+	long data[4];
 
-    data[0] = monitors->top;
-    data[1] = monitors->bottom;
-    data[2] = monitors->left;
-    data[3] = monitors->right;
+	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);
+	XChangeProperty (d->display, w->id, d->wmFullscreenMonitorsAtom,
+			 XA_CARDINAL, 32, PropModeReplace,
+			 (unsigned char *) data, 4);
+    }
+    else if (hadFsMonitors)
+    {
+	XDeleteProperty (d->display, w->id, d->wmFullscreenMonitorsAtom);
+    }
 
     if (w->state & CompWindowStateFullscreenMask)
-	updateWindowAttributes (w, CompStackingUpdateModeNone);
+	if (w->fullscreenMonitorsSet || hadFsMonitors)
+	    updateWindowAttributes (w, CompStackingUpdateModeNone);
 }
 
 static void
-- 
1.6.0.6

_______________________________________________
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz

Reply via email to