layout/scrolling: fix prop refresh triggering hard input (#14594)

This commit is contained in:
erstarr
2026-05-25 18:15:08 +01:00
committed by GitHub
parent 457eb66dfb
commit bb3353f864
5 changed files with 59 additions and 6 deletions
+49
View File
@@ -1023,6 +1023,55 @@ TEST_CASE(testScrollingViewBehaviourMoveFocusInGroupFollowFocusTrue) {
}
}
TEST_CASE(testScrollingViewBehaviourScheduledPropRefresh) {
/*
Scheduled prop refresh must not move scrolling viewport.
The reason a prop refresh was queued is not saved, therefore it is not possible to clearly tell when and when not to move scrolling viewport
In this test, we test this by setting a workspace rule, which schedules a prop refresh
--------------------------------------------------------------------------------------------------------------------------------------
*/
OK(getFromSocket("r/eval hl.config({ general = { layout = 'scrolling' } })"));
// ensure variables are correctly set for the test
OK(getFromSocket("/eval hl.config({scrolling = {follow_focus = false}})"));
if (!Tests::spawnKitty("a")) {
FAIL_TEST("Could not spawn kitty with win class `a`");
return;
}
OK(getFromSocket("/dispatch hl.dsp.layout('colresize 0.8')"));
if (!Tests::spawnKitty("b")) {
FAIL_TEST("Could not spawn kitty with win class `b`");
return;
}
// since follow_focus = false, viewport does not move
OK(getFromSocket("/dispatch hl.dsp.focus({ window = 'class:a' })"));
// setting a workspace rule queues a doLater() call in the Event Loop Manager
OK(getFromSocket("/eval hl.workspace_rule({workspace = hl.get_active_workspace().id,gaps_in = 0})"));
// Check that the workspace rule is set
ASSERT_CONTAINS(getFromSocket("/workspacerules"), "gapsIn: 0 0 0 0");
// The viewport must not have moved: left corner cords of window should be < 0
const std::string currentWindowPos = Tests::getAttribute(getFromSocket("/activewindow"), "at");
const std::string currentWindowPosX = currentWindowPos.substr(0, currentWindowPos.find(','));
// test pass
if (std::stoi(currentWindowPosX) < 0) {
NLog ::log("{}Passed: {}window of class 'a' has negative x coordinates for its position: {}", Colors ::GREEN, Colors::RESET, currentWindowPosX);
}
// test fail
else {
FAIL_TEST("{}Failed: {}window of class 'a' does not have negative x coordinates for its position: {}", Colors::RED, Colors::RESET, currentWindowPosX);
}
}
TEST_CASE(testScrollInhibitor) {
/*
@@ -85,7 +85,7 @@ void CPropRefresher::scheduleRefresh(PropRefreshBits prop) {
if (!m)
continue;
g_layoutManager->recalculateMonitor(m);
g_layoutManager->recalculateMonitor(m, Layout::CLayoutManager::RECALCULATE_MONITOR_REASON_PROP_REFRESH);
}
g_pCompositor->ensurePersistentWorkspacesPresent();
@@ -95,7 +95,7 @@ void CPropRefresher::scheduleRefresh(PropRefreshBits prop) {
Layout::Supplementary::algoMatcher()->updateWorkspaceLayouts();
for (auto const& m : g_pCompositor->m_monitors) {
g_layoutManager->recalculateMonitor(m);
g_layoutManager->recalculateMonitor(m, Layout::CLayoutManager::RECALCULATE_MONITOR_REASON_PROP_REFRESH);
g_pHyprRenderer->damageMonitor(m);
}
}
+1
View File
@@ -52,6 +52,7 @@ namespace Layout {
enum eRecalculateMonitorReason : uint8_t {
RECALCULATE_MONITOR_REASON_UNKNOWN, // when the recalculate monitor reason is unknown or not important to preserve
RECALCULATE_MONITOR_REASON_PROP_REFRESH,
RECALCULATE_MONITOR_REASON_WORKSPACE_CHANGE,
RECALCULATE_MONITOR_REASON_TOGGLE_SPECIAL_WORKSPACE,
RECALCULATE_MONITOR_REASON_TOGGLE_FULLSCREEN,
+5 -4
View File
@@ -32,7 +32,7 @@ CSpace::CSpace(PHLWORKSPACE parent) : m_parent(parent) {
recheckWorkArea();
if (m_algorithm)
m_algorithm->recalculate();
m_algorithm->recalculate(RECALCULATE_REASON_CREATE_SPACE);
});
}
@@ -219,9 +219,9 @@ SP<ITarget> CSpace::getNextCandidate(SP<ITarget> old) {
}
bool Layout::isHardRecalculateReason(eRecalculateReason reason) {
return reason != RECALCULATE_REASON_WORKSPACE_CHANGE && reason != RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE &&
reason != RECALCULATE_REASON_TOGGLE_LAYOUT_HANDLED_FULLSCREEN && reason != RECALCULATE_REASON_TOGGLE_DEFAULT_HANDLED_FULLSCREEN &&
reason != RECALCULATE_REASON_INVALIDATE_MONITOR_GEOMETRIES && reason != RECALCULATE_REASON_RENDER_MOINTOR;
return reason != RECALCULATE_REASON_CREATE_SPACE && reason != RECALCULATE_REASON_PROP_REFRESH && reason != RECALCULATE_REASON_WORKSPACE_CHANGE &&
reason != RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE && reason != RECALCULATE_REASON_TOGGLE_LAYOUT_HANDLED_FULLSCREEN &&
reason != RECALCULATE_REASON_TOGGLE_DEFAULT_HANDLED_FULLSCREEN && reason != RECALCULATE_REASON_INVALIDATE_MONITOR_GEOMETRIES && reason != RECALCULATE_REASON_RENDER_MOINTOR;
}
const std::vector<WP<ITarget>>& CSpace::targets() const {
@@ -234,6 +234,7 @@ eRecalculateReason Layout::recalcMonitorReasonToRecalcReason(CLayoutManager::eRe
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_DEFAULT_HANDLED_FULLSCREEN;
case CLayoutManager::RECALCULATE_MONITOR_REASON_PROP_REFRESH: return RECALCULATE_REASON_PROP_REFRESH;
default: return RECALCULATE_REASON_UNKNOWN;
}
}
+2
View File
@@ -15,6 +15,8 @@ namespace Layout {
enum eRecalculateReason : uint8_t {
RECALCULATE_REASON_UNKNOWN, // when the recalculate reason is unknown or not important to preserve
RECALCULATE_REASON_PROP_REFRESH,
RECALCULATE_REASON_CREATE_SPACE,
RECALCULATE_REASON_WORKSPACE_CHANGE,
RECALCULATE_REASON_SPECIAL_WORKSPACE_TOGGLE,
RECALCULATE_REASON_TOGGLE_DEFAULT_HANDLED_FULLSCREEN,