rcxml: rewrite <windowRules> parser

This commit is contained in:
tokyo4j 2025-04-12 02:40:31 +09:00 committed by Johan Malm
parent 936c5f6df1
commit ba00f57dad

View file

@ -282,82 +282,82 @@ set_property(const char *str, enum property *variable)
*variable = ret ? LAB_PROP_TRUE : LAB_PROP_FALSE; *variable = ret ? LAB_PROP_TRUE : LAB_PROP_FALSE;
} }
static void append_actions(xmlNode *node, struct wl_list *list);
static void static void
fill_window_rule(char *nodename, char *content, struct parser_state *state) fill_window_rule(xmlNode *node)
{ {
if (!strcasecmp(nodename, "windowRule.windowRules")) { struct window_rule *window_rule = znew(*window_rule);
state->current_window_rule = znew(*state->current_window_rule); window_rule->window_type = -1; // Window types are >= 0
state->current_window_rule->window_type = -1; // Window types are >= 0 wl_list_append(&rc.window_rules, &window_rule->link);
wl_list_append(&rc.window_rules, &state->current_window_rule->link); wl_list_init(&window_rule->actions);
wl_list_init(&state->current_window_rule->actions);
return;
}
string_truncate_at_pattern(nodename, ".windowrule.windowrules");
if (!content) {
/* nop */
} else if (!state->current_window_rule) {
wlr_log(WLR_ERROR, "no window-rule");
xmlNode *child;
char *key, *content;
LAB_XML_FOR_EACH(node, child, key, content) {
/* Criteria */ /* Criteria */
} else if (!strcmp(nodename, "identifier")) { if (!strcmp(key, "identifier")) {
xstrdup_replace(state->current_window_rule->identifier, content); xstrdup_replace(window_rule->identifier, content);
} else if (!strcmp(nodename, "title")) { } else if (!strcmp(key, "title")) {
xstrdup_replace(state->current_window_rule->title, content); xstrdup_replace(window_rule->title, content);
} else if (!strcmp(nodename, "type")) { } else if (!strcmp(key, "type")) {
state->current_window_rule->window_type = parse_window_type(content); window_rule->window_type = parse_window_type(content);
} else if (!strcasecmp(nodename, "matchOnce")) { } else if (!strcasecmp(key, "matchOnce")) {
set_bool(content, &state->current_window_rule->match_once); set_bool(content, &window_rule->match_once);
} else if (!strcasecmp(nodename, "sandboxEngine")) { } else if (!strcasecmp(key, "sandboxEngine")) {
xstrdup_replace(state->current_window_rule->sandbox_engine, content); xstrdup_replace(window_rule->sandbox_engine, content);
} else if (!strcasecmp(nodename, "sandboxAppId")) { } else if (!strcasecmp(key, "sandboxAppId")) {
xstrdup_replace(state->current_window_rule->sandbox_app_id, content); xstrdup_replace(window_rule->sandbox_app_id, content);
/* Event */ /* Event */
} else if (!strcmp(nodename, "event")) { } else if (!strcmp(key, "event")) {
/* /*
* This is just in readiness for adding any other types of * This is just in readiness for adding any other types of
* events in the future. We default to onFirstMap anyway. * events in the future. We default to onFirstMap anyway.
*/ */
if (!strcasecmp(content, "onFirstMap")) { if (!strcasecmp(content, "onFirstMap")) {
state->current_window_rule->event = LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP; window_rule->event = LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP;
} }
/* Properties */ /* Properties */
} else if (!strcasecmp(nodename, "serverDecoration")) { } else if (!strcasecmp(key, "serverDecoration")) {
set_property(content, &state->current_window_rule->server_decoration); set_property(content, &window_rule->server_decoration);
} else if (!strcasecmp(nodename, "iconPriority")) { } else if (!strcasecmp(key, "iconPriority")) {
if (!strcasecmp(content, "client")) { if (!strcasecmp(content, "client")) {
state->current_window_rule->icon_prefer_client = LAB_PROP_TRUE; window_rule->icon_prefer_client = LAB_PROP_TRUE;
} else if (!strcasecmp(content, "server")) { } else if (!strcasecmp(content, "server")) {
state->current_window_rule->icon_prefer_client = LAB_PROP_FALSE; window_rule->icon_prefer_client = LAB_PROP_FALSE;
} else { } else {
wlr_log(WLR_ERROR, wlr_log(WLR_ERROR,
"Invalid value for window rule property 'iconPriority'"); "Invalid value for window rule property 'iconPriority'");
} }
} else if (!strcasecmp(nodename, "skipTaskbar")) { } else if (!strcasecmp(key, "skipTaskbar")) {
set_property(content, &state->current_window_rule->skip_taskbar); set_property(content, &window_rule->skip_taskbar);
} else if (!strcasecmp(nodename, "skipWindowSwitcher")) { } else if (!strcasecmp(key, "skipWindowSwitcher")) {
set_property(content, &state->current_window_rule->skip_window_switcher); set_property(content, &window_rule->skip_window_switcher);
} else if (!strcasecmp(nodename, "ignoreFocusRequest")) { } else if (!strcasecmp(key, "ignoreFocusRequest")) {
set_property(content, &state->current_window_rule->ignore_focus_request); set_property(content, &window_rule->ignore_focus_request);
} else if (!strcasecmp(nodename, "ignoreConfigureRequest")) { } else if (!strcasecmp(key, "ignoreConfigureRequest")) {
set_property(content, &state->current_window_rule->ignore_configure_request); set_property(content, &window_rule->ignore_configure_request);
} else if (!strcasecmp(nodename, "fixedPosition")) { } else if (!strcasecmp(key, "fixedPosition")) {
set_property(content, &state->current_window_rule->fixed_position); set_property(content, &window_rule->fixed_position);
}
/* Actions */ }
} else if (!strcmp(nodename, "name.action")) {
state->current_window_rule_action = action_create(content); append_actions(node, &window_rule->actions);
if (state->current_window_rule_action) { }
wl_list_append(&state->current_window_rule->actions,
&state->current_window_rule_action->link); static void
fill_window_rules(xmlNode *node)
{
/* TODO: make sure <windowRules> is empty here */
xmlNode *child;
char *key, *content;
LAB_XML_FOR_EACH(node, child, key, content) {
if (!strcasecmp(key, "windowRule")) {
fill_window_rule(child);
} }
} else if (!state->current_window_rule_action) {
wlr_log(WLR_ERROR, "expect <action name=\"\"> element first. "
"nodename: '%s' content: '%s'", nodename, content);
} else {
action_arg_from_xml_node(state->current_window_rule_action, nodename, content);
} }
} }
@ -487,8 +487,6 @@ fill_action_query(struct action *action, xmlNode *node, struct view_query *query
} }
} }
static void append_actions(xmlNode *node, struct wl_list *list);
static void static void
parse_action_args(xmlNode *node, struct action *action) parse_action_args(xmlNode *node, struct action *action)
{ {
@ -1084,8 +1082,8 @@ entry(xmlNode *node, char *nodename, char *content, struct parser_state *state)
fill_window_switcher_fields(node); fill_window_switcher_fields(node);
return; return;
} }
if (state->in_window_rules) { if (!strcasecmp(nodename, "windowRules")) {
fill_window_rule(nodename, content, state); fill_window_rules(node);
return; return;
} }