--- a/src/protocols/core/Output.hpp +++ b/src/protocols/core/Output.hpp @@ -33,0 +34 @@ + friend class COutputTest; // Test fixture advances the real removal timer deterministically. --- a/tests/protocols/Output.cpp +++ b/tests/protocols/Output.cpp @@ -75 +75,2 @@ - void releaseOutput(); + void releaseOutput(bool expireGrace = true); + void advanceRemovalGrace(); @@ -134,0 +136 @@ + g_pEventLoopManager = makeUnique(m_display.get(), g_pCompositor->m_wlEventLoop); @@ -176,0 +179 @@ + g_pEventLoopManager.reset(); @@ -276 +279,12 @@ -void COutputTest::releaseOutput() { +void COutputTest::advanceRemovalGrace() { + auto protocols = PROTO::defunctOutputs; + for (const auto& [_, protocol] : PROTO::outputs) + protocols.emplace_back(protocol); + for (const auto& protocol : protocols) { + if (protocol->m_removeTimer) + protocol->m_removeTimer->updateTimeout(std::chrono::nanoseconds(0)); + } + g_pEventLoopManager->onTimerFire(); +} + +void COutputTest::releaseOutput(bool expireGrace) { @@ -284,0 +299,2 @@ + if (expireGrace) + advanceRemovalGrace(); @@ -290,0 +307 @@ + advanceRemovalGrace(); @@ -835,0 +853,24 @@ + +TEST_F(COutputTest, RemovalGraceRetainsUnboundOutputForLateBind) { + m_protocol->remove(); + ASSERT_TRUE(m_protocol->isDefunct()); + ASSERT_FALSE(m_protocol->hasBoundResources()); + EXPECT_TRUE(PROTO::outputs.contains(m_monitor->m_name)); + g_pEventLoopManager->onTimerFire(); + EXPECT_TRUE(PROTO::outputs.contains(m_monitor->m_name)); + ASSERT_NO_FATAL_FAILURE(bindOutput()); + ASSERT_NO_FATAL_FAILURE(releaseOutput(false)); + EXPECT_TRUE(PROTO::outputs.contains(m_monitor->m_name)); + advanceRemovalGrace(); + EXPECT_TRUE(PROTO::outputs.empty()); +} + +TEST_F(COutputTest, RemovalGraceExpiryKeepsBoundOutputUntilRelease) { + m_protocol->remove(); + ASSERT_NO_FATAL_FAILURE(bindOutput()); + advanceRemovalGrace(); + EXPECT_TRUE(PROTO::outputs.contains(m_monitor->m_name)); + EXPECT_TRUE(m_protocol->hasBoundResources()); + ASSERT_NO_FATAL_FAILURE(releaseOutput()); + EXPECT_TRUE(PROTO::outputs.empty()); +} --- /dev/null +++ b/tests/config/shared/MonitorRuleVRR.cpp @@ -0,0 +1,19 @@ +#include +#include + +TEST(MonitorRuleVRR, ChangingOnlyVRRRequestsSoftRefresh) { + Config::CMonitorRule active; + active.m_vrr = 0; + auto requested = active; + requested.m_vrr = 1; + EXPECT_EQ(active.compare(requested), Config::COMPARISON_SOFT_MISMATCH); + EXPECT_EQ(requested.compare(active), Config::COMPARISON_SOFT_MISMATCH); + EXPECT_EQ(active.compare(active), Config::COMPARISON_FULL_MATCH); +} + +TEST(MonitorRuleVRR, ExplicitVRRDiffersFromInheritedDefault) { + Config::CMonitorRule inherited; + auto requested = inherited; + requested.m_vrr = 0; + EXPECT_EQ(inherited.compare(requested), Config::COMPARISON_SOFT_MISMATCH); +} --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -32 +32 @@ - static const std::string ver = std::format("{}_aq_{}_hu_{}_hg_{}_hc_{}_hlg_{}", GIT_COMMIT_HASH, stripPatch(AQUAMARINE_VERSION), stripPatch(HYPRUTILS_VERSION), + static const std::string ver = std::format("{}_omadora_912521ee8a53_aq_{}_hu_{}_hg_{}_hc_{}_hlg_{}", GIT_COMMIT_HASH, stripPatch(AQUAMARINE_VERSION), stripPatch(HYPRUTILS_VERSION), --- a/src/plugins/PluginAPI.hpp +++ b/src/plugins/PluginAPI.hpp @@ -404 +404 @@ - static const std::string ver = std::format("{}_aq_{}_hu_{}_hg_{}_hc_{}_hlg_{}", GIT_COMMIT_HASH, stripPatch(AQUAMARINE_VERSION), stripPatch(HYPRUTILS_VERSION), + static const std::string ver = std::format("{}_omadora_912521ee8a53_aq_{}_hu_{}_hg_{}_hc_{}_hlg_{}", GIT_COMMIT_HASH, stripPatch(AQUAMARINE_VERSION), stripPatch(HYPRUTILS_VERSION), --- /dev/null +++ b/tests/plugins/OmadoraABI.cpp @@ -0,0 +1,8 @@ +#include +#include +#include + +TEST(OmadoraABI, CandidateClientAndServerHashesMatch) { + EXPECT_STREQ(__hyprland_api_get_hash(), __hyprland_api_get_client_hash()); + EXPECT_TRUE(std::string_view(__hyprland_api_get_hash()).contains("_omadora_912521ee8a53_")); +}