Ubuntu – Maximize windows to physical screen when using a virtual resolution w/xrandr


I have a netbook with a small screen in widescreen format (1024×600), which means that a lot of programs whose designers didn't imagine such a thing open windows that can't be resized and whose bottoms are obscured. Through Ubuntu 10.04, I took care of it with an xrandr command:

xrandr --output LVDS1 --fb 1024x768 --panning 0x768

(note the 0x) which had the effect of giving me a normal-sized virtual desktop that panned vertically, but which (somehow) the window manager ignored, so maximized windows only occupied the physical screen. The result was that I didn't have to pan unless a large dialog box popped up: nice.

In 11.04, this doesn't quite work. Everything I said above is true, but the bottom 168 pixels seem permanently blackened, so that if a large window extends down there I can't see what's in it (however, it is there: the resize handles appear, and are useful on those occasions that resizing is allowed). I imagine this is Unity-related. That defeats the purpose, so I'm trying this xrandr command:

xrandr --output LVDS1 --fb 1024x768 --panning 1024x768

(note the 1024x). Alas, it does not trick the window manager anymore, and maximized windows all go off the bottom. Question:

How do I set things up so that a "maximized" window takes up only the physical screen (or more generally, takes up a particular piece of screen)?

A related question I'd be happy to have answered instead is:

Why does the first xrandr command fool the window manager (the "0x" means, according to the man page, that panning along the horizontal axis is disabled; functionally, this is meaningless since the virtual size is the same as the physical size)? What goes wrong with Unity?

Note that the "maximize" action is necessary, since in Unity, a maximized window is styled differently: its titlebar is absorbed into the toolbar at the top of the screen, saving valuable pixels for me. Simply resizing a window is not a good alternative.


I found this question: I'd like to prevent maximize from covering one third of the screen. I was very disappointed when Compiz Maximumize appeared to do nothing at all (there's a Launchpad bug: https://bugs.launchpad.net/ubuntu/+source/compiz-fusion-plugins-extra/+bug/462158).

I also found the same question on superuser: https://superuser.com/questions/269966/id-like-to-prevent-maximize-from-covering-one-third-of-the-screen, which offers two alternatives. The Compiz Grid plugin doesn't help because it doesn't maximize, as I described above. I have not tried the Python window organizer, but it looks similar to Grid. In general I don't expect that clever scripts will help, because the meaning of "maximize" is controlled by the window manager itself, and so the solution should be a Compiz solution. Is there one?

Best Answer

Let me answer my own question; the answer is bizarrely involved. The trick is that the desired desktop behavior (which held in 10.04) is now (in 11.04) controlled by Compiz, which has a notion of "outputs": that is, screens to draw on. These are configured in the CompizConfig Settings Manager (package compizconfig-backend-gconf or -kconfig), in the "general options" menu, under the "Display Settings" tab.

This thing has three settings, all of which are important. The most important is "Detect outputs": that must be unchecked, because the whole point is that I want to create an unphysical screen setup, whereas autodetection will just pick up the size of my screen.

The second most important is the "Outputs" box, which is a list of resolutions. At first glance you may expect that the thing to put in here is "1024x768", but that's wrong: it tells Compiz to use the whole virtual screen, so maximized windows will flow into the bottom; that's the wrong behavior. But writing "1024x600" doesn't work either, since that will tell Compiz to pretend that the screen is only 600 pixels high; the counterintuitive result is therefore it decides to stretch every window. This is ugly and also nonfunctional, causing amazing graphical glitches and, mysteriously, displacing buttons from the place you need to click to activate them. Not good.

A much better option is to write "1024x600+0-168", which tells Compiz that there are actually 168 unused pixels on the bottom: that reproduces the "black bar" behavior I was complaining about. It's good to know where that comes from, but I still don't want it. But it tells me what it means: it means that Compiz is simply ignoring those pixels: it won't draw windows there. My mouse still goes there, though, because that behavior is controlled by X, which comes before Compiz. It seems that the thing to do is somehow tell Compiz to draw there (so windows can go there) but also not to draw there (so they don't want to go there).

The totally correct solution is therefore to describe two output devices to Compiz: one "1024x600+0-168", and one "1024x768", thus telling Compiz to draw and not draw on those bottom pixels, at the same time. But how to make sure it knows which one to "want"? That's the first option in this tab: "Overlapping Output Handler". Set it to "Prefer smaller output", which is exactly what I said in words up there.

So the answer: run xrandr --mode 1024x700 --fb 1024x768 --panning 0x768; go to Compiz' display options and put in two outputs "1024x600+0-168" and "1024x768"; uncheck "Detect Outputs"; and make "Overlapping Output Handler" prefer smaller outputs. Whew.

Related Question