config: bring back desc: for description matching

fixes #318
This commit is contained in:
Vaxry
2026-01-08 22:16:54 +01:00
parent feafd06287
commit 2953d963be
3 changed files with 36 additions and 24 deletions

View File

@ -2,6 +2,8 @@
#include <algorithm>
using namespace std::string_literals;
// Check if a monitor string represents a wildcard (matches all monitors)
// Empty string or "*" are both treated as wildcards.
// "*" is preferred since hyprlang's special category system doesn't properly
@ -28,24 +30,24 @@ void CWallpaperMatcher::addStates(std::vector<CConfigManager::SSetting>&& s) {
recalcStates();
}
void CWallpaperMatcher::registerOutput(const std::string_view& s) {
m_monitorNames.emplace_back(s);
void CWallpaperMatcher::registerOutput(const std::string_view& s, const std::string_view& desc) {
m_monitorNames.emplace_back(std::make_pair<>(s, desc));
recalcStates();
}
void CWallpaperMatcher::unregisterOutput(const std::string_view& s) {
std::erase(m_monitorNames, s);
std::erase_if(m_monitorNames, [&s](const auto& e) { return e.first == s; });
std::erase_if(m_monitorStates, [&s](const auto& e) { return e.name == s; });
recalcStates();
}
bool CWallpaperMatcher::outputExists(const std::string_view& s) {
return std::ranges::contains(m_monitorNames, s);
return std::ranges::any_of(m_monitorNames, [&s](const auto& e) { return e.first == s || "desc:" + e.second == s; });
}
std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperMatcher::getSetting(const std::string_view& monName) {
std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperMatcher::getSetting(const std::string_view& monName, const std::string_view& monDesc) {
for (const auto& m : m_monitorStates) {
if (m.name != monName)
if (m.name != monName && monDesc != m.name)
continue;
for (const auto& s : m_settings) {
@ -60,10 +62,10 @@ std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperM
return std::nullopt;
}
std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperMatcher::matchSetting(const std::string_view& monName) {
std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperMatcher::matchSetting(const std::string_view& monName, const std::string_view& monDesc) {
// match explicit
for (const auto& s : m_settings) {
if (s.monitor != monName)
if (s.monitor != monName && s.monitor != "desc:"s + std::string{monDesc})
continue;
return s;
}
@ -77,9 +79,9 @@ std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperM
return std::nullopt;
}
CWallpaperMatcher::SMonitorState& CWallpaperMatcher::getState(const std::string_view& monName) {
CWallpaperMatcher::SMonitorState& CWallpaperMatcher::getState(const std::string_view& monName, const std::string_view& monDesc) {
for (auto& s : m_monitorStates) {
if (s.name == monName)
if (s.name == monName || s.desc == monDesc)
return s;
}
@ -89,14 +91,15 @@ CWallpaperMatcher::SMonitorState& CWallpaperMatcher::getState(const std::string_
void CWallpaperMatcher::recalcStates() {
std::vector<std::string_view> namesChanged;
for (const auto& name : m_monitorNames) {
const auto STATE = matchSetting(name);
auto& activeState = getState(name);
for (const auto& [name, desc] : m_monitorNames) {
const auto STATE = matchSetting(name, desc);
auto& activeState = getState(name, desc);
if (!STATE)
activeState = {.name = name};
activeState = {.name = name, .desc = desc};
else {
activeState.name = name;
activeState.desc = desc;
if (activeState.currentID != STATE->get().id) {
activeState.currentID = STATE->get().id;
namesChanged.emplace_back(name);

View File

@ -1,6 +1,7 @@
#pragma once
#include <optional>
#include <tuple>
#include "ConfigManager.hpp"
@ -21,11 +22,11 @@ class CWallpaperMatcher {
void addState(CConfigManager::SSetting&&);
void addStates(std::vector<CConfigManager::SSetting>&&);
void registerOutput(const std::string_view&);
void registerOutput(const std::string_view&, const std::string_view&);
void unregisterOutput(const std::string_view&);
bool outputExists(const std::string_view&);
std::optional<rw<const CConfigManager::SSetting>> getSetting(const std::string_view& monName);
std::optional<rw<const CConfigManager::SSetting>> getSetting(const std::string_view& monName, const std::string_view& monDesc);
struct {
Hyprutils::Signal::CSignalT<const std::string_view&> monitorConfigChanged;
@ -33,21 +34,21 @@ class CWallpaperMatcher {
private:
void recalcStates();
std::optional<rw<const CConfigManager::SSetting>> matchSetting(const std::string_view& monName);
std::optional<rw<const CConfigManager::SSetting>> matchSetting(const std::string_view& monName, const std::string_view& monDesc);
std::vector<CConfigManager::SSetting> m_settings;
struct SMonitorState {
std::string name;
std::string name, desc;
uint32_t currentID = CConfigManager::SETTING_INVALID;
};
std::vector<std::string> m_monitorNames;
std::vector<SMonitorState> m_monitorStates;
std::vector<std::pair<std::string, std::string>> m_monitorNames;
std::vector<SMonitorState> m_monitorStates;
uint32_t m_maxId = 0;
uint32_t m_maxId = 0;
SMonitorState& getState(const std::string_view& monName);
SMonitorState& getState(const std::string_view& monName, const std::string_view& monDesc);
};
inline UP<CWallpaperMatcher> g_matcher = makeUnique<CWallpaperMatcher>();

View File

@ -8,12 +8,20 @@
#include <hyprtoolkit/core/Output.hpp>
#include <hyprutils/string/String.hpp>
CUI::CUI() = default;
CUI::~CUI() {
m_targets.clear();
}
static std::string_view pruneDesc(const std::string_view& sv) {
if (sv.contains('('))
return Hyprutils::String::trim(sv.substr(0, sv.find_last_of('(')));
return sv;
}
class CWallpaperTarget::CImagesData {
public:
CImagesData(Hyprtoolkit::eImageFitMode fitMode, const std::vector<std::string>& images, const int timeout = 0) :
@ -119,7 +127,7 @@ void CWallpaperTarget::onRepeatTimer() {
}
void CUI::registerOutput(const SP<Hyprtoolkit::IOutput>& mon) {
g_matcher->registerOutput(mon->port());
g_matcher->registerOutput(mon->port(), pruneDesc(mon->desc()));
if (IPC::g_IPCSocket)
IPC::g_IPCSocket->onNewDisplay(mon->port());
mon->m_events.removed.listenStatic([this, m = WP<Hyprtoolkit::IOutput>{mon}] {
@ -205,7 +213,7 @@ void CUI::targetChanged(const std::string_view& monName) {
}
void CUI::targetChanged(const SP<Hyprtoolkit::IOutput>& mon) {
const auto TARGET = g_matcher->getSetting(mon->port());
const auto TARGET = g_matcher->getSetting(mon->port(), pruneDesc(mon->desc()));
if (!TARGET) {
g_logger->log(LOG_DEBUG, "Monitor {} has no target: no wp will be created", mon->port());