diff --git a/src/core/rules.c b/src/core/rules.c index 7201584..a739c56 100644 --- a/src/core/rules.c +++ b/src/core/rules.c @@ -1,5 +1,9 @@ #include "core/rules.h" +#include +#include +#include + #include "base/memory.h" #include "core/types.h" @@ -35,3 +39,43 @@ void rules_cleanup(rules_t *rules) { rules->capacity = 0; rules->count = 0; } + +static inline bool str_match(const char *pattern, const char *value) { + return !pattern || (value && strcmp(pattern, value) == 0); +} + +static bool rule_match_window(const rule_match_t *match, + const window_metadata_t *meta) { + return str_match(match->app_id, meta->app_id) && + str_match(match->role, meta->role) && + str_match(match->class_name, meta->class_name) && + str_match(match->instance_name, meta->instance_name); +} + +static void rule_action_merge(const rule_action_t *src, rule_action_t *dest) { + if (!src || !dest) return; + + if (src->workspace != ZDWM_WORKSPACE_ID_INVALID) { + dest->workspace = src->workspace; + } + dest->switch_to_workspace |= src->switch_to_workspace; + dest->fullscreen |= src->fullscreen; + dest->maximize |= src->maximize; + dest->floating |= src->floating; +} + +bool rules_resolve(const rules_t *rules, const window_metadata_t *metadata, + rule_action_t *action_out) { + if (!action_out) return false; + + bool matched = false; + + for (size_t i = 0; i < rules->count; ++i) { + if (!rule_match_window(&rules->items[i].match, metadata)) continue; + + matched = true; + rule_action_merge(&rules->items[i].action, action_out); + } + + return matched; +} diff --git a/src/core/rules.h b/src/core/rules.h index d26e4ae..de9a6a7 100644 --- a/src/core/rules.h +++ b/src/core/rules.h @@ -3,6 +3,7 @@ #include #include "core/types.h" +#include "core/window.h" typedef struct rule_item_t { rule_match_t match; @@ -17,3 +18,6 @@ typedef struct rules_t { bool rules_move(rules_t *src, rules_t *dest); void rules_cleanup(rules_t *rules); + +bool rules_resolve(const rules_t *rules, const window_metadata_t *metadata, + rule_action_t *action_out);