action: allow if-action without activator view

..in preparation for If/ForEach action with <prompt>, which should be
executed whether or not any window is focused.

This patch makes <If> actions execute <else> branch if no window is
focused or hovered.
This commit is contained in:
tokyo4j 2025-08-01 16:15:00 +09:00 committed by Johan Malm
parent 15e3c32b5b
commit b9c84f9c38

View file

@ -776,29 +776,24 @@ view_for_action(struct view *activator, struct server *server,
} }
static bool static bool
run_if_action(struct view *view, struct server *server, struct action *action) match_queries(struct view *view, struct action *action)
{ {
struct view_query *query; struct wl_list *queries = action_get_querylist(action, "query");
struct wl_list *queries, *actions; if (!queries) {
const char *branch = "then"; return true;
}
if (!view) {
return false;
}
queries = action_get_querylist(action, "query"); /* All queries are OR'ed */
if (queries) { struct view_query *query;
branch = "else"; wl_list_for_each(query, queries, link) {
/* All queries are OR'ed */ if (view_matches_query(view, query)) {
wl_list_for_each(query, queries, link) { return true;
if (view_matches_query(view, query)) {
branch = "then";
break;
}
} }
} }
return false;
actions = action_get_actionlist(action, branch);
if (actions) {
actions_run(view, server, actions, NULL);
}
return !strcmp(branch, "then");
} }
static struct output * static struct output *
@ -1209,26 +1204,43 @@ run_action(struct view *view, struct server *server, struct action *action,
} }
break; break;
} }
case ACTION_TYPE_IF: case ACTION_TYPE_IF: {
if (view) { struct wl_list *actions;
run_if_action(view, server, action); if (match_queries(view, action)) {
actions = action_get_actionlist(action, "then");
} else {
actions = action_get_actionlist(action, "else");
}
if (actions) {
actions_run(view, server, actions, ctx);
} }
break; break;
}
case ACTION_TYPE_FOR_EACH: { case ACTION_TYPE_FOR_EACH: {
struct wl_array views; struct wl_list *actions = NULL;
struct view **item;
bool matches = false; bool matches = false;
struct wl_array views;
wl_array_init(&views); wl_array_init(&views);
view_array_append(server, &views, LAB_VIEW_CRITERIA_NONE); view_array_append(server, &views, LAB_VIEW_CRITERIA_NONE);
struct view **item;
wl_array_for_each(item, &views) { wl_array_for_each(item, &views) {
matches |= run_if_action(*item, server, action); if (match_queries(*item, action)) {
matches = true;
actions = action_get_actionlist(action, "then");
} else {
actions = action_get_actionlist(action, "else");
}
if (actions) {
actions_run(*item, server, actions, ctx);
}
} }
wl_array_release(&views); wl_array_release(&views);
if (!matches) { if (!matches) {
struct wl_list *child_actions; actions = action_get_actionlist(action, "none");
child_actions = action_get_actionlist(action, "none"); if (actions) {
if (child_actions) { actions_run(view, server, actions, NULL);
actions_run(view, server, child_actions, NULL);
} }
} }
break; break;