Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i3 dies if there are no available outputs. #926

Closed
i3bot opened this issue Jan 17, 2013 · 7 comments
Closed

i3 dies if there are no available outputs. #926

i3bot opened this issue Jan 17, 2013 · 7 comments
Assignees

Comments

@i3bot
Copy link

i3bot commented Jan 17, 2013

[Originally reported by cneumann@…]
(If I disable all outputs via xrandr, i3 dies with the message "No usable outputs available.". i3 should not die but wait until a now output appears.

@stapelberg
Copy link
Member

I agree that this would be more useful behavior, but it’s not in the cards unfortunately.

The added code complexity is by no means worth the effort. It’s not as simple as just looping and sleep()ing: When i3 disables an output, it needs to be able to put the existing windows somewhere and that usually is another output. We’d need a third place, e.g. yet another pseudo container, or an entirely separate data structure (bad idea), to place these windows.

Therefore, this ticket is closed wontfix until someone proposes a patch which is not too complex and has no evil side-effects.

I’d recommend to just never disable all outputs. Note that you can do multiple changes in a single xrandr(1) call, so there never is a need to actually disable all outputs.

@i3bot
Copy link
Author

i3bot commented Oct 22, 2013

[Original comment by netsuso]

The problem is that you can't always do multiple changes in a single xrandr execution, because of this: https://bugs.freedesktop.org/show_bug.cgi?id=29929

If you have 2 crtc, and you have two outputs enabled, if you try to disable both of them and at the same time activate a third one, it will fail because it won't find a free crtc (it tries to assign it first for the new output before unassigning the ones used by the other two outputs)

So you are forced to run a first xrandr to just disable one of the current outputs. But if they are no longer connected (typical situation when you undock a laptop), i3 will detect both outputs as disabled, and will die before the third output has time to be activated (no matter how fast you run the second xrandr)

I don't know if xrandr/RandR will be fixed at some point (that bug is 3 years old, though), but I don't see an easy workaround so i3 doesn't die in this situation...

@stapelberg
Copy link
Member

Replying to comment 2 by netsuso:

The problem is that you can't always do multiple changes in a single xrandr execution, because of this: https://bugs.freedesktop.org/show_bug.cgi?id=29929

If you have 2 crtc, and you have two outputs enabled, if you try to disable both of them and at the same time activate a third one, it will fail because it won't find a free crtc (it tries to assign it first for the new output before unassigning the ones used by the other two outputs)
I don’t really understand this yet. Can you give an example containing the xrandr output in each situation and the commands you run please?

@i3bot
Copy link
Author

i3bot commented Oct 28, 2013

[Original comment by netsuso]

Natürlich!

Initial situation, two monitors connected (DP-0, DP-1) and laptop panel disconnected:

$ xrandr
Screen 0: minimum 8 x 8, current 2970 x 1680, maximum 16384 x 16384
VGA-0 disconnected (normal left inverted right x axis y axis)
LVDS-0 connected (normal left inverted right x axis y axis)
   1600x900       60.0 +   40.1  
DP-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 518mm x 324mm
   1920x1200      60.0*+
   1600x1200      60.0  
   1280x1024      75.0     60.0  
   1152x864       75.0  
   1024x768       75.0     60.0  
   800x600        75.0     60.3  
   640x480        75.0     59.9  
DP-1 connected 1050x1680+1920+0 left (normal left inverted right x axis y axis) 474mm x 296mm
   1680x1050      59.9*+   60.0  
   1280x1024      75.0     60.0  
   1152x864       75.0  
   1024x768       75.0     60.0  
   800x600        75.0     60.3  
   640x480        75.0     59.9  
HDMI-0 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)

Trying to turn them both off and turn on the laptop display:

$ xrandr --verbose --output DP-0 --off --output DP-1 --off --output LVDS-0 --preferred --primary
xrandr: cannot find crtc for output LVDS-0

No matter whether I unplug the monitors before or after, no matter what I do with the --primary and no matter the order of arguments, it always return the same error, even with --dryrun!!

The situation after disconnecting both monitors is:

$ xrandr 
Screen 0: minimum 8 x 8, current 2970 x 1680, maximum 16384 x 16384
VGA-0 disconnected (normal left inverted right x axis y axis)
LVDS-0 connected (normal left inverted right x axis y axis)
   1600x900       60.0 +   40.1  
