Allow matching class, name and role in If action
This commit is contained in:
parent
780b2428a2
commit
1d1fe5e6cc
1 changed files with 92 additions and 34 deletions
|
@ -30,6 +30,22 @@ typedef enum {
|
||||||
QUERY_TARGET_IS_FOCUS_TARGET,
|
QUERY_TARGET_IS_FOCUS_TARGET,
|
||||||
} QueryTarget;
|
} QueryTarget;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MATCH_TYPE_NONE = 0,
|
||||||
|
MATCH_TYPE_PATTERN,
|
||||||
|
MATCH_TYPE_REGEX,
|
||||||
|
MATCH_TYPE_EXACT,
|
||||||
|
} MatchType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MatchType type;
|
||||||
|
union m {
|
||||||
|
GPatternSpec *pattern;
|
||||||
|
GRegex *regex;
|
||||||
|
gchar *exact;
|
||||||
|
} m;
|
||||||
|
} TypedMatch;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
QueryTarget target;
|
QueryTarget target;
|
||||||
gboolean shaded_on;
|
gboolean shaded_on;
|
||||||
|
@ -55,9 +71,10 @@ typedef struct {
|
||||||
guint desktop_number;
|
guint desktop_number;
|
||||||
guint screendesktop_number;
|
guint screendesktop_number;
|
||||||
guint client_monitor;
|
guint client_monitor;
|
||||||
GPatternSpec *matchtitle;
|
TypedMatch title;
|
||||||
GRegex *regextitle;
|
TypedMatch class;
|
||||||
gchar *exacttitle;
|
TypedMatch name;
|
||||||
|
TypedMatch role;
|
||||||
} Query;
|
} Query;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -97,6 +114,60 @@ static inline void set_bool(xmlNodePtr node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setup_typed_match(TypedMatch *tm, xmlNodePtr n)
|
||||||
|
{
|
||||||
|
gchar *s;
|
||||||
|
if ((s = obt_xml_node_string(n))) {
|
||||||
|
gchar *type = NULL;
|
||||||
|
if (!obt_xml_attr_string(n, "type", &type) ||
|
||||||
|
!g_ascii_strcasecmp(type, "pattern"))
|
||||||
|
{
|
||||||
|
tm->type = MATCH_TYPE_PATTERN;
|
||||||
|
tm->m.pattern = g_pattern_spec_new(s);
|
||||||
|
} else if (type && !g_ascii_strcasecmp(type, "regex")) {
|
||||||
|
tm->type = MATCH_TYPE_REGEX;
|
||||||
|
tm->m.regex = g_regex_new(s, 0, 0, NULL);
|
||||||
|
} else if (type && !g_ascii_strcasecmp(type, "exact")) {
|
||||||
|
tm->type = MATCH_TYPE_EXACT;
|
||||||
|
tm->m.exact = g_strdup(s);
|
||||||
|
}
|
||||||
|
g_free(s);
|
||||||
|
g_free(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_typed_match(TypedMatch *tm)
|
||||||
|
{
|
||||||
|
switch (tm->type) {
|
||||||
|
case MATCH_TYPE_PATTERN:
|
||||||
|
g_pattern_spec_free(tm->m.pattern);
|
||||||
|
break;
|
||||||
|
case MATCH_TYPE_REGEX:
|
||||||
|
g_regex_unref(tm->m.regex);
|
||||||
|
break;
|
||||||
|
case MATCH_TYPE_EXACT:
|
||||||
|
g_free(tm->m.exact);
|
||||||
|
break;
|
||||||
|
case MATCH_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean check_typed_match(TypedMatch *tm, gchar *s)
|
||||||
|
{
|
||||||
|
switch (tm->type) {
|
||||||
|
case MATCH_TYPE_PATTERN:
|
||||||
|
return g_pattern_match_string(tm->m.pattern, s);
|
||||||
|
case MATCH_TYPE_REGEX:
|
||||||
|
return g_regex_match(tm->m.regex, s, 0, NULL);
|
||||||
|
case MATCH_TYPE_EXACT:
|
||||||
|
return !strcmp(tm->m.exact, s);
|
||||||
|
case MATCH_TYPE_NONE:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_query(Options* o, xmlNodePtr node, QueryTarget target) {
|
static void setup_query(Options* o, xmlNodePtr node, QueryTarget target) {
|
||||||
Query *q = g_slice_new0(Query);
|
Query *q = g_slice_new0(Query);
|
||||||
g_array_append_val(o->queries, q);
|
g_array_append_val(o->queries, q);
|
||||||
|
@ -130,19 +201,16 @@ static void setup_query(Options* o, xmlNodePtr node, QueryTarget target) {
|
||||||
q->screendesktop_number = obt_xml_node_int(n);
|
q->screendesktop_number = obt_xml_node_int(n);
|
||||||
}
|
}
|
||||||
if ((n = obt_xml_find_node(node, "title"))) {
|
if ((n = obt_xml_find_node(node, "title"))) {
|
||||||
gchar *s, *type = NULL;
|
setup_typed_match(&q->title, n);
|
||||||
if ((s = obt_xml_node_string(n))) {
|
}
|
||||||
if (!obt_xml_attr_string(n, "type", &type) ||
|
if ((n = obt_xml_find_node(node, "class"))) {
|
||||||
!g_ascii_strcasecmp(type, "pattern"))
|
setup_typed_match(&q->class, n);
|
||||||
{
|
}
|
||||||
q->matchtitle = g_pattern_spec_new(s);
|
if ((n = obt_xml_find_node(node, "name"))) {
|
||||||
} else if (type && !g_ascii_strcasecmp(type, "regex")) {
|
setup_typed_match(&q->name, n);
|
||||||
q->regextitle = g_regex_new(s, 0, 0, NULL);
|
}
|
||||||
} else if (type && !g_ascii_strcasecmp(type, "exact")) {
|
if ((n = obt_xml_find_node(node, "role"))) {
|
||||||
q->exacttitle = g_strdup(s);
|
setup_typed_match(&q->role, n);
|
||||||
}
|
|
||||||
g_free(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((n = obt_xml_find_node(node, "monitor"))) {
|
if ((n = obt_xml_find_node(node, "monitor"))) {
|
||||||
q->client_monitor = obt_xml_node_int(n);
|
q->client_monitor = obt_xml_node_int(n);
|
||||||
|
@ -211,12 +279,10 @@ static void free_func(gpointer options)
|
||||||
for (i = 0; i < o->queries->len; ++i) {
|
for (i = 0; i < o->queries->len; ++i) {
|
||||||
Query *q = g_array_index(o->queries, Query*, i);
|
Query *q = g_array_index(o->queries, Query*, i);
|
||||||
|
|
||||||
if (q->matchtitle)
|
free_typed_match(&q->title);
|
||||||
g_pattern_spec_free(q->matchtitle);
|
free_typed_match(&q->class);
|
||||||
if (q->regextitle)
|
free_typed_match(&q->name);
|
||||||
g_regex_unref(q->regextitle);
|
free_typed_match(&q->role);
|
||||||
if (q->exacttitle)
|
|
||||||
g_free(q->exacttitle);
|
|
||||||
|
|
||||||
g_slice_free(Query, q);
|
g_slice_free(Query, q);
|
||||||
}
|
}
|
||||||
|
@ -328,18 +394,10 @@ static gboolean run_func_if(ObActionsData *data, gpointer options)
|
||||||
if (q->screendesktop_number)
|
if (q->screendesktop_number)
|
||||||
is_true &= screen_desktop == q->screendesktop_number - 1;
|
is_true &= screen_desktop == q->screendesktop_number - 1;
|
||||||
|
|
||||||
if (q->matchtitle) {
|
is_true &= check_typed_match(&q->title, query_target->original_title);
|
||||||
is_true &= g_pattern_match_string(q->matchtitle,
|
is_true &= check_typed_match(&q->class, query_target->class);
|
||||||
query_target->original_title);
|
is_true &= check_typed_match(&q->name, query_target->name);
|
||||||
}
|
is_true &= check_typed_match(&q->role, query_target->role);
|
||||||
if (q->regextitle) {
|
|
||||||
is_true &= g_regex_match(q->regextitle,
|
|
||||||
query_target->original_title,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
if (q->exacttitle)
|
|
||||||
is_true &= !strcmp(q->exacttitle, query_target->original_title);
|
|
||||||
|
|
||||||
if (q->client_monitor)
|
if (q->client_monitor)
|
||||||
is_true &= client_monitor(query_target) == q->client_monitor - 1;
|
is_true &= client_monitor(query_target) == q->client_monitor - 1;
|
||||||
|
|
Loading…
Reference in a new issue