layout: fix crash on monitor reconnect due to stale workspace state

Guard against null/expired workspace and monitor pointers during layout recalculation triggered by arrangeMonitors after sleep/wake.
This commit is contained in:
matjam 2026-03-09 14:45:21 -07:00 committed by Vaxry
parent 470997f751
commit 48ac5b323a
Signed by: vaxry
GPG key ID: 665806380871D640
3 changed files with 18 additions and 3 deletions

View file

@ -105,7 +105,10 @@ void CAlgorithm::recalculate() {
m_floating->recalculate();
const auto PWORKSPACE = m_space->workspace();
const auto PMONITOR = PWORKSPACE->m_monitor;
if (!PWORKSPACE)
return;
const auto PMONITOR = PWORKSPACE->m_monitor;
if (PWORKSPACE->m_hasFullscreenWindow && PMONITOR) {
// massive hack from the fullscreen func

View file

@ -422,7 +422,8 @@ SP<SColumnData> SScrollingData::atCenter() {
}
void SScrollingData::recalculate(bool forceInstant) {
if (!algorithm->m_parent->space()->workspace() || algorithm->m_parent->space()->workspace()->m_hasFullscreenWindow)
if (!algorithm->m_parent || !algorithm->m_parent->space() || !algorithm->m_parent->space()->workspace() || !algorithm->m_parent->space()->workspace()->m_monitor ||
algorithm->m_parent->space()->workspace()->m_hasFullscreenWindow)
return;
static const auto PFSONONE = CConfigValue<Hyprlang::INT>("scrolling:fullscreen_on_one_column");
@ -1496,6 +1497,9 @@ eScrollDirection CScrollingAlgorithm::getDynamicDirection() {
}
CBox CScrollingAlgorithm::usableArea() {
if (!m_parent || !m_parent->space())
return {};
CBox box = m_parent->space()->workArea();
// doesn't matter, this happens when this algo is about to be destroyed

View file

@ -21,8 +21,16 @@ CSpace::CSpace(PHLWORKSPACE parent) : m_parent(parent) {
// NOLINTNEXTLINE
m_geomUpdateCallback = Event::bus()->m_events.monitor.layoutChanged.listen([this] {
// During monitor disconnect/reconnect (e.g. sleep/wake), some workspaces
// may have stale or null monitors. Guard against that to avoid crashing
// when recalculating layout for workspaces mid-migration.
if (!m_parent || !m_parent->m_monitor)
return;
recheckWorkArea();
m_algorithm->recalculate();
if (m_algorithm)
m_algorithm->recalculate();
});
}