diff --git a/src/layout/algorithm/Algorithm.cpp b/src/layout/algorithm/Algorithm.cpp index cfb5b7e39..b83a03a35 100644 --- a/src/layout/algorithm/Algorithm.cpp +++ b/src/layout/algorithm/Algorithm.cpp @@ -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 diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp index 4c093a1c3..58c8631ce 100644 --- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp +++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp @@ -422,7 +422,8 @@ SP 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("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 diff --git a/src/layout/space/Space.cpp b/src/layout/space/Space.cpp index db3925f6f..a02ba5173 100644 --- a/src/layout/space/Space.cpp +++ b/src/layout/space/Space.cpp @@ -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(); }); }