labwc/src/window-rules.c

117 lines
3.1 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-only
#define _POSIX_C_SOURCE 200809L
#include "window-rules.h"
#include <assert.h>
#include <stdbool.h>
#include <strings.h>
#include "action.h"
#include "config/rcxml.h"
#include "labwc.h"
#include "view.h"
static bool
other_instances_exist(struct view *self, struct view_query *query)
{
struct wl_list *views = &self->server->views;
struct view *view;
wl_list_for_each(view, views, link) {
if (view != self && view_matches_query(view, query)) {
return true;
}
}
return false;
}
static bool
view_matches_criteria(struct window_rule *rule, struct view *view)
{
struct view_query query = {
.identifier = rule->identifier,
.title = rule->title,
.window_type = rule->window_type,
.sandbox_engine = rule->sandbox_engine,
.sandbox_app_id = rule->sandbox_app_id,
/* Must be synced with view_query_create() */
.maximized = VIEW_AXIS_INVALID,
.decoration = LAB_SSD_MODE_INVALID,
};
if (rule->match_once && other_instances_exist(view, &query)) {
return false;
}
return view_matches_query(view, &query);
}
void
window_rules_apply(struct view *view, enum window_rule_event event)
{
struct window_rule *rule;
wl_list_for_each(rule, &rc.window_rules, link) {
if (rule->event != event) {
continue;
}
if (view_matches_criteria(rule, view)) {
actions_run(view, view->server, &rule->actions, NULL);
}
}
}
enum property
window_rules_get_property(struct view *view, const char *property)
{
assert(property);
/*
* We iterate in reverse here because later items in list have higher
* priority. For example, in the config below we want the return value
* for foot's "serverDecoration" property to be "default".
*
* <windowRules>
* <windowRule identifier="*" serverDecoration="no"/>
* <windowRule identifier="foot" serverDecoration="default"/>
* </windowRules>
*/
struct window_rule *rule;
wl_list_for_each_reverse(rule, &rc.window_rules, link) {
/*
* Only return if property != LAB_PROP_UNSPECIFIED otherwise a
* <windowRule> which does not set a particular property
* attribute would still return here if that property was asked
* for.
*/
if (view_matches_criteria(rule, view)) {
if (rule->server_decoration
&& !strcasecmp(property, "serverDecoration")) {
return rule->server_decoration;
}
if (rule->skip_taskbar
&& !strcasecmp(property, "skipTaskbar")) {
return rule->skip_taskbar;
}
if (rule->skip_window_switcher
&& !strcasecmp(property, "skipWindowSwitcher")) {
return rule->skip_window_switcher;
}
if (rule->ignore_focus_request
&& !strcasecmp(property, "ignoreFocusRequest")) {
return rule->ignore_focus_request;
}
if (rule->ignore_configure_request
&& !strcasecmp(property, "ignoreConfigureRequest")) {
return rule->ignore_configure_request;
}
if (rule->fixed_position
&& !strcasecmp(property, "fixedPosition")) {
return rule->fixed_position;
}
if (rule->icon_prefer_client
&& !strcasecmp(property, "iconPreferClient")) {
return rule->icon_prefer_client;
}
}
}
return LAB_PROP_UNSPECIFIED;
}