diff --git a/hyprtester/src/tests/main/groups.cpp b/hyprtester/src/tests/main/groups.cpp index 57d6abd83..121472758 100644 --- a/hyprtester/src/tests/main/groups.cpp +++ b/hyprtester/src/tests/main/groups.cpp @@ -109,7 +109,15 @@ TEST_CASE(groups) { // disable the groupbar for ease of testing for now NLog::log("{}Disable groupbar", Colors::YELLOW); - OK(getFromSocket("r/eval hl.config({ group = { groupbar = { enabled = 0 } } })")); + OK(getFromSocket("/eval hl.config({ group = { groupbar = { enabled = 0 } } })")); + + // check the height of the window now + NLog::log("{}Recheck kitty dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/clients"); + EXPECT_CONTAINS(str, "at: 22,22"); + EXPECT_CONTAINS(str, "size: 1876,1036"); + } // kill all NLog::log("{}Kill windows", Colors::YELLOW); @@ -647,3 +655,75 @@ TEST_CASE(groupsLuaApiFullscreen) { Tests::killAllWindows(); ASSERT(Tests::windowCount(), 0); } + +TEST_CASE(groups_disable_when_only) { + ASSERT(Tests::windowCount(), 0); + + NLog::log("{}Testing disable_when_only ", Colors::YELLOW); + auto kittyA = Tests::spawnKitty("kittyA"); + if (!kittyA) { + FAIL_TEST("Could not spawn kitty"); + } + ASSERT(Tests::windowCount(), 1); + OK(getFromSocket("/dispatch hl.dsp.focus({ window = 'class:kittyA' })")); + + // check kitty properties. One kitty should take the entire screen, minus the gaps. + NLog::log("{}Check kittyA dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/activewindow"); + EXPECT_COUNT_STRING(str, "at: 22,22", 1); + EXPECT_COUNT_STRING(str, "size: 1876,1036", 1); + } + + OK(getFromSocket("/dispatch hl.dsp.group.toggle()")); + OK(getFromSocket("/eval hl.config({ group = { groupbar = { disable_when_only = true } } })")); + + // check kittyA properties. groupbar should be hidden due to disable_when_only + NLog::log("{}Check kittyA dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/activewindow"); + EXPECT_COUNT_STRING(str, "at: 22,22", 1); + EXPECT_COUNT_STRING(str, "size: 1876,1036", 1); + } + + auto kittyB = Tests::spawnKitty("kittyB"); + if (!kittyB) { + FAIL_TEST("Could not spawn kitty"); + } + ASSERT(Tests::windowCount(), 2); + OK(getFromSocket("/dispatch hl.dsp.focus({ window = 'class:kittyB' })")); + + // check kittyB properties. groupbar is visible + NLog::log("{}Check kittyB dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/activewindow"); + EXPECT_CONTAINS(str, "at: 22,43"); + EXPECT_COUNT_STRING(str, "size: 1876,1015", 1); + } + + OK(getFromSocket("/dispatch hl.dsp.window.kill()")); + Tests::waitUntilWindowsN(1); + ASSERT(Tests::windowCount(), 1); + OK(getFromSocket("/dispatch hl.dsp.focus({ window = 'class:kittyA' })")); + + // check kittyA properties. groupbar should be hidden due to disable_when_only + NLog::log("{}Check kittyA dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/activewindow"); + EXPECT_COUNT_STRING(str, "at: 22,22", 1); + EXPECT_COUNT_STRING(str, "size: 1876,1036", 1); + } + + OK(getFromSocket("/eval hl.config({ group = { groupbar = { disable_when_only = false } } })")); + + // check kittyA properties. groupbar should be visible due to disable_when_only == false + NLog::log("{}Check kittyA dimensions", Colors::YELLOW); + { + auto str = getFromSocket("/activewindow"); + EXPECT_COUNT_STRING(str, "at: 22,43", 1); + EXPECT_COUNT_STRING(str, "size: 1876,1015", 1); + } + + Tests::killAllWindows(); + ASSERT(Tests::windowCount(), 0); +} diff --git a/src/config/supplementary/propRefresher/PropRefresher.cpp b/src/config/supplementary/propRefresher/PropRefresher.cpp index 41c42cd7e..498bd105e 100644 --- a/src/config/supplementary/propRefresher/PropRefresher.cpp +++ b/src/config/supplementary/propRefresher/PropRefresher.cpp @@ -89,6 +89,9 @@ void CPropRefresher::refreshProp(const bool execdAsScheduled) { if (m_propsTripped & REFRESH_WINDOW_STATES) { Desktop::Rule::ruleEngine()->updateAllRules(); + for (auto const& w : Desktop::windowState()->windows()) + w->uncacheWindowDecos(); + for (const auto& ws : State::workspaceState()->workspaces()) { if (!ws) continue; diff --git a/src/config/values/ConfigValues.cpp b/src/config/values/ConfigValues.cpp index 5705c60bf..06e4b7cff 100644 --- a/src/config/values/ConfigValues.cpp +++ b/src/config/values/ConfigValues.cpp @@ -433,7 +433,9 @@ std::vector> Values::getConfigValues() { * group:groupbar: */ - MS("group:groupbar:enabled", "enables groupbars", true), + MS("group:groupbar:enabled", "enables groupbars", true, {.refresh = Supplementary::REFRESH_WINDOW_STATES}), + MS("group:groupbar:disable_when_only", "disable if contains single window. Considered only if enabled == true", false, + {.refresh = Supplementary::REFRESH_WINDOW_STATES}), MS("group:groupbar:font_family", "font used to display groupbar titles", "[[EMPTY]]"), MS("group:groupbar:font_weight_active", "weight of the font used to display active groupbar titles"), MS("group:groupbar:font_weight_inactive", "weight of the font used to display inactive groupbar titles"), diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index ad55ceaf3..1a03f3d1d 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -25,8 +25,8 @@ static SP m_tGradientLockedInactive; constexpr int BAR_TEXT_PAD = 2; CHyprGroupBarDecoration::CHyprGroupBarDecoration(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow), m_window(pWindow) { - static auto PGRADIENTS = CConfigValue("group:groupbar:enabled"); - static auto PENABLED = CConfigValue("group:groupbar:gradients"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); if (*PENABLED && *PGRADIENTS) refreshGroupBarGradients(); @@ -101,8 +101,10 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { const bool VISIBLE = visible(); - if (VISIBLE != m_bLastVisibilityStatus) + if (!m_bLastVisibilityStatus.has_value() || VISIBLE != *m_bLastVisibilityStatus) { g_pDecorationPositioner->repositionDeco(this); + m_bLastVisibilityStatus = VISIBLE; + } if (!VISIBLE) return; @@ -353,8 +355,8 @@ static SP renderGradient(Config::CGradientValueData* grad) { } void refreshGroupBarGradients() { - static auto PGRADIENTS = CConfigValue("group:groupbar:enabled"); - static auto PENABLED = CConfigValue("group:groupbar:gradients"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); static auto PGROUPCOLACTIVE = CConfigValue("group:groupbar:col.active"); static auto PGROUPCOLINACTIVE = CConfigValue("group:groupbar:col.inactive"); @@ -535,6 +537,7 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() { } bool CHyprGroupBarDecoration::visible() { - static auto PENABLED = CConfigValue("group:groupbar:enabled"); - return *PENABLED && m_window->m_ruleApplicator->decorate().valueOrDefault(); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PDISABLE = CConfigValue("group:groupbar:disable_when_only"); + return *PENABLED && (!*PDISABLE || m_dwGroupMembers.size() > 1) && m_window->m_ruleApplicator->decorate().valueOrDefault(); } diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index f6581c8d6..583d7844c 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -58,7 +58,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { float m_barWidth; float m_barHeight; - bool m_bLastVisibilityStatus = true; + std::optional m_bLastVisibilityStatus; CTitleTex* textureFromTitle(const std::string&); void invalidateTextures();