Comment 8 for bug 82279

Revision history for this message
Anthony Fok (foka) wrote :

Hello,

I am personally affected by this bug, and so did my colleagues and clients, in feisty, gutsy and hardy. So, we finally found some time to look into it more deeply.

This bug is not very hardware specific. Our observation is that often tools like krandrtray, displayconfig-gtk, xrandr work, but displayconfig in kde-guidance does not. That hints at a software bug.

Our test configuration:

* Kubuntu 8.04 (i386)
* Intel Q35 chipset (display)
* SONY Trintron Multiscan E230 CRT Monitor

Test: Changing screen resolution using displayconfig from kde-guidance in non-administrator mode.

With that configuration, displayconfig shows the following available resolutions: 640x480, 720x400, 800x600, 832x624, 1024x768, 1280x960, 1280x1024, 1600x1200

However, we could only change to 640x480, 800x600 and 1024x768 directly.

Other resolutions didn't really work. Or did they? After changing from 1024x768 to, say, 1600x1200 (without manually setting the refresh rate), the screen stays at 1024x768 with the 15-second timeout pop-up box, but with the following error message in the console:

  X Error: BadValue (integer parameter out of range for operation) 2
    Major opcode: 156
    Minor opcode: 2
    Resource id: 0x4b

If I accept the resolution change, then kill X by Ctrl-Alt-Backspace, and re-login, X is in 1600x1200!

Indeed, a quick check of ~/.kde/share/config/displayconfigrc reviews that it has stored the setting of 1600x1200, and apparently /usr/bin/displayconfig-restore (called by /etc/X11/Xsession.d/40guidance-displayconfig_restore) is working!

Since both displayconfig and displayconfig-gtk use guidance-backend, and yet one works and another does not, we became convinced the bug is *not* in the backend, but somewhere in /usr/bin/displayconfig the frontend itself.

Running xf86misc.py shows the following:

=================================================================
Number of screens: 1
Idle seconds: 0.059

Gamma:(1.0, 1.0, 1.0)

SizeID:0
Size:(1024, 768, 312, 234)
Available Sizes:[(1024, 768, 312, 234), (1600, 1200, 312, 234), (1280, 1024, 312, 234), (1280, 960, 312, 234), (1152, 864, 312, 234), (832, 624, 312, 234), (800, 600, 312, 234), (640, 480, 312, 234), (720, 400, 312, 234)]

Rotation:1
Available Rotations:63

Refresh rate:75
Refresh rates for the current screen:[85, 75, 70, 60, 43]
All Refresh Rates:[85, 75, 70, 60, 43]
All Refresh Rates:[60]
All Refresh Rates:[75]
All Refresh Rates:[75]
All Refresh Rates:[85, 75]
All Refresh Rates:[75]
All Refresh Rates:[85, 72, 75, 60, 56]
All Refresh Rates:[85, 75, 73, 67, 60]
All Refresh Rates:[88, 70]
SizeID:0
Size:(1024, 768, 312, 234)
Available Sizes:[(1024, 768, 312, 234), (1600, 1200, 312, 234), (1280, 1024, 312, 234), (1280, 960, 312, 234), (1152, 864, 312, 234), (832, 624, 312, 234), (800, 600, 312, 234), (640, 480, 312, 234), (720, 400, 312, 234)]
=================================================================

The default resolution is 1024x768 @ 85 Hz.

After some debugging, it turns out that: when trying to change to 1600x1200, even though displayconfig shows "60 Hz" (the only valid refresh rate) selected in the combo box, upon clicking "Apply", displayconfig actually tried to set the resolution to 1600x1200 @ 85 Hz, and that's why the backend complained with an "X Error: BadValue (integer parameter out of range for operation)".

Finally, I arrived at _fillRefreshCombo() in displayconfig:

    def _fillRefreshCombo(self):
        # Update refresh combobox
        self.size_refresh_combo.clear()
        for rate in self.current_screen.getAvailableRefreshRates():
            self.size_refresh_combo.insertItem(i18n("%1 Hz").arg(rate))
        self.size_refresh_combo.setCurrentItem(self.current_screen.getRefreshRateIndex())

It got the correct refresh rate(s) for a certain resolution using self.current_screen.getAvailableRefreshRates(), but setRefreshRateIndex() is never called. Well, there was a signal-slot set up earlier in the code using

    self.connect(self.size_refresh_combo,SIGNAL("activated(int)"),self.slotRefreshRateChange)

But that is not helpful in this case, since the QComboBox::activated() signal "is not emitted if the item is changed programmatically, e.g. using setCurrentItem()" - http://doc.trolltech.com/3.3/qcombobox.html#activated

So, a manual call to setRefreshRateIndex() fixes the bug. A patch is attached (kubuntu_32_displayconfig_update_refresh_rate.patch). I have tested it on both hardy and feisty.

Hope this helps.

--
Anthony Fok
ThizLinux Software Co., Ltd.
Hong Kong - Shenzhen - Beijing, China