From a6a0cc308c827557d04cb3e4c3b5d258de0411e6 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Fri, 8 May 2026 15:00:38 +0100 Subject: [PATCH] desktop/workspace: fix visibility criteria matching (#14349) ref https://github.com/hyprwm/Hyprland/discussions/14233 --- hyprtester/pointer-scroll.txt | 7 +++++ hyprtester/src/tests/main/workspaces.cpp | 40 ++++++++++++++++++++++++ src/desktop/Workspace.cpp | 11 +++++-- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 hyprtester/pointer-scroll.txt diff --git a/hyprtester/pointer-scroll.txt b/hyprtester/pointer-scroll.txt new file mode 100644 index 000000000..081adbe14 --- /dev/null +++ b/hyprtester/pointer-scroll.txt @@ -0,0 +1,7 @@ + > binding to global: wl_seat (version 9) with id 1 + > binding to global: wl_compositor (version 6) with id 3 + > binding to global: wl_shm (version 2) with id 5 + > binding to global: xdg_wm_base (version 7) with id 37 +started +-1.00 +-1.00 diff --git a/hyprtester/src/tests/main/workspaces.cpp b/hyprtester/src/tests/main/workspaces.cpp index 8cde4914b..6cd187667 100644 --- a/hyprtester/src/tests/main/workspaces.cpp +++ b/hyprtester/src/tests/main/workspaces.cpp @@ -754,3 +754,43 @@ TEST_CASE(workspacesCombined) { NLog::log("{}Expecting 0 windows", Colors::YELLOW); ASSERT(Tests::windowCount(), 0); } + +TEST_CASE(workspacesFollowProperNoGaps) { + OK(getFromSocket("/dispatch hl.dsp.focus({ workspace = \"100\" })")); + OK(getFromSocket(R"#(/eval hl.workspace_rule({ workspace = "w[tv1]", gaps_out = 0, gaps_in = 0 }) + hl.workspace_rule({ workspace = "f[1]", gaps_out = 0, gaps_in = 0 }) + hl.window_rule({ + name = "no-gaps-wtv1", + match = { float = false, workspace = "w[tv1]" }, + border_size = 0, + rounding = 0, + }) + hl.window_rule({ + name = "no-gaps-f1", + match = { float = false, workspace = "f[1]" }, + border_size = 0, + rounding = 0, + }) + )#")); + + ASSERT(!!Tests::spawnKitty(), true); + + { + auto str = getFromSocket("/activewindow"); + ASSERT_CONTAINS(str, "size: 1920,1080"); + } + + ASSERT(!!Tests::spawnKitty(), true); + + OK(getFromSocket("/dispatch hl.dsp.window.move({ workspace = \"101\" })")); + + { + auto str = getFromSocket("/activewindow"); + ASSERT_CONTAINS(str, "size: 1920,1080"); + } + + { + auto str = getFromSocket("/activeworkspace"); + ASSERT_CONTAINS(str, "workspace ID 101 (101)"); + } +} diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 6ff6d0b4a..18f77a63a 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -16,6 +16,7 @@ #include #include using namespace Hyprutils::String; +using namespace Desktop::View; PHLWORKSPACE CWorkspace::create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special, bool isEmpty) { PHLWORKSPACE workspace = makeShared(id, monitor, name, special, isEmpty); @@ -436,11 +437,14 @@ int CWorkspace::getWindows(std::optional onlyTiled, std::optional on if (!t) continue; + const auto visibilityFulfilled = + t->window() && !t->window()->isHidden() && !t->window()->isInputBlocked(INPUT_BLOCK_GROUP_INACTIVE | INPUT_BLOCK_MONOCLE_INACTIVE | INPUT_BLOCK_BELOW_FULLSCREEN); + if (onlyTiled.has_value() && t->floating() == onlyTiled.value()) continue; if (onlyPinned.has_value() && (!t->window() || t->window()->m_pinned != onlyPinned.value())) continue; - if (onlyVisible.has_value() && (!t->window() || t->window()->targetVisible() != onlyVisible.value())) + if (onlyVisible.has_value() && (!t->window() || visibilityFulfilled != onlyVisible.value())) continue; no++; } @@ -453,13 +457,16 @@ int CWorkspace::getGroups(std::optional onlyTiled, std::optional onl for (auto const& g : Desktop::View::groups()) { const auto HEAD = g->head(); + const auto visibilityFulfilled = + g->current() && !g->current()->isHidden() && !g->current()->isInputBlocked(INPUT_BLOCK_GROUP_INACTIVE | INPUT_BLOCK_MONOCLE_INACTIVE | INPUT_BLOCK_BELOW_FULLSCREEN); + if (HEAD->workspaceID() != m_id || !HEAD->m_isMapped) continue; if (onlyTiled.has_value() && HEAD->m_isFloating == onlyTiled.value()) continue; if (onlyPinned.has_value() && HEAD->m_pinned != onlyPinned.value()) continue; - if (onlyVisible.has_value() && g->current()->targetVisible() != onlyVisible.value()) + if (onlyVisible.has_value() && visibilityFulfilled != onlyVisible.value()) continue; no++; }