window-rules: support matchOnce attribute

...allowing a rule to be applied to only the first window matching a
particular criteria. For example, the following can be used to apply a
window rule to lxqt-panel but not its configuration window with the same
app_id:

    <windowRules>
      <windowRule identifier="lxqt-panel" matchOnce="true">
        <skipTaskbar>yes</skipTaskbar>
        <action name="MoveTo" x="0" y="0" />
        <action name="ToggleAlwaysOnTop"/>
      </windowRule>
    </windowRules>
This commit is contained in:
Johan Malm 2023-06-07 21:44:38 +01:00 committed by Johan Malm
parent f6c3a3d7c3
commit 41de529fff
5 changed files with 73 additions and 15 deletions

View file

@ -130,6 +130,8 @@ fill_window_rule(char *nodename, char *content)
} else if (!strcmp(nodename, "title")) {
free(current_window_rule->title);
current_window_rule->title = xstrdup(content);
} else if (!strcasecmp(nodename, "matchOnce")) {
set_bool(content, &current_window_rule->match_once);
/* Event */
} else if (!strcmp(nodename, "event")) {

View file

@ -14,6 +14,33 @@
#include "view.h"
#include "window-rules.h"
static bool
other_instances_exist(struct view *self, const char *id, const char *title)
{
struct wl_list *views = &self->server->views;
const char *prop = NULL;
struct view *view;
wl_list_for_each(view, views, link) {
if (view == self) {
continue;
}
if (id) {
prop = view_get_string_prop(view, "app_id");
if (prop && !strcmp(prop, id)) {
return true;
}
}
if (title) {
prop = view_get_string_prop(view, "title");
if (prop && !strcmp(prop, title)) {
return true;
}
}
}
return false;
}
/* Try to match against identifier AND title (if set) */
static bool
view_matches_criteria(struct window_rule *rule, struct view *view)
@ -21,6 +48,10 @@ view_matches_criteria(struct window_rule *rule, struct view *view)
const char *id = view_get_string_prop(view, "app_id");
const char *title = view_get_string_prop(view, "title");
if (rule->match_once && other_instances_exist(view, id, title)) {
return false;
}
if (rule->identifier && rule->title) {
if (!id || !title) {
return false;