[dev] [dwm] fix status bar cropping on screen resize

From: Mark Williams <markrwilliams_AT_gmail.com>
Date: Thu, 24 Feb 2011 17:22:03 -0800

Resizing the screen with xrandr -s/--size to a smaller resolution and
then calling it again to return to the previous resolution results in
dwm's status bar being cut off at the smaller width (e.g., the
following cuts the bar off at 640 pixels on my netbook: xrandr --size
640x480 && xrandr --size 1024x600).

The manpage for xrandr(1) makes it clear that this the RandR < 1.2 way
to do resizing. If you do it the >= 1.2 way the bar does not get cut
off (xrandr --output LVDS1 --mode 640x480 && xrandr --output LVDS1
--mode 1024x600); in fact, so long as you resize up with the newer
method the bar resizes ok. This is nice because if something like
dosbox resizes your screen and screws up your bar, you can resize down
and back and restore it.

Definitely an edge case, but it's happened to me enough times that
three possible fixes came to mind (listed in ascending preference):

1) Put a note in the BUGS section of the man page that mentions that
some screen resizes may result in a cropped status bar, and that it
can be fixed by resizing down and then back to your desired resolution
with the >= 1.2 command line.

2) The bar gets cut off because configurenotify() expects updategeom()
to return true only if the ConfigureEvent reports a change to the root
window's dimensions. While updategeom() does this correctly when
Xinerama isn't enabled (line 1851), the Xinerama code causes the
dc.drawable pixmap to get created on the basis of the wrong
ConfigureEvent (line 557). (Evidently the newer RandR resize method
results in a useful ConfigureEvent sooner than the older one.) One
solution would be to have the Xinerama code do the same check as the
non-Xinerama code. The first patch (fix_barcrop_checkwidth.diff)
provides a straightforward implementation of this.

3) Interestingly, the current code and the previous solution create a
dc.drawable pixmap that's as wide as the aggregate horizontal
resolution across all monitors. That makes sense for the non-Xinerama
code, where the bar stretches from monitor to monitor, but it doesn't
when each has its own bar. In the latter case the pixmap only has to
be as wide as the largest monitor's horizontal resolution. The second
patch (fix_barcrop_add_dw.diff) adds a new int to the DC struct, dw,
which is set to that and then used as the width argument in the
XCreatePixmap calls. This saves a negligible amount of memory and
also creates a pixmap of the right width regardless of how RandR
resizes the screen, because the Xinerama code gets geometries that
have accurate values even when the ConfigureEvent doesn't.

Even though this happens because of other people's weak code, I think
3 (or 2) is the best solution since dwm itself seems to be making some
incorrect assumptions; however, if the BUGS entry is the right
solution I'll be happy to write the explanation.


Received on Fri Feb 25 2011 - 02:22:03 CET

This archive was generated by hypermail 2.2.0 : Fri Feb 25 2011 - 02:24:02 CET