Bug 249636

Summary: Switching between external monitors fails (DVI/VGA crtc issue)
Product: [Applications] systemsettings Reporter: Tim Holy <holy>
Component: kcm_randrAssignee: Gustavo Pichorim Boiko <gustavo.boiko>
Status: RESOLVED UNMAINTAINED    
Severity: normal CC: andresbajotierra, hbock, holy, ncoghlan
Priority: NOR    
Version: 0.2   
Target Milestone: ---   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: xrandr commands to switch to external monitors (order matters!)
xrandr commands to switch to internal monitor (order matters!)

Description Tim Holy 2010-08-31 16:01:20 UTC
Version:           0.2 (using KDE 4.5.0) 
OS:                Linux

Brief summary: this bug can be fixed if the configuration program executes the equivalent of
$ xrandr --output DVI-0 --off
on a disconnected DVI monitor before activating a new VGA monitor (and vice versa).

Slightly longer summary: if your laptop video card has only 2 crtcs (one of which is devoted to the laptop LVDS display), then switching between two different external monitors fails if one of them is connected with a digital (DVI) connector and the other uses a VGA connector. The problem is that xrandr does not automatically "free" the crtc devoted to whichever one you plugged in first, so there is no crtc available to drive the new monitor. However, if you explicitly turn that output off, then you can activate the second monitor. Currently the GUI does not support this, so it is necessary to go to the command line.

The discussion here:
https://bugs.freedesktop.org/show_bug.cgi?id=29852
indicates that it is undesirable for xrandr to automatically turn the disconnected output off, and that this is better handled by the GUI.

Reproducible: Always

Steps to Reproduce:
Here's my hardware:
Laptop: Thinkpad T60, with a 1400x1050 screen (4:3), ATI X1400 videocard
Home external monitor: Dell S2409W with 1920x1080 resolution (16:9), connected via VGA
Work external monitor: HP LP2065 with a 1600x1200 resolution (4:3), connected via DVI

Steps:
1. Start X with one external monitor connected.
2. Put laptop to sleep.
3. Connect laptop to different external monitor.
4. Wake laptop up.
5. Accept the suggestion to configure the new display.
6. The GUI pops up correctly identifying the modes of the new monitor. Set things up as you like them. Then click "apply".

Actual Results:  
Rather than implement the new settings and present the dialog that asks whether you want to accept the new settings or revert to the old ones, the GUI just grays out the Apply button without changing anything. The new monitor is not activated.

Work-around:
1. Go to the command line
2. Type "xrandr --auto". You will see the error
xrandr: cannot find crtc for output DVI-0
(or VGA-0 if that is the new monitor type), which explains the hiccup in the GUI.
3. Type "xrandr --output [connectiontype] --off", where [connectiontype] should be DVI or VGA depending on which type the first monitor was.
4. Go back to Systemsettings->Display and re-configure. This time it will work. 


Expected Results:  
It should have just activated the new monitor as requested, with requiring me to go to the command line. When one monitor is disconnected and a new one is detected, the appropriate calls to libxrandr should be made to ensure that the disconnected output is turned off before the new display is turned on.

OS: Linux (i686) release 2.6.35-19-generic
Compiler: cc
Maverick daily build 2010-08-26. However, I should say that this is a long-standing bug, present for me starting in Kubuntu Karmic.
Comment 1 Tim Holy 2010-09-01 11:44:21 UTC
I should also have pointed out that I reported more completely on issues involved in switching between external monitors (including a comparison between KDE and GNOME) here:
https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-ati/+bug/625220

This highlighted a couple of other bugs that are less severe than this one.
Comment 2 Tim Holy 2010-09-10 16:54:33 UTC
OK, I downloaded the source by doing this:
svn co svn://anonsvn.kde.org/home/kde/trunk/KDE/kdebase/workspace/kcontrol/randr
(I hope that is the current code)
and that helped me discover kdebugdialog. I am not yet quite to the point where I feel confident about supplying a patch, but I'm getting there... If you are too busy to fix it yourself, I could try, but I would certainly appreciate some guidance (see below).


I started out connected to my home monitor, then went into work, and at work I ran systemsettings from the command line with the kdebugdialog output on for systemsettings. Here was the output:
$ systemsettings &
[1] 8671
 systemsettings(8672)/kdecore (KSycoca) KSycocaPrivate::openDatabase: Trying to open ksycoca from  "/var/tmp/kdecache-tim/ksycoca4"
