layerrules: add dynamically registered rules for plugins (#13331)
* layerrules: add dynamically registered rules for plugins * be gone * layerrules: add layer tests with waybar * fix: use kitty layers instead of waybar
This commit is contained in:
parent
42f0a6005b
commit
e0c5710059
8 changed files with 230 additions and 14 deletions
|
|
@ -10,7 +10,9 @@
|
||||||
#include <src/managers/PointerManager.hpp>
|
#include <src/managers/PointerManager.hpp>
|
||||||
#include <src/managers/input/trackpad/TrackpadGestures.hpp>
|
#include <src/managers/input/trackpad/TrackpadGestures.hpp>
|
||||||
#include <src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp>
|
#include <src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp>
|
||||||
|
#include <src/desktop/rule/layerRule/LayerRuleEffectContainer.hpp>
|
||||||
#include <src/desktop/rule/windowRule/WindowRuleApplicator.hpp>
|
#include <src/desktop/rule/windowRule/WindowRuleApplicator.hpp>
|
||||||
|
#include <src/desktop/view/LayerSurface.hpp>
|
||||||
#include <src/Compositor.hpp>
|
#include <src/Compositor.hpp>
|
||||||
#include <src/desktop/state/FocusState.hpp>
|
#include <src/desktop/state/FocusState.hpp>
|
||||||
#include <src/layout/LayoutManager.hpp>
|
#include <src/layout/LayoutManager.hpp>
|
||||||
|
|
@ -270,32 +272,67 @@ static SDispatchResult keybind(std::string in) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Desktop::Rule::CWindowRuleEffectContainer::storageType ruleIDX = 0;
|
static Desktop::Rule::CWindowRuleEffectContainer::storageType windowRuleIDX = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
static SDispatchResult addRule(std::string in) {
|
static SDispatchResult addWindowRule(std::string in) {
|
||||||
ruleIDX = Desktop::Rule::windowEffects()->registerEffect("plugin_rule");
|
windowRuleIDX = Desktop::Rule::windowEffects()->registerEffect("plugin_rule");
|
||||||
|
|
||||||
if (Desktop::Rule::windowEffects()->registerEffect("plugin_rule") != ruleIDX)
|
if (Desktop::Rule::windowEffects()->registerEffect("plugin_rule") != windowRuleIDX)
|
||||||
return {.success = false, .error = "re-registering returned a different id?"};
|
return {.success = false, .error = "re-registering returned a different id?"};
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDispatchResult checkRule(std::string in) {
|
static SDispatchResult checkWindowRule(std::string in) {
|
||||||
const auto PLASTWINDOW = Desktop::focusState()->window();
|
const auto PLASTWINDOW = Desktop::focusState()->window();
|
||||||
|
|
||||||
if (!PLASTWINDOW)
|
if (!PLASTWINDOW)
|
||||||
return {.success = false, .error = "No window"};
|
return {.success = false, .error = "No window"};
|
||||||
|
|
||||||
if (!PLASTWINDOW->m_ruleApplicator->m_otherProps.props.contains(ruleIDX))
|
if (!PLASTWINDOW->m_ruleApplicator->m_otherProps.props.contains(windowRuleIDX))
|
||||||
return {.success = false, .error = "No rule"};
|
return {.success = false, .error = "No rule"};
|
||||||
|
|
||||||
if (PLASTWINDOW->m_ruleApplicator->m_otherProps.props[ruleIDX]->effect != "effect")
|
if (PLASTWINDOW->m_ruleApplicator->m_otherProps.props[windowRuleIDX]->effect != "effect")
|
||||||
return {.success = false, .error = "Effect isn't \"effect\""};
|
return {.success = false, .error = "Effect isn't \"effect\""};
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Desktop::Rule::CLayerRuleEffectContainer::storageType layerRuleIDX = 0;
|
||||||
|
|
||||||
|
static SDispatchResult addLayerRule(std::string in) {
|
||||||
|
layerRuleIDX = Desktop::Rule::layerEffects()->registerEffect("plugin_rule");
|
||||||
|
|
||||||
|
if (Desktop::Rule::layerEffects()->registerEffect("plugin_rule") != layerRuleIDX)
|
||||||
|
return {.success = false, .error = "re-registering returned a different id?"};
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDispatchResult checkLayerRule(std::string in) {
|
||||||
|
if (g_pCompositor->m_layers.size() != 3)
|
||||||
|
return {.success = false, .error = "Layers under test not here"};
|
||||||
|
|
||||||
|
for (const auto& layer : g_pCompositor->m_layers) {
|
||||||
|
if (layer->m_namespace == "rule-layer") {
|
||||||
|
|
||||||
|
if (!layer->m_ruleApplicator->m_otherProps.props.contains(layerRuleIDX))
|
||||||
|
return {.success = false, .error = "No rule"};
|
||||||
|
|
||||||
|
if (layer->m_ruleApplicator->m_otherProps.props[layerRuleIDX]->effect != "effect")
|
||||||
|
return {.success = false, .error = "Effect isn't \"effect\""};
|
||||||
|
|
||||||
|
} else if (layer->m_namespace == "norule-layer") {
|
||||||
|
|
||||||
|
if (layer->m_ruleApplicator->m_otherProps.props.contains(layerRuleIDX))
|
||||||
|
return {.success = false, .error = "Rule even though it shouldn't"};
|
||||||
|
|
||||||
|
} else
|
||||||
|
return {.success = false, .error = "Unrecognized layer"};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static SDispatchResult floatingFocusOnFullscreen(std::string in) {
|
static SDispatchResult floatingFocusOnFullscreen(std::string in) {
|
||||||
const auto PLASTWINDOW = Desktop::focusState()->window();
|
const auto PLASTWINDOW = Desktop::focusState()->window();
|
||||||
|
|
||||||
|
|
@ -325,8 +362,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:scroll", ::scroll);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:scroll", ::scroll);
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:click", ::click);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:click", ::click);
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:keybind", ::keybind);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:keybind", ::keybind);
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:add_rule", ::addRule);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:add_window_rule", ::addWindowRule);
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:check_rule", ::checkRule);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:check_window_rule", ::checkWindowRule);
|
||||||
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:add_layer_rule", ::addLayerRule);
|
||||||
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:check_layer_rule", ::checkLayerRule);
|
||||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:floating_focus_on_fullscreen", ::floatingFocusOnFullscreen);
|
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:floating_focus_on_fullscreen", ::floatingFocusOnFullscreen);
|
||||||
|
|
||||||
// init mouse
|
// init mouse
|
||||||
|
|
|
||||||
53
hyprtester/src/tests/main/layer.cpp
Normal file
53
hyprtester/src/tests/main/layer.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../../Log.hpp"
|
||||||
|
#include "../shared.hpp"
|
||||||
|
#include "tests.hpp"
|
||||||
|
#include "../../shared.hpp"
|
||||||
|
#include "../../hyprctlCompat.hpp"
|
||||||
|
#include <hyprutils/os/Process.hpp>
|
||||||
|
#include <hyprutils/memory/WeakPtr.hpp>
|
||||||
|
|
||||||
|
static int ret = 0;
|
||||||
|
|
||||||
|
using namespace Hyprutils::OS;
|
||||||
|
using namespace Hyprutils::Memory;
|
||||||
|
|
||||||
|
static bool spawnLayer(const std::string& namespace_) {
|
||||||
|
NLog::log("{}Spawning kitty layer {}", Colors::YELLOW, namespace_);
|
||||||
|
if (!Tests::spawnLayerKitty(namespace_)) {
|
||||||
|
NLog::log("{}Error: {} layer did not spawn", Colors::RED, namespace_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test() {
|
||||||
|
NLog::log("{}Testing plugin layerrules", Colors::GREEN);
|
||||||
|
|
||||||
|
if (!spawnLayer("rule-layer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:add_layer_rule"));
|
||||||
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
|
OK(getFromSocket("/keyword layerrule match:namespace rule-layer, plugin_rule effect"));
|
||||||
|
|
||||||
|
if (!spawnLayer("rule-layer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!spawnLayer("norule-layer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:check_layer_rule"));
|
||||||
|
|
||||||
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
|
NLog::log("{}Killing all layers", Colors::YELLOW);
|
||||||
|
Tests::killAllLayers();
|
||||||
|
|
||||||
|
NLog::log("{}Expecting 0 layers", Colors::YELLOW);
|
||||||
|
EXPECT(Tests::layerCount(), 0);
|
||||||
|
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_TEST_FN(test)
|
||||||
|
|
@ -1086,7 +1086,7 @@ static bool test() {
|
||||||
OK(getFromSocket("/reload"));
|
OK(getFromSocket("/reload"));
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch plugin:test:add_rule"));
|
OK(getFromSocket("/dispatch plugin:test:add_window_rule"));
|
||||||
OK(getFromSocket("/reload"));
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
OK(getFromSocket("/keyword windowrule match:class plugin_kitty, plugin_rule effect"));
|
OK(getFromSocket("/keyword windowrule match:class plugin_kitty, plugin_rule effect"));
|
||||||
|
|
@ -1094,12 +1094,12 @@ static bool test() {
|
||||||
if (!spawnKitty("plugin_kitty"))
|
if (!spawnKitty("plugin_kitty"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch plugin:test:check_rule"));
|
OK(getFromSocket("/dispatch plugin:test:check_window_rule"));
|
||||||
|
|
||||||
OK(getFromSocket("/reload"));
|
OK(getFromSocket("/reload"));
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch plugin:test:add_rule"));
|
OK(getFromSocket("/dispatch plugin:test:add_window_rule"));
|
||||||
OK(getFromSocket("/reload"));
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
OK(getFromSocket("/keyword windowrule[test-plugin-rule]:match:class plugin_kitty"));
|
OK(getFromSocket("/keyword windowrule[test-plugin-rule]:match:class plugin_kitty"));
|
||||||
|
|
@ -1108,7 +1108,7 @@ static bool test() {
|
||||||
if (!spawnKitty("plugin_kitty"))
|
if (!spawnKitty("plugin_kitty"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch plugin:test:check_rule"));
|
OK(getFromSocket("/dispatch plugin:test:check_window_rule"));
|
||||||
|
|
||||||
OK(getFromSocket("/reload"));
|
OK(getFromSocket("/reload"));
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <fstream>
|
||||||
#include "../shared.hpp"
|
#include "../shared.hpp"
|
||||||
#include "../hyprctlCompat.hpp"
|
#include "../hyprctlCompat.hpp"
|
||||||
|
|
||||||
|
|
@ -39,6 +40,38 @@ CUniquePointer<CProcess> Tests::spawnKitty(const std::string& class_, const std:
|
||||||
return kitty;
|
return kitty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUniquePointer<CProcess> Tests::spawnLayerKitty(const std::string& namespace_, const std::vector<std::string> args) {
|
||||||
|
std::vector<std::string> programArgs = args;
|
||||||
|
if (!namespace_.empty()) {
|
||||||
|
programArgs.insert(programArgs.begin(), "--class");
|
||||||
|
programArgs.insert(programArgs.begin() + 1, namespace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
programArgs.insert(programArgs.begin(), "+kitten");
|
||||||
|
programArgs.insert(programArgs.begin() + 1, "panel");
|
||||||
|
|
||||||
|
CUniquePointer<CProcess> kitty = makeUnique<CProcess>("kitty", programArgs);
|
||||||
|
kitty->addEnv("WAYLAND_DISPLAY", WLDISPLAY);
|
||||||
|
kitty->runAsync();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
|
||||||
|
// wait while the layer spawns
|
||||||
|
int counter = 0;
|
||||||
|
while (processAlive(kitty->pid()) && countOccurrences(getFromSocket("/layers"), std::format("pid: {}", kitty->pid())) == 0) {
|
||||||
|
counter++;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
|
||||||
|
if (counter > 50)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processAlive(kitty->pid()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return kitty;
|
||||||
|
}
|
||||||
|
|
||||||
bool Tests::processAlive(pid_t pid) {
|
bool Tests::processAlive(pid_t pid) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int ret = kill(pid, 0);
|
int ret = kill(pid, 0);
|
||||||
|
|
@ -96,6 +129,38 @@ void Tests::waitUntilWindowsN(int n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Tests::layerCount() {
|
||||||
|
return countOccurrences(getFromSocket("/layers"), "namespace: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tests::killAllLayers() {
|
||||||
|
auto str = getFromSocket("/layers");
|
||||||
|
auto pos = str.find("pid: ");
|
||||||
|
while (pos != std::string::npos) {
|
||||||
|
auto pid = stoi(str.substr(pos + 5, str.find('\n', pos)));
|
||||||
|
kill(pid, 15);
|
||||||
|
|
||||||
|
// we need to wait for a bit because for some reason otherwise we'll end up
|
||||||
|
// with layers with pid -1 if they are all removed at the same time
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
|
||||||
|
pos = str.find("pid: ", pos + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
while (Tests::layerCount() != 0) {
|
||||||
|
counter++;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
|
||||||
|
if (counter > 50) {
|
||||||
|
std::println("{}Timed out waiting for layers to close", Colors::RED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Tests::execAndGet(const std::string& cmd) {
|
std::string Tests::execAndGet(const std::string& cmd) {
|
||||||
CProcess proc("/bin/sh", {"-c", cmd});
|
CProcess proc("/bin/sh", {"-c", cmd});
|
||||||
|
|
||||||
|
|
@ -105,3 +170,14 @@ std::string Tests::execAndGet(const std::string& cmd) {
|
||||||
|
|
||||||
return proc.stdOut();
|
return proc.stdOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Tests::writeFile(const std::string& name, const std::string& contents) {
|
||||||
|
std::ofstream of(name, std::ios::trunc);
|
||||||
|
if (!of.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
of << contents;
|
||||||
|
of.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,14 @@
|
||||||
//NOLINTNEXTLINE
|
//NOLINTNEXTLINE
|
||||||
namespace Tests {
|
namespace Tests {
|
||||||
Hyprutils::Memory::CUniquePointer<Hyprutils::OS::CProcess> spawnKitty(const std::string& class_ = "", const std::vector<std::string> args = {});
|
Hyprutils::Memory::CUniquePointer<Hyprutils::OS::CProcess> spawnKitty(const std::string& class_ = "", const std::vector<std::string> args = {});
|
||||||
|
Hyprutils::Memory::CUniquePointer<Hyprutils::OS::CProcess> spawnLayerKitty(const std::string& namespace_ = "", const std::vector<std::string> args = {});
|
||||||
bool processAlive(pid_t pid);
|
bool processAlive(pid_t pid);
|
||||||
int windowCount();
|
int windowCount();
|
||||||
int countOccurrences(const std::string& in, const std::string& what);
|
int countOccurrences(const std::string& in, const std::string& what);
|
||||||
bool killAllWindows();
|
bool killAllWindows();
|
||||||
void waitUntilWindowsN(int n);
|
void waitUntilWindowsN(int n);
|
||||||
|
int layerCount();
|
||||||
|
bool killAllLayers();
|
||||||
std::string execAndGet(const std::string& cmd);
|
std::string execAndGet(const std::string& cmd);
|
||||||
|
bool writeFile(const std::string& name, const std::string& contents);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../../view/LayerSurface.hpp"
|
#include "../../view/LayerSurface.hpp"
|
||||||
#include "../../types/OverridableVar.hpp"
|
#include "../../types/OverridableVar.hpp"
|
||||||
#include "../../../helpers/MiscFunctions.hpp"
|
#include "../../../helpers/MiscFunctions.hpp"
|
||||||
|
#include "../../../event/EventBus.hpp"
|
||||||
|
|
||||||
using namespace Desktop;
|
using namespace Desktop;
|
||||||
using namespace Desktop::Rule;
|
using namespace Desktop::Rule;
|
||||||
|
|
@ -32,11 +33,38 @@ void CLayerRuleApplicator::resetProps(std::underlying_type_t<eRuleProperty> prop
|
||||||
UNSET(aboveLock)
|
UNSET(aboveLock)
|
||||||
UNSET(ignoreAlpha)
|
UNSET(ignoreAlpha)
|
||||||
UNSET(animationStyle)
|
UNSET(animationStyle)
|
||||||
|
|
||||||
|
#undef UNSET
|
||||||
|
|
||||||
|
if (prio == Types::PRIORITY_WINDOW_RULE)
|
||||||
|
std::erase_if(m_otherProps.props, [props](const auto& el) { return !el.second || el.second->propMask & props; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLayerRuleApplicator::applyDynamicRule(const SP<CLayerRule>& rule) {
|
void CLayerRuleApplicator::applyDynamicRule(const SP<CLayerRule>& rule) {
|
||||||
for (const auto& [key, effect] : rule->effects()) {
|
for (const auto& [key, effect] : rule->effects()) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
default: {
|
||||||
|
if (key <= LAYER_RULE_EFFECT_LAST_STATIC) {
|
||||||
|
Log::logger->log(Log::TRACE, "CLayerRuleApplicator::applyDynamicRule: Skipping effect {}, not dynamic", sc<std::underlying_type_t<eLayerRuleEffect>>(key));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom type, add to our vec
|
||||||
|
if (!m_otherProps.props.contains(key)) {
|
||||||
|
m_otherProps.props.emplace(key,
|
||||||
|
makeUnique<SCustomPropContainer>(SCustomPropContainer{
|
||||||
|
.idx = key,
|
||||||
|
.propMask = rule->getPropertiesMask(),
|
||||||
|
.effect = effect,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
auto& e = m_otherProps.props[key];
|
||||||
|
e->propMask |= rule->getPropertiesMask();
|
||||||
|
e->effect = effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LAYER_RULE_EFFECT_NONE: {
|
case LAYER_RULE_EFFECT_NONE: {
|
||||||
Log::logger->log(Log::ERR, "CLayerRuleApplicator::applyDynamicRule: BUG THIS: LAYER_RULE_EFFECT_NONE??");
|
Log::logger->log(Log::ERR, "CLayerRuleApplicator::applyDynamicRule: BUG THIS: LAYER_RULE_EFFECT_NONE??");
|
||||||
break;
|
break;
|
||||||
|
|
@ -125,4 +153,7 @@ void CLayerRuleApplicator::propertiesChanged(std::underlying_type_t<eRulePropert
|
||||||
|
|
||||||
applyDynamicRule(wr);
|
applyDynamicRule(wr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for plugins
|
||||||
|
Event::bus()->m_events.layer.updateRules.emit(m_ls.lock());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "LayerRuleEffectContainer.hpp"
|
||||||
#include "../../DesktopTypes.hpp"
|
#include "../../DesktopTypes.hpp"
|
||||||
#include "../Rule.hpp"
|
#include "../Rule.hpp"
|
||||||
#include "../../types/OverridableVar.hpp"
|
#include "../../types/OverridableVar.hpp"
|
||||||
|
|
@ -21,6 +22,17 @@ namespace Desktop::Rule {
|
||||||
void propertiesChanged(std::underlying_type_t<eRuleProperty> props);
|
void propertiesChanged(std::underlying_type_t<eRuleProperty> props);
|
||||||
void resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio = Types::PRIORITY_WINDOW_RULE);
|
void resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio = Types::PRIORITY_WINDOW_RULE);
|
||||||
|
|
||||||
|
struct SCustomPropContainer {
|
||||||
|
CLayerRuleEffectContainer::storageType idx = LAYER_RULE_EFFECT_NONE;
|
||||||
|
std::underlying_type_t<eRuleProperty> propMask = RULE_PROP_NONE;
|
||||||
|
std::string effect;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This struct holds props that were dynamically registered. Plugins may read this.
|
||||||
|
struct {
|
||||||
|
std::unordered_map<CLayerRuleEffectContainer::storageType, UP<SCustomPropContainer>> props;
|
||||||
|
} m_otherProps;
|
||||||
|
|
||||||
#define COMMA ,
|
#define COMMA ,
|
||||||
#define DEFINE_PROP(type, name, def) \
|
#define DEFINE_PROP(type, name, def) \
|
||||||
private: \
|
private: \
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ namespace Event {
|
||||||
struct {
|
struct {
|
||||||
Event<PHLLS> opened;
|
Event<PHLLS> opened;
|
||||||
Event<PHLLS> closed;
|
Event<PHLLS> closed;
|
||||||
|
Event<PHLLS> updateRules;
|
||||||
} layer;
|
} layer;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue