layout: fix crash in dwindle during config reload on monitor disconnect#13591
Open
brunojuliao wants to merge 2 commits intohyprwm:mainfrom
Open
layout: fix crash in dwindle during config reload on monitor disconnect#13591brunojuliao wants to merge 2 commits intohyprwm:mainfrom
brunojuliao wants to merge 2 commits intohyprwm:mainfrom
Conversation
When a monitor disconnects and a config reload is triggered (e.g. by hyprdynamicmonitors or any tool that rewrites monitor config files), updateWorkspaceLayouts() could crash with SEGV (bad_variant_access) inside CDwindleAlgorithm::newTarget(). Two issues contributed to this: 1. updateWorkspaceLayouts() did not skip inert workspaces. When a monitor disconnects, its workspaces become inert with their m_monitor reset to null. Processing these during a layout switchup leads to null dereferences in the tiled algorithm. 2. updateWorkspaceLayouts() compared the raw config layout name against registered algo names without resolving fallbacks. An unrecognized name (e.g. "default") falls back to "dwindle" when creating the algorithm, but the string comparison "dwindle" == "default" fails, causing a redundant layout switchup on every config reload. During monitor disconnect, this unnecessary switchup triggers the crash. Additionally, CDwindleAlgorithm::addTarget() now validates that both the workspace and its monitor are available before proceeding, and handles a null focused monitor gracefully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Hello and thank you for making a PR to Hyprland! Please check the PR Guidelines and make sure your PR follows them. If your code can be tested, please always add tests. See more here. beep boop, I'm just a bot. A real human will review your PR soon. |
Add integration tests that verify Hyprland does not crash when a config reload is triggered after a monitor disconnects with tiled windows. Covers both the direct crash path and the fallback layout name mismatch that caused redundant layout switchups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes a SEGV crash (
bad_variant_accessinCDwindleAlgorithm::newTarget()) that occurs when a config reload is triggered while a monitor is disconnecting. This commonly happens when tools like hyprdynamicmonitors rewritemonitors.confin response to a monitor hotplug event.How does it do it?
Three targeted changes across two files:
WorkspaceAlgoMatcher::updateWorkspaceLayouts()Skip inert workspaces: When a monitor disconnects, its workspaces become inert (
m_monitoris reset to null,m_idbecomesWORKSPACE_INVALID). The previous code only checked for null workspace pointers but did not checkinert(), leading to null dereferences when the layout algorithm tried to access the workspace's monitor.Resolve fallback layout names before comparison:
algoForNameTiled()falls back to"dwindle"for unrecognized layout names (e.g.,"default"), but the comparison inupdateWorkspaceLayouts()used the raw config string. This meant"dwindle" == "default"always failed, causing a redundant layout switchup on every config reload. During a monitor disconnect, this unnecessary switchup iterates all tiled targets on workspaces that may have stale monitor references, triggering the crash.CDwindleAlgorithm::addTarget()getFirstNode()instead of dereferencing null.How to reproduce the crash (before this fix)
general:layoutto a value that falls back to dwindle (e.g.,"default")Crash backtrace
Log tail
Tests
Added two
hyprtesterintegration tests inhyprtester/src/tests/main/monitorDisconnect.cpp:testCrashOnMonitorDisconnectReload— spawns tiled windows on a secondary headless monitor, removes the monitor, then triggers a config reload. Verifies Hyprland stays responsive and windows migrate to the remaining monitor.testCrashOnFallbackLayoutMonitorDisconnect— setsgeneral:layoutto an unrecognized name ("default") that falls back to dwindle, then removes a monitor and reloads. Verifies the fallback name resolution doesn't cause a crash during the layout switchup.Checklist
clang-formatctestpasses)