Package: icewm
Version: 1.2.35-1
Severity: normal
Tags: patch

When using icewm with an X Server with the RANDR extension but not the XINERAMA
extension RANDR resize events are not acted upon. This bug was introduced 
upstream in icewm-1.2.34. If you resize the screen on such a server the icewm
taskbar does not reposition and resize and icewm does not recognize that
the size of the screen has changed.

The bug was introduced when icewm-1.2.34 tried to improve support for XINERAMA.

See wmmgr.cc 

#ifdef CONFIG_XRANDR
void YWindowManager::handleRRScreenChangeNotify(const 
XRRScreenChangeNotifyEvent &xrrsc) {
#if RANDR_MAJOR >= 1
    XRRUpdateConfiguration((XEvent *)&xrrsc);
#endif

    int nw = DisplayWidth(xapp->display(), DefaultScreen(xapp->display()));
    int nh = DisplayHeight(xapp->display(), DefaultScreen(xapp->display()));
    updateXineramaInfo(nw, nh);

    if (width() != nw ||
        height() != nh)
    {

        MSG(("xrandr: %d %d",
             nw,
             nh));
        setSize(nw, nh);
        updateWorkArea();
#ifdef CONFIG_TASKBAR
        if (taskBar) {
            taskBar->relayout();
            taskBar->relayoutNow();
            taskBar->updateLocation();
        }
#endif
/// TODO #warning "make something better"
        wmapp->actionPerformed(actionArrange, 0);
    }
}
#endif

This function is called when there is an RANDR resize event. It checks if 
the new size of the screen is different from the current size, and if it 
is it fixes things up accordingly (like repositioning and resizing the 
taskbar). 

Now look at ywindow.cc 

void YDesktop::updateXineramaInfo(int &w, int &h) {
#ifdef XINERAMA
    xiHeads = 0;
    xiInfo = NULL;

    if (XineramaIsActive(xapp->display())) {
        xiInfo = XineramaQueryScreens(xapp->display(), &xiHeads);
        msg("xinerama: heads=%d", xiHeads);
        for (int i = 0; i < xiHeads; i++) {
            msg("xinerama: %d +%d+%d %dx%d",
                xiInfo[i].screen_number,
                xiInfo[i].x_org,
                xiInfo[i].y_org,
                xiInfo[i].width,
                xiInfo[i].height);
        }
    } else {
        xiHeads = 1;
        xiInfo = new XineramaScreenInfo[1];
        xiInfo[0].screen_number = 0;
        xiInfo[0].x_org = 0;
        xiInfo[0].y_org = 0;
        xiInfo[0].width = width();
        xiInfo[0].height = height();
    }
    w = xiInfo[0].width;
    h = xiInfo[0].height;
#endif
}

The problem here is that if the XINERAMA extension is not present it is 
retuning the current width and height of the desktop as icewm knows it. 
Which is incorrect when called from the RANDR resize handler as we want to 
know what the new size of the screen is (icewm hasn't resized itself yet).

I believe the following simple patch fixes the problem by setting the width
and height to values queried from the X Server when the XINERAMA extension is
not present.

diff -urNad icewm-1.2.35/src/ywindow.cc icewm-1.2.35x/src/ywindow.cc
--- icewm-1.2.35/src/ywindow.cc 2008-01-05 02:34:25.000000000 -0500
+++ icewm-1.2.35x/src/ywindow.cc        2009-04-24 09:22:09.000000000 -0400
@@ -1895,8 +1895,8 @@
         xiInfo[0].screen_number = 0;
         xiInfo[0].x_org = 0;
         xiInfo[0].y_org = 0;
-        xiInfo[0].width = width();
-        xiInfo[0].height = height();
+        xiInfo[0].width = DisplayWidth(xapp->display(), 
DefaultScreen(xapp->display()));
+        xiInfo[0].height = DisplayHeight(xapp->display(), 
DefaultScreen(xapp->display()));
     }
     w = xiInfo[0].width;
     h = xiInfo[0].height;


-- System Information:
Debian Release: 5.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.18-ovz-028stab053.5-smp (SMP w/8 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/bash
diff -urNad icewm-1.2.35/src/ywindow.cc icewm-1.2.35x/src/ywindow.cc
--- icewm-1.2.35/src/ywindow.cc	2008-01-05 02:34:25.000000000 -0500
+++ icewm-1.2.35x/src/ywindow.cc	2009-04-24 09:22:09.000000000 -0400
@@ -1895,8 +1895,8 @@
         xiInfo[0].screen_number = 0;
         xiInfo[0].x_org = 0;
         xiInfo[0].y_org = 0;
-        xiInfo[0].width = width();
-        xiInfo[0].height = height();
+        xiInfo[0].width = DisplayWidth(xapp->display(), DefaultScreen(xapp->display()));
+        xiInfo[0].height = DisplayHeight(xapp->display(), DefaultScreen(xapp->display()));
     }
     w = xiInfo[0].width;
     h = xiInfo[0].height;

Reply via email to