diff --git a/hyprtester/src/tests/main/scroll.cpp b/hyprtester/src/tests/main/scroll.cpp index 5c8660060..c861738e7 100644 --- a/hyprtester/src/tests/main/scroll.cpp +++ b/hyprtester/src/tests/main/scroll.cpp @@ -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) { /* diff --git a/src/config/supplementary/propRefresher/PropRefresher.cpp b/src/config/supplementary/propRefresher/PropRefresher.cpp index a214b2a7f..837aa7677 100644 --- a/src/config/supplementary/propRefresher/PropRefresher.cpp +++ b/src/config/supplementary/propRefresher/PropRefresher.cpp @@ -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); } } diff --git a/src/layout/LayoutManager.hpp b/src/layout/LayoutManager.hpp index 1e509586f..bd8d31100 100644 --- a/src/layout/LayoutManager.hpp +++ b/src/layout/LayoutManager.hpp @@ -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, diff --git a/src/layout/space/Space.cpp b/src/layout/space/Space.cpp index 6c55c97bc..f05665db9 100644 --- a/src/layout/space/Space.cpp +++ b/src/layout/space/Space.cpp @@ -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 CSpace::getNextCandidate(SP 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>& 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; } } \ No newline at end of file diff --git a/src/layout/space/Space.hpp b/src/layout/space/Space.hpp index 1d0ea575f..ce0d1af76 100644 --- a/src/layout/space/Space.hpp +++ b/src/layout/space/Space.hpp @@ -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,