Display topology gets lost during disconnect / reconnect #35

Closed
opened 2026-10-06 06:03:40 +02:00 by enrico_badgerr · 2 comments

Software configuration
Budgie 10.10.3
Budgie Desktop Services 1.0.3
Labwc
Fedora 44

Hardware configuration
Lenovo ThinkPad with built-in display and an external display connected through HDMI/DisplayPort.

What happens

I have my display topology configured with the external monitor on the left and the laptop's built-in display on the right:

$ wlr-randr | grep -E '^(DP|eDP)|Position'
DP-2 "External (DP-2 via HDMI)"
  Position: 0,0
eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)"
  Position: 2560,0

If I disconnect the external monitor, the built-in display retains its previous absolute position:

eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)"
  Position: 2560,0

If I then reconnect the external monitor, I end up with:

$ wlr-randr | grep -E '^(DP|eDP)|Position'
DP-2 "External (DP-2 via HDMI)"
  Position: 4480,0
eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)"
  Position: 2560,0

The saved Budgie display configuration still contains the correct original topology, so it does not appear that the saved configuration itself has been lost.

As a control experiment, if I disconnect DP-2 and manually move eDP-1 to 0,0:

wlr-randr --output eDP-1 --pos 0,0
then reconnect DP-2, DP-2 appears at 1920,0. This suggests Labwc is placing a newly connected output immediately to the right of the currently active output(s), and Budgie Desktop Services is not subsequently restoring the saved two-display topology.

I threw some ChatGPT at the source code. I have not tested or verified this diagnosis, so use it at your own peril.


Its observation was that the machinery for restoring a saved group appears to exist, but configuration application seems to be tied to initial output-manager readiness rather than subsequent topology changes.

In particular, the startup path connects bd::Outputs::State::ready to bd::Config::Outputs::State::apply(), while the output-added/output-removed paths appear to call checkAndEmitSignals() without subsequently applying the newly matching saved group.

There may also be an interaction with shim mode: checkAndEmitSignals() updates the active configuration from the compositor heads and saves it. If that path runs during hotplug, it potentially treats the compositor's provisional hotplug layout as configuration state rather than restoring the persisted topology.

I have not established what the correct fix is. In particular, simply calling apply() from the head-added callback may be wrong because the output-manager state may not yet be complete. Applying the matching configuration after the corresponding output-manager done event may be more appropriate.

**Software configuration** Budgie 10.10.3 Budgie Desktop Services 1.0.3 Labwc Fedora 44 **Hardware configuration** Lenovo ThinkPad with built-in display and an external display connected through HDMI/DisplayPort. What happens I have my display topology configured with the external monitor on the left and the laptop's built-in display on the right: ``` $ wlr-randr | grep -E '^(DP|eDP)|Position' DP-2 "External (DP-2 via HDMI)" Position: 0,0 eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)" Position: 2560,0 ``` If I disconnect the external monitor, the built-in display retains its previous absolute position: ``` eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)" Position: 2560,0 ``` If I then reconnect the external monitor, I end up with: ``` $ wlr-randr | grep -E '^(DP|eDP)|Position' DP-2 "External (DP-2 via HDMI)" Position: 4480,0 eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)" Position: 2560,0 ``` The saved Budgie display configuration still contains the correct original topology, so it does not appear that the saved configuration itself has been lost. As a control experiment, if I disconnect DP-2 and manually move eDP-1 to 0,0: `wlr-randr --output eDP-1 --pos 0,0 ` then reconnect DP-2, DP-2 appears at 1920,0. This suggests Labwc is placing a newly connected output immediately to the right of the currently active output(s), and Budgie Desktop Services is not subsequently restoring the saved two-display topology. I threw some ChatGPT at the source code. I have not tested or verified this diagnosis, so use it at your own peril. --- Its observation was that the machinery for restoring a saved group appears to exist, but configuration application seems to be tied to initial output-manager readiness rather than subsequent topology changes. In particular, the startup path connects bd::Outputs::State::ready to bd::Config::Outputs::State::apply(), while the output-added/output-removed paths appear to call checkAndEmitSignals() without subsequently applying the newly matching saved group. There may also be an interaction with shim mode: checkAndEmitSignals() updates the active configuration from the compositor heads and saves it. If that path runs during hotplug, it potentially treats the compositor's provisional hotplug layout as configuration state rather than restoring the persisted topology. I have not established what the correct fix is. In particular, simply calling apply() from the head-added callback may be wrong because the output-manager state may not yet be complete. Applying the matching configuration after the corresponding output-manager done event may be more appropriate. ---
Author

I decided to ask Codex to debug through this, and it spat out this diff. In my limited local experimentation, it worked - I unplugged DP2, and eDP1 moved to 2560,0, but when I replugged DP2, everything went back where it belonged:

$ wlr-randr | grep -E '^(DP|eDP)|Position'
DP-2 "External (DP-2 via HDMI)"
  Position: 0,0
eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)"
  Position: 2560,0

I am not an expert in this area, so I can't quite tell how clean/good this diff is, but I thought I'd attach to the bug in case it is of any help in debugging this further

I decided to ask Codex to debug through this, and it spat out this diff. In my limited local experimentation, it worked - I unplugged DP2, and eDP1 moved to `2560,0`, but when I replugged DP2, everything went back where it belonged: ``` $ wlr-randr | grep -E '^(DP|eDP)|Position' DP-2 "External (DP-2 via HDMI)" Position: 0,0 eDP-1 "Lenovo Group Limited N160JCA-GT1 (eDP-1)" Position: 2560,0 ``` I am not an expert in this area, so I can't quite tell how clean/good this diff is, but I thought I'd attach to the bug in case it is of any help in debugging this further
Owner

I appreciate the effort, however all of this code is currently being re-architected, so going to close this.

Also we don't accept LLM generated code for Budgie 11 (which budgie-desktop-services is generally considered intended for). See our AI policy at https://docs.buddiesofbudgie.org/organization/ai-policy#budgie-11

While the code Codex generated is understandable enough, I'm trying to keep LLM usage isolated to B10 where possible for the purposes of B11.

Thanks again for the effort.

I appreciate the effort, however all of this code is currently being re-architected, so going to close this. Also we don't accept LLM generated code for Budgie 11 (which budgie-desktop-services is generally considered intended for). See our AI policy at https://docs.buddiesofbudgie.org/organization/ai-policy#budgie-11 While the code Codex generated is understandable enough, I'm trying to keep LLM usage isolated to B10 where possible for the purposes of B11. Thanks again for the effort.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
BuddiesOfBudgie/budgie-desktop-services#35
No description provided.