diff --git a/include/sway/criteria.h b/include/sway/criteria.h index ae546821c..8ba8c9989 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h @@ -53,6 +53,9 @@ struct criteria { char urgent; // 'l' for latest or 'o' for oldest struct pattern *workspace; pid_t pid; + struct pattern *sandbox_engine; + struct pattern *sandbox_app_id; + struct pattern *sandbox_instance_id; }; bool criteria_is_empty(struct criteria *criteria); diff --git a/sway/criteria.c b/sway/criteria.c index 2b7290c0e..0aefa0080 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -34,7 +34,10 @@ bool criteria_is_empty(struct criteria *criteria) { && !criteria->tiling && !criteria->urgent && !criteria->workspace - && !criteria->pid; + && !criteria->pid + && !criteria->sandbox_engine + && !criteria->sandbox_app_id + && !criteria->sandbox_instance_id; } // The error pointer is used for parsing functions, and saves having to pass it @@ -98,6 +101,9 @@ void criteria_destroy(struct criteria *criteria) { #endif pattern_destroy(criteria->con_mark); pattern_destroy(criteria->workspace); + pattern_destroy(criteria->sandbox_engine); + pattern_destroy(criteria->sandbox_app_id); + pattern_destroy(criteria->sandbox_instance_id); free(criteria->target); free(criteria->cmdlist); free(criteria->raw); @@ -248,6 +254,66 @@ static bool criteria_matches_view(struct criteria *criteria, } } + if (criteria->sandbox_engine) { + const char *sandbox_engine = view_get_sandbox_engine(view); + if (!sandbox_engine) { + return false; + } + + switch (criteria->sandbox_engine->match_type) { + case PATTERN_FOCUSED: + if (focused && lenient_strcmp(sandbox_engine, view_get_sandbox_engine(focused))) { + return false; + } + break; + case PATTERN_PCRE2: + if (regex_cmp(sandbox_engine, criteria->sandbox_engine->regex) < 0) { + return false; + } + break; + } + } + + if (criteria->sandbox_app_id) { + const char *sandbox_app_id = view_get_sandbox_app_id(view); + if (!sandbox_app_id) { + return false; + } + + switch (criteria->sandbox_app_id->match_type) { + case PATTERN_FOCUSED: + if (focused && lenient_strcmp(sandbox_app_id, view_get_sandbox_app_id(focused))) { + return false; + } + break; + case PATTERN_PCRE2: + if (regex_cmp(sandbox_app_id, criteria->sandbox_app_id->regex) < 0) { + return false; + } + break; + } + } + + if (criteria->sandbox_instance_id) { + const char *sandbox_instance_id = view_get_sandbox_instance_id(view); + if (!sandbox_instance_id) { + return false; + } + + switch (criteria->sandbox_instance_id->match_type) { + case PATTERN_FOCUSED: + if (focused && lenient_strcmp(sandbox_instance_id, view_get_sandbox_instance_id(focused))) { + return false; + } + break; + case PATTERN_PCRE2: + if (regex_cmp(sandbox_instance_id, criteria->sandbox_instance_id->regex) < 0) { + return false; + } + break; + } + } + if (!criteria_matches_container(criteria, view->container)) { return false; } @@ -475,6 +541,9 @@ enum criteria_token { T_URGENT, T_WORKSPACE, T_PID, + T_SANDBOX_ENGINE, + T_SANDBOX_APP_ID, + T_SANDBOX_INSTANCE_ID, T_INVALID, }; @@ -514,6 +583,12 @@ static enum criteria_token token_from_name(char *name) { return T_FLOATING; } else if (strcmp(name, "pid") == 0) { return T_PID; + } else if (strcmp(name, "sandbox_engine") == 0) { + return T_SANDBOX_ENGINE; + } else if (strcmp(name, "sandbox_app_id") == 0) { + return T_SANDBOX_APP_ID; + } else if (strcmp(name, "sandbox_instance_id") == 0) { + return T_SANDBOX_INSTANCE_ID; } return T_INVALID; } @@ -617,6 +692,15 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { error = strdup("The value for 'pid' should be numeric"); } break; + case T_SANDBOX_ENGINE: + pattern_create(&criteria->sandbox_engine, value); + break; + case T_SANDBOX_APP_ID: + pattern_create(&criteria->sandbox_app_id, value); + break; + case T_SANDBOX_INSTANCE_ID: + pattern_create(&criteria->sandbox_instance_id, value); + break; case T_INVALID: break; } diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 5e4df0dc7..4def2cbb1 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -1058,6 +1058,22 @@ The following attributes may be matched with: expression. If the value is \_\_focused\_\_, then all the views on the currently focused workspace matches. +*sandbox_engine* + Compare against the associated sandbox engine. Can be a regular expression. + If the value is \_\_focused\_\_, then the sandbox engine must be the same as + that of the currently focused window. + +*sandbox_app_id* + Compare against the app ID provided by the associated sandbox engine. Can be + a regular expression. If the value is \_\_focused\_\_, then the sandbox app + ID must be the same as that of the currently focused window. + +*sandbox_instance_id* + Compare against the instance ID provided by the associated sandbox engine. + Can be a regular expression. If the value is \_\_focused\_\_, then the + sandbox instance ID must be the same as that of the currently focused + window. + # SEE ALSO *sway*(1) *sway-input*(5) *sway-output*(5) *sway-bar*(5) *sway-ipc*(7)