Bus::open: Can not get ibus-daemon's address. 
IBusInputContext::createInputContext: no connection to ibus-daemon 
systemsettings(8672)/kutils (KCModuleProxy) KCModuleProxyPrivate::loadModule: Module not already loaded, loading module  "Size & Orientation"  from library  "kcm_randr"  using symbol  "kcm_randr"
systemsettings(8672) RandRDisplay::RandRDisplay: Using XRANDR extension 1.2 or greater.
systemsettings(8672) RandRDisplay::RandRDisplay: XRANDR error base:  164
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 0 ("None")
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 79
systemsettings(8672) RandRCrtc::loadSettings: Querying information about CRTC 79
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 80
systemsettings(8672) RandRCrtc::loadSettings: Querying information about CRTC 80
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 81
systemsettings(8672) RandROutput::queryOutputInfo: XID 81 is output "VGA-0" (disconnected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 80 (enabled) on output "VGA-0"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "VGA-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 80
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 82
systemsettings(8672) RandROutput::queryOutputInfo: XID 82 is output "LVDS" (connected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 79 (enabled) on output "LVDS"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "LVDS" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo: Current configuration for output "LVDS" :
systemsettings(8672) RandROutput::queryOutputInfo:    - Refresh rate: 60.0197
systemsettings(8672) RandROutput::queryOutputInfo:    - Rect: QRect(0,0 1400x1050)
systemsettings(8672) RandROutput::queryOutputInfo:    - Rotation: 1
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 83
systemsettings(8672) RandROutput::queryOutputInfo: XID 83 is output "DVI-0" (connected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 0 (disabled) on output "DVI-0"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "DVI-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 80
systemsettings(8672) RandROutput::queryOutputInfo: Current configuration for output "DVI-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - Refresh rate: 0
systemsettings(8672) RandROutput::queryOutputInfo:    - Rect: QRect(0,0 0x0)
systemsettings(8672) RandROutput::queryOutputInfo:    - Rotation: 1
systemsettings(8672)/kutils (KCModuleProxy) KCModuleProxyPrivate::loadModule: Module not already loaded, loading module  "Multiple Monitors"  from library  "kcm_xinerama"  using symbol  "kcm_xinerama"
systemsettings(8672) KRandRModule::load: Loading KRandRModule...
systemsettings(8672) OutputConfig::load: Loading output configuration for "VGA-0"
systemsettings(8672) OutputConfig::load: Loading output configuration for "LVDS"
systemsettings(8672) RandRConfig::load: Output rect: QRect(0,0 1400x1050)
systemsettings(8672) OutputConfig::load: Loading output configuration for "DVI-0"
systemsettings(8672) RandRConfig::load: Output rect: QRect(0,0 0x0)
systemsettings(8672) RandRConfig::apply: Applying settings...
systemsettings(8672) RandRConfig::apply: Normalizing positions by QPoint(0,0)
systemsettings(8672) RandRConfig::apply: Ignoring identical config for "LVDS"
systemsettings(8672) RandRConfig::apply: Output config for "DVI-0" :
  rect = QRect(0,0 1600x1200) , rot = 1 , rate = 60
systemsettings(8672) RandROutput::slotEnable: Attempting to enable "DVI-0"
systemsettings(8672) RandROutput::slotEnable: Attempting to enable "DVI-0"
systemsettings(8672) RandROutput::slotEnable: Attempting to enable "DVI-0"
systemsettings(8672) RandRScreen::applyProposed: Applying proposed changes for screen 0 ...
systemsettings(8672) RandROutput::applyProposed: Applying proposed changes for output "DVI-0" ...
systemsettings(8672) RandRScreen::applyProposed: Changes have been applied to all outputs.
systemsettings(8672) RandRScreen::applyProposed: Changes canceled, reverting to original setup.

(About the "Changes canceled": I did not click "revert" in a dialog, in fact it never showed the dialog at all. Canceling appears to be instantaneous, and the Apply button merely gets grayed out. Note in particular the 3 successive messages, Attempting to enable "DVI-0".)

And after command-line intervention:
$ xrandr --output VGA-0 --off

systemsettings(8672)/kutils (KCModuleProxy) KCModuleProxyPrivate::loadModule: Module not already loaded, loading module  "Size & Orientation"  from library  "kcm_randr"  using symbol  "kcm_randr"
systemsettings(8672) RandRDisplay::RandRDisplay: Using XRANDR extension 1.2 or greater.
systemsettings(8672) RandRDisplay::RandRDisplay: XRANDR error base:  164
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 0 ("None")
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 79
systemsettings(8672) RandRCrtc::loadSettings: Querying information about CRTC 79
systemsettings(8672) RandRScreen::loadSettings: Creating CRTC object for XID 80
systemsettings(8672) RandRCrtc::loadSettings: Querying information about CRTC 80
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 81
systemsettings(8672) RandROutput::queryOutputInfo: XID 81 is output "VGA-0" (disconnected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 0 (disabled) on output "VGA-0"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "VGA-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 80
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 82
systemsettings(8672) RandROutput::queryOutputInfo: XID 82 is output "LVDS" (connected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 79 (enabled) on output "LVDS"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "LVDS" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo: Current configuration for output "LVDS" :
systemsettings(8672) RandROutput::queryOutputInfo:    - Refresh rate: 60.0197
systemsettings(8672) RandROutput::queryOutputInfo:    - Rect: QRect(0,0 1400x1050)
systemsettings(8672) RandROutput::queryOutputInfo:    - Rotation: 1
systemsettings(8672) RandRScreen::loadSettings: Creating output object for XID 83
systemsettings(8672) RandROutput::queryOutputInfo: XID 83 is output "DVI-0" (connected)
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 0 (disabled) on output "DVI-0"
systemsettings(8672) RandROutput::queryOutputInfo: Possible CRTCs for output "DVI-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 79
systemsettings(8672) RandROutput::queryOutputInfo:    - CRTC 80
systemsettings(8672) RandROutput::queryOutputInfo: Current configuration for output "DVI-0" :
systemsettings(8672) RandROutput::queryOutputInfo:    - Refresh rate: 0
systemsettings(8672) RandROutput::queryOutputInfo:    - Rect: QRect(0,0 0x0)
systemsettings(8672) RandROutput::queryOutputInfo:    - Rotation: 1
systemsettings(8672)/kutils (KCModuleProxy) KCModuleProxyPrivate::loadModule: Module not already loaded, loading module  "Multiple Monitors"  from library  "kcm_xinerama"  using symbol  "kcm_xinerama"
systemsettings(8672) KRandRModule::load: Loading KRandRModule...
systemsettings(8672) OutputConfig::load: Loading output configuration for "VGA-0"
systemsettings(8672) OutputConfig::load: Loading output configuration for "LVDS"
systemsettings(8672) RandRConfig::load: Output rect: QRect(0,0 1400x1050)
systemsettings(8672) OutputConfig::load: Loading output configuration for "DVI-0"
systemsettings(8672) RandRConfig::load: Output rect: QRect(0,0 0x0)
systemsettings(8672) RandRConfig::apply: Applying settings...
systemsettings(8672) RandRConfig::apply: Normalizing positions by QPoint(0,0)
systemsettings(8672) RandRConfig::apply: Ignoring identical config for "LVDS"
systemsettings(8672) RandRConfig::apply: Output config for "DVI-0" :
  rect = QRect(0,0 1600x1200) , rot = 1 , rate = 60
systemsettings(8672) RandROutput::slotEnable: Attempting to enable "DVI-0"
systemsettings(8672) RandROutput::setCrtc: Setting CRTC 80 (enabled) on output "DVI-0"
systemsettings(8672) RandRScreen::applyProposed: Applying proposed changes for screen 0 ...
systemsettings(8672) RandROutput::applyProposed: Applying proposed changes for output "DVI-0" ...
systemsettings(8672) RandROutput::tryCrtc: Trying to change output "DVI-0" to CRTC 80 ...
systemsettings(8672) RandRCrtc::applyProposed: Applying proposed changes for CRTC 80 ...
systemsettings(8672) RandRCrtc::applyProposed:        Current Screen rect: QRect(0,0 1400x1050)
systemsettings(8672) RandRCrtc::applyProposed:        Current CRTC rect: QRect(0,0 0x0)
systemsettings(8672) RandRCrtc::applyProposed:        Current rotation: 1
systemsettings(8672) RandRCrtc::applyProposed:        Proposed CRTC rect: QRect(0,0 1600x1200)
systemsettings(8672) RandRCrtc::applyProposed:        Proposed rotation: 1
systemsettings(8672) RandRCrtc::applyProposed:        Proposed refresh rate: 60
systemsettings(8672) RandRCrtc::applyProposed:        Enabled outputs:
systemsettings(8672) RandRCrtc::applyProposed:           - "DVI-0"
systemsettings(8672) RandRCrtc::applyProposed: Changes for CRTC 80 successfully applied.
systemsettings(8672) OutputConfig::outputChanged: Output "DVI-0" changed. ( mask = "4" )
systemsettings(8672) OutputConfig::outputChanged: Output mode changed.
systemsettings(8672) RandROutput::tryCrtc: Changed output "DVI-0" to CRTC 80
systemsettings(8672) RandROutput::tryCrtc:    ( from old CRTC 80 )
systemsettings(8672) RandRScreen::applyProposed: Changes have been applied to all outputs.

As far as I can tell, the problem must be that RandROutput::findEmptyCrtc() fails to return an empty crtc, I'd guess because because connectedOutputs().count() does not return 0 for CRTC 80---it's still enabled for VGA-0 even though it was listed as "disconnected" by loadSettings().

So it seems something should be done to update the connectedOutputs list and remove disconnected outputs before calling findEmptyCrtc; or, perhaps in findEmptyCrtc, if it can't find a non-zero crtc to return, it could do a second pass in which it checks for disconnected outputs. But the problem I see is that, if I understand correctly, all this happens within the object handling the DVI-0 output, and the problem is that it really needs to first get at the output handling VGA-0 to disable it. So I'm not sure where I should patch the problem.
Comment 3 Tim Holy 2010-09-10 17:01:38 UTC
Sorry, correction:
     was listed as "disconnected" by loadSettings()
should have been
     was listed as "disconnected" by queryOutputInfo()
I wonder if that is the right place to do the patch---just free the crtc of any disconnected output? Or does this get called even if the user wiggles the cable and the status changes transiently?
Comment 4 Tim Holy 2011-02-19 13:21:51 UTC
This is still a problem for me. And I'm not alone: do a google search:
        "xrandr: cannot find crtc for output" kubuntu
or
        "xrandr: cannot find crtc for output" KDE
and see how many hits you get. I think it merits marking this bug as confirmed. 

Just curious, is there someone who can at least tell me:
1. Should the fix be made within KDE, or is it an X problem (note Alex Deutcher suggests that it needs to be fixed in KDE, see the freedesktop.org bug report I linked to in the initial report)
2. If you're too busy right now to get to it, fine, but I'd at least like to know that you've read this report. I once even made the offer to fix it myself with some guidance (sadly, I am way too busy at the moment, and my command-line scripts work around the problem successfully), and I am surprised by the silence that has ensued.
Comment 5 Nick Coghlan 2011-07-20 03:35:48 UTC
Created attachment 62004 [details]
xrandr commands to switch to external monitors (order matters!)

The internal monitor must be disabled first to ensure channels are free for both external monitors
Comment 6 Nick Coghlan 2011-07-20 03:39:36 UTC
I can confirm this bug. I run dual external monitors from a T510 ThinkPad and the settings GUI can't handle the configuration properly due to the need to manage three monitors when the graphics card can only handle two at a time.

I'm attaching the scripts I use to ensure the monitors are configured appropriately.

I believe this bug is also at fault for KDE's failure to reenable the laptop screen when undocking, but I haven't investigated that aspect thoroughly.
Comment 7 Nick Coghlan 2011-07-20 03:49:28 UTC
Created attachment 62006 [details]
xrandr commands to switch to internal monitor (order matters!)

At least one of the external monitors must be disabled before the internal monitor can be reenabled. I've tried this config change through the GUI and the end result is to disable all 3 monitors (as it tries to enable the internal monitor first, which fails, but it then proceeds to disable the other two monitors regardless).
Comment 8 David Edmundson 2015-01-22 12:10:04 UTC
Thanks for reporting your bug.

Since reporting Krandr has since been replaced by KScreen. It is available in the Plasma 4 series, and is default in Plasma 5 onwards.

I hope this solves your issue. If you still have a problem after upgrading please reopen a new bug under kscreen.

Thanks