DP-0 disconnected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
DP-1 disconnected 1050x1680+1920+0 left (normal left inverted right x axis y axis) 0mm x 0mm
HDMI-0 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)
  1680x1050 (0x28d)  119.0MHz
        h: width  1680 start 1728 end 1760 total 1840 skew    0 clock   64.7KHz
        v: height 1050 start 1053 end 1059 total 1080           clock   59.9Hz
  1920x1200 (0x281)  154.0MHz
        h: width  1920 start 1968 end 2000 total 2080 skew    0 clock   74.0KHz
        v: height 1200 start 1203 end 1209 total 1235           clock   60.0Hz

As you see, monitors appear as disconnected but still with their original resolution, and still using both available crtcs.

So, as I explained, my only possibility now is explicitly turning off one of the monitors. This is the command and its output

$ xrandr --verbose --output DP-1 --off
crtc 1: disable
screen 0: 1920x1200 352x220 mm 138.55dpi

$ xrandr
Screen 0: minimum 8 x 8, current 1920 x 1200, maximum 16384 x 16384
VGA-0 disconnected (normal left inverted right x axis y axis)
LVDS-0 connected (normal left inverted right x axis y axis)
   1600x900       60.0 +   40.1  
DP-0 disconnected primary (normal left inverted right x axis y axis)
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-0 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)

At this point xrandr finally notices and frees both crtcs (although leaving the screen resolution at 1920x1200, which was the resolution of DP-0), but it's too late because this is the moment where i3 exits. On the Randr event it looks again at every output and notices that there's no available output (DP-0 is disconnected too), and it simply leaves.

I've been trying a patch that leaves the last remaining output as active and leaves all the workspaces there, just waiting for a new randr event that turns on some outputs so it can finally reassign them. For the moment it seems to work well, but I might be missing some uncovered situation here.

@stapelberg
Copy link
Member

Thanks for your detailed explanation of the issue.

Can you try the following after disconnecting your monitors please?

killall -SIGSTOP i3
xrandr --output DP-1 --off
xrandr --output LVDS-0 --auto
killall -SIGCONT i3

Does that work as expected?

@i3bot
Copy link
Author

i3bot commented Oct 30, 2013

[Original comment by netsuso]

Hahaha, very nice trick, I hadn't thought about it. But it works perfectly :) When I resume i3 it correctly detects the new LVDS-0 output and assigns all workspaces to it, which is exactly what was expected.

I don't know whether the problem with RandR will be addressed in the future, or whether it's worth applying the changes I suggested to i3 (i.e, leaving always at least one internally active output even if there's no one). But for the moment that trick solves my problem, so I'll leave it like that ;)

Thank you!!

@stapelberg
Copy link
Member

Replying to comment 6 by netsuso:

Hahaha, very nice trick, I hadn't thought about it. But it works perfectly :) When I resume i3 it correctly detects the new LVDS-0 output and assigns all workspaces to it, which is exactly what was expected.
Thanks for confirming.

So, the situation overall is a bit unfortunate, since ideally one would not need hacks like that. However, given that there is no sensible action for i3 other than to wait, I think this works quite nicely in that it makes the user very aware of what’s happening. It’s clear that it’s the user’s responsibility to SIGCONT i3 when appropriate, and we don’t need any code changes.

Additionally, this only affects a small number of users in the first place. So, I’ll consider this issue fixed with the workaround posted in #5, at least for now :).

tcatm pushed a commit to tcatm/i3 that referenced this issue Sep 14, 2015
This patch introduces a root output covering the root window. It is used
in two cases:

1. RandR is not available. In this case, the previous behaviour of
   creating a single output covering the root window is preserved.

2. RandR is available, but there is no active output. In this case,
   the root output is enabled and will be the only active output.
   If any RandR output becomes available, the root output will be
   disabled again. Existing mechanisms for migrating workspaces will
   just work without modification.

I've carefully slipped in a global variable `Output root_output` representing
that output. I'm not exactly happy with it, though. We could, by
convention, consider the first output in outputs to be the root output.
This would work because the root output will always be created before any
other output.

I also had to alter the `struct xoutput` a little by introducing a `bool
root`. This could be obsoleted by introducing the aforementioned convention,
too.

Fixes i3#926 and i3#1489
tcatm pushed a commit to tcatm/i3 that referenced this issue Sep 18, 2015
This patch introduces a root output covering the root window. It is used
in two cases:

1. RandR is not available. In this case, the previous behaviour of
   creating a single output covering the root window is preserved.

2. RandR is available, but there is no active output. In this case,
   the root output is enabled and will be the only active output.
   If any RandR output becomes available, the root output will be
   disabled again. Existing mechanisms for migrating workspaces will
   just work without modification.

I've carefully slipped in a global variable `Output root_output` representing
that output.

Fixes i3#926 and i3#1489
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants