summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorerstarr <253168930+erstarr@users.noreply.github.com>2026-05-08 17:45:43 +0200
committerGitHub <noreply@github.com>2026-05-08 16:45:43 +0100
commitbd7f695363898826d5bd04fe830f19581ac4c5b2 (patch)
treea4dd157b8d851330035b4b6184995fb4ebd9d277 /src/layout
parentac75bcab713490eb000e4fa48f7e7316c3535854 (diff)
algo/scrolling: various scrolling view related bugfixes (#13974)
* fix scrolling view move when a grouped window is closed - prevent redundant space assignment for a grouped window that's about to be unmapped, add a `FOCUS_REASON` for unmapping grouped windows * fix focus_fallback after unmapping a window floating moving view * fix view change when changing workspaces (special and normal). add an optional `RECALCULATE_REASON` parameter to `recalculate()` calls of all algorithms. add an optional `RECALCULATE_MONITOR_REASON` parameter to `recalculateMonitor()` calls. add 2 new `FOCUS_REASON`s, for workspace change and special workspace toggle * Fix hyprctl keyword causing scrolling view move. rename INPUT_MODE_KB to INPUT_MODE_HARD since it seems to have little to do with keybinds * fix fullscreen/maximise moving the scrolling view * fix opening of layer 3 programs moving scrolling view * refactor, clean up and clang-format * fix bad decisions * fix includes, clang-format. * remove TODO * `focuswindow` no longer moves scrolling view when `follow_focus = 0` * fix: changes in a group's current window no longer casues scrolling view shift when `follow_focus = 0` * fix: `moveintogroup`, `movewindoworgroup` no longer causes scrolling view change if `follow_focus = 0` * clang-format * add `RECALCULATE_REASON_UNKNOWN`, `RECALCULATE_MONITOR_REASON_UNKNOWN`, `REMOVE_FROM_GROUP_REASON_UNKNOWN` remove optional wrapper from their enums, refactor code to work with the change * dispatches that call `switchtoWindow()` in CKeybindManager no longer cause scrolling view to move if `follow_focus = 0`. They still cause the move if `follow_focus = 1` Dispatches effected by this: `movefocus`, `cyclenext`, `focuscurrentorlast`, `focuscurrentorurgent` * Fix for Lua: switchToWondow * Fix for Lua: focus({window}) * Fix for Lua: Move Window Into Group * clang-format * Drop `hyprctl keyword` change * test: `focus({window})` with `follow_focus = false` * test: `focus({window})` with `follow_focus = true` * test: test Focus Fallback * test: Focus Fallback with groups * test: workspace change * test: special workspace toggle * test: workspace change - special to special also minor refactoring * test: close window in a group * test: move window into group `follow_focus = false` minor fix in test: expect -> assert * test: move window into group `follow_focus = true` * test: new layer * test: maximise fix in test: expect to assert. * test: fullscreen * test: `dispatch window.focus({ direction })` when `follow_focus = false` * test: `dispatch window.focus({ direction })` when `follow_focus = true` test-fix: expect -> assert * test: move focus within group when `follow_focus = false` * test: move focus within group when `follow_focus = true` * test-fix: kill all layers before killing all windows in layers test. prevents internal post test cleanup function failing to kill all layers test-fix: maximized and fullscreen swapped between their tests test-fix: testScrollingViewBehaviourMoveFocusInGroupFollowFocusTrue missing layout initialization test-fix: testScrollingViewBehaviourWorkspaceChange, testScrollingViewBehaviourCloseWindowInGroup have stale window class in a comment clang-format * catch up with main: move to new test function * clean-up the clean-up part of the tests: redundant * clang-format * pain * suffering: fix rebase fail * test: manually kill all layers since the cleanup function fails * remove test: fullscreen and maximise. scrolling has its own behaviour now
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/LayoutManager.cpp9
-rw-r--r--src/layout/LayoutManager.hpp9
-rw-r--r--src/layout/algorithm/Algorithm.cpp6
-rw-r--r--src/layout/algorithm/Algorithm.hpp3
-rw-r--r--src/layout/algorithm/FloatingAlgorithm.cpp2
-rw-r--r--src/layout/algorithm/FloatingAlgorithm.hpp2
-rw-r--r--src/layout/algorithm/ModeAlgorithm.hpp3
-rw-r--r--src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp2
-rw-r--r--src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp2
-rw-r--r--src/layout/algorithm/tiled/master/MasterAlgorithm.cpp2
-rw-r--r--src/layout/algorithm/tiled/master/MasterAlgorithm.hpp2
-rw-r--r--src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp2
-rw-r--r--src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp2
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp25
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp4
-rw-r--r--src/layout/space/Space.cpp21
-rw-r--r--src/layout/space/Space.hpp16
17 files changed, 83 insertions, 29 deletions
diff --git a/src/layout/LayoutManager.cpp b/src/layout/LayoutManager.cpp
index 875ae2ae..738a2286 100644
--- a/src/layout/LayoutManager.cpp
+++ b/src/layout/LayoutManager.cpp
@@ -334,18 +334,19 @@ void CLayoutManager::performSnap(Vector2D& sourcePos, Vector2D& sourceSize, SP<I
sourceSize = {sourceX.end - sourceX.start, sourceY.end - sourceY.start};
}
-void CLayoutManager::recalculateMonitor(PHLMONITOR m) {
+void CLayoutManager::recalculateMonitor(PHLMONITOR m, eRecalculateMonitorReason reason) {
if (m->m_activeSpecialWorkspace)
- m->m_activeSpecialWorkspace->m_space->recalculate();
+ m->m_activeSpecialWorkspace->m_space->recalculate(recalcMonitorReasonToRecalcReason(reason));
+
if (m->m_activeWorkspace)
- m->m_activeWorkspace->m_space->recalculate();
+ m->m_activeWorkspace->m_space->recalculate(recalcMonitorReasonToRecalcReason(reason));
}
void CLayoutManager::invalidateMonitorGeometries(PHLMONITOR m) {
for (const auto& ws : g_pCompositor->getWorkspaces()) {
if (ws && ws->m_monitor == m) {
ws->m_space->recheckWorkArea();
- ws->m_space->recalculate();
+ ws->m_space->recalculate(RECALCULATE_REASON_INVALIDATE_MONITOR_GEOMETRIES);
}
}
}
diff --git a/src/layout/LayoutManager.hpp b/src/layout/LayoutManager.hpp
index ef886daa..1e509586 100644
--- a/src/layout/LayoutManager.hpp
+++ b/src/layout/LayoutManager.hpp
@@ -50,6 +50,13 @@ namespace Layout {
CLayoutManager();
~CLayoutManager() = default;
+ enum eRecalculateMonitorReason : uint8_t {
+ RECALCULATE_MONITOR_REASON_UNKNOWN, // when the recalculate monitor reason is unknown or not important to preserve
+ RECALCULATE_MONITOR_REASON_WORKSPACE_CHANGE,
+ RECALCULATE_MONITOR_REASON_TOGGLE_SPECIAL_WORKSPACE,
+ RECALCULATE_MONITOR_REASON_TOGGLE_FULLSCREEN,
+ };
+
void newTarget(SP<ITarget> target, SP<CSpace> space);
void removeTarget(SP<ITarget> target);
@@ -81,7 +88,7 @@ namespace Layout {
void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, SP<ITarget> target, eMouseBindMode mode, int corner, const Vector2D& beginSize);
void invalidateMonitorGeometries(PHLMONITOR);
- void recalculateMonitor(PHLMONITOR);
+ void recalculateMonitor(PHLMONITOR, eRecalculateMonitorReason reason = RECALCULATE_MONITOR_REASON_UNKNOWN);
const UP<Supplementary::CDragStateController>& dragController();
diff --git a/src/layout/algorithm/Algorithm.cpp b/src/layout/algorithm/Algorithm.cpp
index ae96a7d8..3b3accc1 100644
--- a/src/layout/algorithm/Algorithm.cpp
+++ b/src/layout/algorithm/Algorithm.cpp
@@ -101,9 +101,9 @@ size_t CAlgorithm::floatingTargets() const {
return m_floatingTargets.size();
}
-void CAlgorithm::recalculate() {
- m_tiled->recalculate();
- m_floating->recalculate();
+void CAlgorithm::recalculate(eRecalculateReason reason) {
+ m_tiled->recalculate(reason);
+ m_floating->recalculate(reason);
const auto PWORKSPACE = m_space->workspace();
if (!PWORKSPACE)
diff --git a/src/layout/algorithm/Algorithm.hpp b/src/layout/algorithm/Algorithm.hpp
index 61c40285..c4a1d2e0 100644
--- a/src/layout/algorithm/Algorithm.hpp
+++ b/src/layout/algorithm/Algorithm.hpp
@@ -5,6 +5,7 @@
#include "../../helpers/memory/Memory.hpp"
#include "../LayoutManager.hpp"
+#include "../space/Space.hpp"
#include <expected>
#include <optional>
@@ -34,7 +35,7 @@ namespace Layout {
Config::ErrorResult layoutMsg(const std::string_view& sv);
std::optional<Vector2D> predictSizeForNewTiledTarget();
- void recalculate();
+ void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
void recenter(SP<ITarget> t);
void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
diff --git a/src/layout/algorithm/FloatingAlgorithm.cpp b/src/layout/algorithm/FloatingAlgorithm.cpp
index 058887bf..ed9d2c46 100644
--- a/src/layout/algorithm/FloatingAlgorithm.cpp
+++ b/src/layout/algorithm/FloatingAlgorithm.cpp
@@ -4,7 +4,7 @@
using namespace Layout;
-void IFloatingAlgorithm::recalculate() {
+void IFloatingAlgorithm::recalculate(eRecalculateReason reason) {
;
}
diff --git a/src/layout/algorithm/FloatingAlgorithm.hpp b/src/layout/algorithm/FloatingAlgorithm.hpp
index 40e53034..9232888d 100644
--- a/src/layout/algorithm/FloatingAlgorithm.hpp
+++ b/src/layout/algorithm/FloatingAlgorithm.hpp
@@ -22,7 +22,7 @@ namespace Layout {
virtual void recenter(SP<ITarget> t);
- virtual void recalculate();
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
protected:
IFloatingAlgorithm() = default;
diff --git a/src/layout/algorithm/ModeAlgorithm.hpp b/src/layout/algorithm/ModeAlgorithm.hpp
index 1348a6f4..cfbeafd3 100644
--- a/src/layout/algorithm/ModeAlgorithm.hpp
+++ b/src/layout/algorithm/ModeAlgorithm.hpp
@@ -5,6 +5,7 @@
#include "../../helpers/memory/Memory.hpp"
#include "../LayoutManager.hpp"
+#include "../space/Space.hpp"
#include <expected>
@@ -36,7 +37,7 @@ namespace Layout {
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE) = 0;
// recalculate layout
- virtual void recalculate() = 0;
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN) = 0;
// swap targets
virtual void swapTargets(SP<ITarget> a, SP<ITarget> b) = 0;
diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp
index 100856be..ff1b1b4f 100644
--- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp
+++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp
@@ -488,7 +488,7 @@ void CDwindleAlgorithm::swapTargets(SP<ITarget> a, SP<ITarget> b) {
nodeB->pTarget = a;
}
-void CDwindleAlgorithm::recalculate() {
+void CDwindleAlgorithm::recalculate(eRecalculateReason reason) {
calculateWorkspace();
}
diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp
index 300daa63..cf544089 100644
--- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp
+++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp
@@ -35,7 +35,7 @@ namespace Layout::Tiled {
virtual void removeTarget(SP<ITarget> target);
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
- virtual void recalculate();
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
virtual SP<ITarget> getNextCandidate(SP<ITarget> old);
diff --git a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp
index c57a3639..b4d4eea1 100644
--- a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp
+++ b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp
@@ -424,7 +424,7 @@ void CMasterAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir
}
}
-void CMasterAlgorithm::recalculate() {
+void CMasterAlgorithm::recalculate(eRecalculateReason reason) {
calculateWorkspace();
}
diff --git a/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp b/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp
index 00e82784..b29542c6 100644
--- a/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp
+++ b/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp
@@ -53,7 +53,7 @@ namespace Layout::Tiled {
virtual void removeTarget(SP<ITarget> target);
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
- virtual void recalculate();
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
virtual SP<ITarget> getNextCandidate(SP<ITarget> old);
diff --git a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp
index 84b4f9e2..e619bf57 100644
--- a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp
+++ b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp
@@ -125,7 +125,7 @@ void CMonocleAlgorithm::resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRe
// monocle layout doesn't support manual resizing, all windows are fullscreen
}
-void CMonocleAlgorithm::recalculate() {
+void CMonocleAlgorithm::recalculate(eRecalculateReason reason) {
if (m_targetDatas.empty())
return;
diff --git a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp
index 3f07748b..072f9cf0 100644
--- a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp
+++ b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp
@@ -26,7 +26,7 @@ namespace Layout::Tiled {
virtual void removeTarget(SP<ITarget> target);
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
- virtual void recalculate();
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
virtual SP<ITarget> getNextCandidate(SP<ITarget> old);
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
index 613ebe19..842e5b85 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
@@ -601,7 +601,16 @@ CScrollingAlgorithm::CScrollingAlgorithm() {
if (!TARGET || TARGET->floating())
return;
- focusOnInput(TARGET, reason == Desktop::FOCUS_REASON_CLICK ? INPUT_MODE_CLICK : (Desktop::isHardInputFocusReason(reason) ? INPUT_MODE_KB : INPUT_MODE_SOFT));
+ // if follow_focus != 0, focuswindow always moves scrolling view
+ // if follow_focus != 0, change in a group's current window state always moves scrolling view
+ // if follow_focus != 0, moving a window into group via the corresponding dispatches `moveintogroup`, `movewindoworgroup` always moves scrolling view
+ // if follow_focus != 0, moving focus via dispatches that cause switching to a specific window via calling switchToWindow(), such as movefocus, cyclenext, focuscurrentor(last/urgent); always moves scrolling view
+ if (*PFOLLOW_FOCUS &&
+ (reason == Desktop::FOCUS_REASON_DISPATCH_FOCUSWINDOW || reason == Desktop::FOCUS_REASON_GROUP_CURRENT_WINDOW_CHANGE ||
+ reason == Desktop::FOCUS_REASON_DISPATCH_MOVEWINDOWINTOGROUP || reason == Desktop::FOCUS_REASON_SWITCH_TO_WINDOW_SOFT))
+ focusOnInput(TARGET, INPUT_MODE_HARD);
+ else
+ focusOnInput(TARGET, reason == Desktop::FOCUS_REASON_CLICK ? INPUT_MODE_CLICK : (Desktop::isHardInputFocusReason(reason) ? INPUT_MODE_HARD : INPUT_MODE_SOFT));
});
// Initialize default widths and direction
@@ -645,7 +654,7 @@ void CScrollingAlgorithm::focusOnInput(SP<ITarget> target, eInputMode input) {
}
// if we moved via non-kb, and it's fully visible, ignore
- if (m_scrollingData->visible(TARGETDATA->column.lock(), true) && input != INPUT_MODE_KB)
+ if (m_scrollingData->visible(TARGETDATA->column.lock(), true) && input != INPUT_MODE_HARD)
return;
static const auto PFITMETHOD = CConfigValue<Config::INTEGER>("scrolling:focus_fit_method");
@@ -867,7 +876,7 @@ void CScrollingAlgorithm::resizeTarget(const Vector2D& delta, SP<ITarget> target
m_scrollingData->recalculate(true);
}
-void CScrollingAlgorithm::recalculate() {
+void CScrollingAlgorithm::recalculate(eRecalculateReason reason) {
// guard against recalculation during transitional monitor states
// (e.g. monitor reconnecting after suspend where workspace/monitor may not be ready)
if (!m_parent || !m_parent->space() || !m_parent->space()->workspace() || !m_parent->space()->workspace()->m_monitor)
@@ -878,8 +887,14 @@ void CScrollingAlgorithm::recalculate() {
const auto TARGETDATA = dataFor(TARGET);
- if (TARGETDATA && !m_scrollingData->visible(TARGETDATA->column.lock(), true))
- focusOnInput(Desktop::focusState()->window()->layoutTarget(), INPUT_MODE_KB);
+ if (TARGETDATA && !m_scrollingData->visible(TARGETDATA->column.lock(), true)) {
+
+ /* guard against unwanted scrolling viewport moves - If recalculate() was called, it is assumed that either the INPUT_MODE will be HARD (i.e. it is meant to move the scrolling viewport) or
+ it is not meant to move the scrolling viewport.
+ (e.g. changing workspace to a scrolling layout workspace fits the focused window in that workspace into view) */
+ if (Layout::isHardRecalculateReason(reason))
+ focusOnInput(Desktop::focusState()->window()->layoutTarget(), INPUT_MODE_HARD);
+ }
}
m_scrollingData->recalculate();
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
index a7c64aa8..867b86e8 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
@@ -100,7 +100,7 @@ namespace Layout::Tiled {
virtual void removeTarget(SP<ITarget> target);
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
- virtual void recalculate();
+ virtual void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
virtual SP<ITarget> getNextCandidate(SP<ITarget> old);
@@ -131,7 +131,7 @@ namespace Layout::Tiled {
enum eInputMode : uint8_t {
INPUT_MODE_SOFT = 0,
INPUT_MODE_CLICK,
- INPUT_MODE_KB
+ INPUT_MODE_HARD
};
private:
diff --git a/src/layout/space/Space.cpp b/src/layout/space/Space.cpp
index 35741a14..f4785d76 100644
--- a/src/layout/space/Space.cpp
+++ b/src/layout/space/Space.cpp
@@ -146,11 +146,11 @@ SP<CAlgorithm> CSpace::algorithm() const {
return m_algorithm;
}
-void CSpace::recalculate() {
+void CSpace::recalculate(eRecalculateReason reason) {
recheckWorkArea();
if (m_algorithm)
- m_algorithm->recalculate();
+ m_algorithm->recalculate(reason);
}
eFullscreenRequestResult CSpace::setFullscreen(SP<ITarget> t, eFullscreenMode currentEffectiveMode, eFullscreenMode mode) {
@@ -173,7 +173,7 @@ eFullscreenRequestResult CSpace::setFullscreen(SP<ITarget> t, eFullscreenMode cu
if (mode == FSMODE_NONE && m_algorithm && t->floating())
m_algorithm->recenter(t);
- recalculate();
+ recalculate(RECALCULATE_REASON_TOGGLE_FULLSCREEN);
return REQUEST_RESULT;
}
@@ -218,6 +218,21 @@ SP<ITarget> CSpace::getNextCandidate(SP<ITarget> old) {
return !m_algorithm ? nullptr : m_algorithm->getNextCandidate(old);
}
+bool Layout::isHardRecalculateReason(eRecalculateReason reason) {
+ return reason != RECALCULATE_REASON_WORKSPACE_CHANGE && reason != RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE && reason != RECALCULATE_REASON_TOGGLE_FULLSCREEN &&
+ reason != RECALCULATE_REASON_INVALIDATE_MONITOR_GEOMETRIES && reason != RECALCULATE_REASON_RENDER_MOINTOR;
+}
+
const std::vector<WP<ITarget>>& CSpace::targets() const {
return m_targets;
}
+
+eRecalculateReason Layout::recalcMonitorReasonToRecalcReason(CLayoutManager::eRecalculateMonitorReason reason) {
+ // If eRecalculateMonitorReason doesn't have a eRecalculateReason pair, it'll return nullopt
+ switch (reason) {
+ case CLayoutManager::RECALCULATE_MONITOR_REASON_TOGGLE_SPECIAL_WORKSPACE: return RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE;
+ case CLayoutManager::RECALCULATE_MONITOR_REASON_WORKSPACE_CHANGE: return RECALCULATE_REASON_WORKSPACE_CHANGE;
+ case CLayoutManager::RECALCULATE_MONITOR_REASON_TOGGLE_FULLSCREEN: return RECALCULATE_REASON_TOGGLE_FULLSCREEN;
+ default: return RECALCULATE_REASON_UNKNOWN;
+ }
+} \ No newline at end of file
diff --git a/src/layout/space/Space.hpp b/src/layout/space/Space.hpp
index a42dd55c..af731a50 100644
--- a/src/layout/space/Space.hpp
+++ b/src/layout/space/Space.hpp
@@ -12,6 +12,18 @@
#include <expected>
namespace Layout {
+
+ enum eRecalculateReason : uint8_t {
+ RECALCULATE_REASON_UNKNOWN, // when the recalculate reason is unknown or not important to preserve
+ RECALCULATE_REASON_WORKSPACE_CHANGE,
+ RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE,
+ RECALCULATE_REASON_TOGGLE_FULLSCREEN,
+ RECALCULATE_REASON_INVALIDATE_MONITOR_GEOMETRIES,
+ RECALCULATE_REASON_RENDER_MOINTOR,
+ };
+
+ eRecalculateReason recalcMonitorReasonToRecalcReason(CLayoutManager::eRecalculateMonitorReason reason);
+
class ITarget;
class CAlgorithm;
@@ -34,7 +46,7 @@ namespace Layout {
void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent);
- void recalculate();
+ void recalculate(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN);
void toggleTargetFloating(SP<ITarget> t);
@@ -68,4 +80,6 @@ namespace Layout {
// for recalc
CHyprSignalListener m_geomUpdateCallback;
};
+
+ bool isHardRecalculateReason(eRecalculateReason reason);
};