mirror of
https://github.com/swaywm/sway.git
synced 2024-12-28 07:56:31 +01:00
criteria: make literal comparison for __focused__ values
This commit is contained in:
parent
f5f12a69f6
commit
7c9b71f5c6
2 changed files with 205 additions and 171 deletions
|
@ -14,29 +14,38 @@ enum criteria_type {
|
||||||
CT_NO_FOCUS = 1 << 4,
|
CT_NO_FOCUS = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum pattern_type {
|
||||||
|
PATTERN_PCRE,
|
||||||
|
PATTERN_FOCUSED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pattern {
|
||||||
|
enum pattern_type match_type;
|
||||||
|
pcre *regex;
|
||||||
|
};
|
||||||
|
|
||||||
struct criteria {
|
struct criteria {
|
||||||
enum criteria_type type;
|
enum criteria_type type;
|
||||||
char *raw; // entire criteria string (for logging)
|
char *raw; // entire criteria string (for logging)
|
||||||
char *cmdlist;
|
char *cmdlist;
|
||||||
char *target; // workspace or output name for `assign` criteria
|
char *target; // workspace or output name for `assign` criteria
|
||||||
|
|
||||||
bool autofail; // __focused__ while no focus or n/a for focused view
|
struct pattern *title;
|
||||||
pcre *title;
|
struct pattern *shell;
|
||||||
pcre *shell;
|
struct pattern *app_id;
|
||||||
pcre *app_id;
|
struct pattern *con_mark;
|
||||||
pcre *con_mark;
|
|
||||||
uint32_t con_id; // internal ID
|
uint32_t con_id; // internal ID
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
pcre *class;
|
struct pattern *class;
|
||||||
uint32_t id; // X11 window ID
|
uint32_t id; // X11 window ID
|
||||||
pcre *instance;
|
struct pattern *instance;
|
||||||
pcre *window_role;
|
struct pattern *window_role;
|
||||||
enum atom_name window_type;
|
enum atom_name window_type;
|
||||||
#endif
|
#endif
|
||||||
bool floating;
|
bool floating;
|
||||||
bool tiling;
|
bool tiling;
|
||||||
char urgent; // 'l' for latest or 'o' for oldest
|
char urgent; // 'l' for latest or 'o' for oldest
|
||||||
pcre *workspace;
|
struct pattern *workspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool criteria_is_empty(struct criteria *criteria);
|
bool criteria_is_empty(struct criteria *criteria);
|
||||||
|
|
349
sway/criteria.c
349
sway/criteria.c
|
@ -16,8 +16,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
bool criteria_is_empty(struct criteria *criteria) {
|
bool criteria_is_empty(struct criteria *criteria) {
|
||||||
return !criteria->autofail
|
return !criteria->title
|
||||||
&& !criteria->title
|
|
||||||
&& !criteria->shell
|
&& !criteria->shell
|
||||||
&& !criteria->app_id
|
&& !criteria->app_id
|
||||||
&& !criteria->con_mark
|
&& !criteria->con_mark
|
||||||
|
@ -35,16 +34,64 @@ bool criteria_is_empty(struct criteria *criteria) {
|
||||||
&& !criteria->workspace;
|
&& !criteria->workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The error pointer is used for parsing functions, and saves having to pass it
|
||||||
|
// as an argument in several places.
|
||||||
|
char *error = NULL;
|
||||||
|
|
||||||
|
// Returns error string on failure or NULL otherwise.
|
||||||
|
static bool generate_regex(pcre **regex, char *value) {
|
||||||
|
const char *reg_err;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
*regex = pcre_compile(value, PCRE_UTF8 | PCRE_UCP, ®_err, &offset, NULL);
|
||||||
|
|
||||||
|
if (!*regex) {
|
||||||
|
const char *fmt = "Regex compilation for '%s' failed: %s";
|
||||||
|
int len = strlen(fmt) + strlen(value) + strlen(reg_err) - 3;
|
||||||
|
error = malloc(len);
|
||||||
|
snprintf(error, len, fmt, value, reg_err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pattern_create(struct pattern **pattern, char *value) {
|
||||||
|
*pattern = calloc(1, sizeof(struct pattern));
|
||||||
|
if (!*pattern) {
|
||||||
|
sway_log(SWAY_ERROR, "Failed to allocate pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(value, "__focused__") == 0) {
|
||||||
|
(*pattern)->match_type = PATTERN_FOCUSED;
|
||||||
|
} else {
|
||||||
|
(*pattern)->match_type = PATTERN_PCRE;
|
||||||
|
if (!generate_regex(&(*pattern)->regex, value)) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pattern_destroy(struct pattern *pattern) {
|
||||||
|
if (pattern) {
|
||||||
|
if (pattern->regex) {
|
||||||
|
pcre_free(pattern->regex);
|
||||||
|
}
|
||||||
|
free(pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void criteria_destroy(struct criteria *criteria) {
|
void criteria_destroy(struct criteria *criteria) {
|
||||||
pcre_free(criteria->title);
|
pattern_destroy(criteria->title);
|
||||||
pcre_free(criteria->shell);
|
pattern_destroy(criteria->shell);
|
||||||
pcre_free(criteria->app_id);
|
pattern_destroy(criteria->app_id);
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
pcre_free(criteria->class);
|
pattern_destroy(criteria->class);
|
||||||
pcre_free(criteria->instance);
|
pattern_destroy(criteria->instance);
|
||||||
pcre_free(criteria->window_role);
|
pattern_destroy(criteria->window_role);
|
||||||
#endif
|
#endif
|
||||||
pcre_free(criteria->con_mark);
|
pattern_destroy(criteria->con_mark);
|
||||||
free(criteria->workspace);
|
free(criteria->workspace);
|
||||||
free(criteria->cmdlist);
|
free(criteria->cmdlist);
|
||||||
free(criteria->raw);
|
free(criteria->raw);
|
||||||
|
@ -99,36 +146,75 @@ static void find_urgent_iterator(struct sway_container *con, void *data) {
|
||||||
|
|
||||||
static bool criteria_matches_view(struct criteria *criteria,
|
static bool criteria_matches_view(struct criteria *criteria,
|
||||||
struct sway_view *view) {
|
struct sway_view *view) {
|
||||||
if (criteria->autofail) {
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
return false;
|
struct sway_container *focus = seat_get_focused_container(seat);
|
||||||
}
|
struct sway_view *focused = focus ? focus->view : NULL;
|
||||||
|
|
||||||
if (criteria->title) {
|
if (criteria->title) {
|
||||||
const char *title = view_get_title(view);
|
const char *title = view_get_title(view);
|
||||||
if (!title || regex_cmp(title, criteria->title) != 0) {
|
if (!title) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->title->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(title, view_get_title(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(title, criteria->title->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->shell) {
|
if (criteria->shell) {
|
||||||
const char *shell = view_get_shell(view);
|
const char *shell = view_get_shell(view);
|
||||||
if (!shell || regex_cmp(shell, criteria->shell) != 0) {
|
if (!shell) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->shell->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(shell, view_get_shell(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(shell, criteria->shell->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->app_id) {
|
if (criteria->app_id) {
|
||||||
const char *app_id = view_get_app_id(view);
|
const char *app_id = view_get_app_id(view);
|
||||||
if (!app_id || regex_cmp(app_id, criteria->app_id) != 0) {
|
if (!app_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->app_id->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(app_id, view_get_app_id(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(app_id, criteria->app_id->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->con_mark) {
|
if (criteria->con_mark) {
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
struct sway_container *con = view->container;
|
struct sway_container *con = view->container;
|
||||||
for (int i = 0; i < con->marks->length; ++i) {
|
for (int i = 0; i < con->marks->length; ++i) {
|
||||||
if (regex_cmp(con->marks->items[i], criteria->con_mark) == 0) {
|
if (regex_cmp(con->marks->items[i], criteria->con_mark->regex) == 0) {
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -154,23 +240,62 @@ static bool criteria_matches_view(struct criteria *criteria,
|
||||||
|
|
||||||
if (criteria->class) {
|
if (criteria->class) {
|
||||||
const char *class = view_get_class(view);
|
const char *class = view_get_class(view);
|
||||||
if (!class || regex_cmp(class, criteria->class) != 0) {
|
if (!class) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->class->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(class, view_get_class(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(class, criteria->class->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->instance) {
|
if (criteria->instance) {
|
||||||
const char *instance = view_get_instance(view);
|
const char *instance = view_get_instance(view);
|
||||||
if (!instance || regex_cmp(instance, criteria->instance) != 0) {
|
if (!instance) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->instance->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(instance, view_get_instance(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(instance, criteria->instance->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->window_role) {
|
if (criteria->window_role) {
|
||||||
const char *role = view_get_window_role(view);
|
const char *window_role = view_get_window_role(view);
|
||||||
if (!role || regex_cmp(role, criteria->window_role) != 0) {
|
if (!window_role) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->window_role->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused && strcmp(window_role, view_get_window_role(focused))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(window_role, criteria->window_role->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->window_type != ATOM_LAST) {
|
if (criteria->window_type != ATOM_LAST) {
|
||||||
|
@ -213,9 +338,23 @@ static bool criteria_matches_view(struct criteria *criteria,
|
||||||
|
|
||||||
if (criteria->workspace) {
|
if (criteria->workspace) {
|
||||||
struct sway_workspace *ws = view->container->workspace;
|
struct sway_workspace *ws = view->container->workspace;
|
||||||
if (!ws || regex_cmp(ws->name, criteria->workspace) != 0) {
|
if (!ws) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (criteria->workspace->match_type) {
|
||||||
|
case PATTERN_FOCUSED:
|
||||||
|
if (focused &&
|
||||||
|
strcmp(ws->name, focused->container->workspace->name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PATTERN_PCRE:
|
||||||
|
if (regex_cmp(ws->name, criteria->workspace->regex) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -258,28 +397,6 @@ list_t *criteria_get_views(struct criteria *criteria) {
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The error pointer is used for parsing functions, and saves having to pass it
|
|
||||||
// as an argument in several places.
|
|
||||||
char *error = NULL;
|
|
||||||
|
|
||||||
// Returns error string on failure or NULL otherwise.
|
|
||||||
static bool generate_regex(pcre **regex, char *value) {
|
|
||||||
const char *reg_err;
|
|
||||||
int offset;
|
|
||||||
|
|
||||||
*regex = pcre_compile(value, PCRE_UTF8 | PCRE_UCP, ®_err, &offset, NULL);
|
|
||||||
|
|
||||||
if (!*regex) {
|
|
||||||
const char *fmt = "Regex compilation for '%s' failed: %s";
|
|
||||||
int len = strlen(fmt) + strlen(value) + strlen(reg_err) - 3;
|
|
||||||
error = malloc(len);
|
|
||||||
snprintf(error, len, fmt, value, reg_err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
static enum atom_name parse_window_type(const char *type) {
|
static enum atom_name parse_window_type(const char *type) {
|
||||||
if (strcasecmp(type, "normal") == 0) {
|
if (strcasecmp(type, "normal") == 0) {
|
||||||
|
@ -363,92 +480,6 @@ static enum criteria_token token_from_name(char *name) {
|
||||||
return T_INVALID;
|
return T_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a property of the focused view.
|
|
||||||
*
|
|
||||||
* Note that we are taking the focused view at the time of criteria parsing, not
|
|
||||||
* at the time of execution. This is because __focused__ only makes sense when
|
|
||||||
* using criteria via IPC. Using __focused__ in config is not useful because
|
|
||||||
* criteria is only executed once per view.
|
|
||||||
*/
|
|
||||||
static char *get_focused_prop(enum criteria_token token, bool *autofail) {
|
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
|
||||||
struct sway_container *focus = seat_get_focused_container(seat);
|
|
||||||
|
|
||||||
struct sway_view *view = focus ? focus->view : NULL;
|
|
||||||
const char *value = NULL;
|
|
||||||
|
|
||||||
switch (token) {
|
|
||||||
case T_APP_ID:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_app_id(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_SHELL:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_shell(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_TITLE:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_title(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_WORKSPACE:
|
|
||||||
*autofail = true;
|
|
||||||
if (focus && focus->workspace) {
|
|
||||||
value = focus->workspace->name;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_CON_ID:
|
|
||||||
*autofail = true;
|
|
||||||
if (view && view->container) {
|
|
||||||
size_t id = view->container->node.id;
|
|
||||||
size_t id_size = snprintf(NULL, 0, "%zu", id) + 1;
|
|
||||||
char *id_str = malloc(id_size);
|
|
||||||
snprintf(id_str, id_size, "%zu", id);
|
|
||||||
value = id_str;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#if HAVE_XWAYLAND
|
|
||||||
case T_CLASS:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_class(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_INSTANCE:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_instance(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_WINDOW_ROLE:
|
|
||||||
*autofail = true;
|
|
||||||
if (view) {
|
|
||||||
value = view_get_window_role(view);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_WINDOW_TYPE: // These do not support __focused__
|
|
||||||
case T_ID:
|
|
||||||
#endif
|
|
||||||
case T_CON_MARK:
|
|
||||||
case T_FLOATING:
|
|
||||||
case T_TILING:
|
|
||||||
case T_URGENT:
|
|
||||||
case T_INVALID:
|
|
||||||
*autofail = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
return strdup(value);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
enum criteria_token token = token_from_name(name);
|
enum criteria_token token = token_from_name(name);
|
||||||
if (token == T_INVALID) {
|
if (token == T_INVALID) {
|
||||||
|
@ -459,20 +490,8 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *effective_value = NULL;
|
|
||||||
if (value && strcmp(value, "__focused__") == 0) {
|
|
||||||
bool autofail = false;
|
|
||||||
effective_value = get_focused_prop(token, &autofail);
|
|
||||||
if (!effective_value && autofail) {
|
|
||||||
criteria->autofail = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (value) {
|
|
||||||
effective_value = strdup(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Require value, unless token is floating or tiled
|
// Require value, unless token is floating or tiled
|
||||||
if (!effective_value && token != T_FLOATING && token != T_TILING) {
|
if (!value && token != T_FLOATING && token != T_TILING) {
|
||||||
const char *fmt = "Token '%s' requires a value";
|
const char *fmt = "Token '%s' requires a value";
|
||||||
int len = strlen(fmt) + strlen(name) - 1;
|
int len = strlen(fmt) + strlen(name) - 1;
|
||||||
error = malloc(len);
|
error = malloc(len);
|
||||||
|
@ -483,41 +502,48 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
char *endptr = NULL;
|
char *endptr = NULL;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case T_TITLE:
|
case T_TITLE:
|
||||||
generate_regex(&criteria->title, effective_value);
|
pattern_create(&criteria->title, value);
|
||||||
break;
|
break;
|
||||||
case T_SHELL:
|
case T_SHELL:
|
||||||
generate_regex(&criteria->shell, effective_value);
|
pattern_create(&criteria->shell, value);
|
||||||
break;
|
break;
|
||||||
case T_APP_ID:
|
case T_APP_ID:
|
||||||
generate_regex(&criteria->app_id, effective_value);
|
pattern_create(&criteria->app_id, value);
|
||||||
break;
|
break;
|
||||||
case T_CON_ID:
|
case T_CON_ID:
|
||||||
criteria->con_id = strtoul(effective_value, &endptr, 10);
|
if (strcmp(value, "__focused__") == 0) {
|
||||||
if (*endptr != 0) {
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
error = strdup("The value for 'con_id' should be '__focused__' or numeric");
|
struct sway_container *focus = seat_get_focused_container(seat);
|
||||||
|
struct sway_view *view = focus ? focus->view : NULL;
|
||||||
|
criteria->con_id = view ? view->container->node.id : 0;
|
||||||
|
} else {
|
||||||
|
criteria->con_id = strtoul(value, &endptr, 10);
|
||||||
|
if (*endptr != 0) {
|
||||||
|
error = strdup("The value for 'con_id' should be '__focused__' or numeric");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_CON_MARK:
|
case T_CON_MARK:
|
||||||
generate_regex(&criteria->con_mark, effective_value);
|
pattern_create(&criteria->con_mark, value);
|
||||||
break;
|
break;
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
generate_regex(&criteria->class, effective_value);
|
pattern_create(&criteria->class, value);
|
||||||
break;
|
break;
|
||||||
case T_ID:
|
case T_ID:
|
||||||
criteria->id = strtoul(effective_value, &endptr, 10);
|
criteria->id = strtoul(value, &endptr, 10);
|
||||||
if (*endptr != 0) {
|
if (*endptr != 0) {
|
||||||
error = strdup("The value for 'id' should be numeric");
|
error = strdup("The value for 'id' should be numeric");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_INSTANCE:
|
case T_INSTANCE:
|
||||||
generate_regex(&criteria->instance, effective_value);
|
pattern_create(&criteria->instance, value);
|
||||||
break;
|
break;
|
||||||
case T_WINDOW_ROLE:
|
case T_WINDOW_ROLE:
|
||||||
generate_regex(&criteria->window_role, effective_value);
|
pattern_create(&criteria->window_role, value);
|
||||||
break;
|
break;
|
||||||
case T_WINDOW_TYPE:
|
case T_WINDOW_TYPE:
|
||||||
criteria->window_type = parse_window_type(effective_value);
|
criteria->window_type = parse_window_type(value);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case T_FLOATING:
|
case T_FLOATING:
|
||||||
|
@ -527,13 +553,13 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
criteria->tiling = true;
|
criteria->tiling = true;
|
||||||
break;
|
break;
|
||||||
case T_URGENT:
|
case T_URGENT:
|
||||||
if (strcmp(effective_value, "latest") == 0 ||
|
if (strcmp(value, "latest") == 0 ||
|
||||||
strcmp(effective_value, "newest") == 0 ||
|
strcmp(value, "newest") == 0 ||
|
||||||
strcmp(effective_value, "last") == 0 ||
|
strcmp(value, "last") == 0 ||
|
||||||
strcmp(effective_value, "recent") == 0) {
|
strcmp(value, "recent") == 0) {
|
||||||
criteria->urgent = 'l';
|
criteria->urgent = 'l';
|
||||||
} else if (strcmp(effective_value, "oldest") == 0 ||
|
} else if (strcmp(value, "oldest") == 0 ||
|
||||||
strcmp(effective_value, "first") == 0) {
|
strcmp(value, "first") == 0) {
|
||||||
criteria->urgent = 'o';
|
criteria->urgent = 'o';
|
||||||
} else {
|
} else {
|
||||||
error =
|
error =
|
||||||
|
@ -542,12 +568,11 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_WORKSPACE:
|
case T_WORKSPACE:
|
||||||
generate_regex(&criteria->workspace, effective_value);
|
pattern_create(&criteria->workspace, value);
|
||||||
break;
|
break;
|
||||||
case T_INVALID:
|
case T_INVALID:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(effective_value);
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue