]> git.sur5r.net Git - i3/i3/commitdiff
Implement new criterion 'workspace'. 1771/head
authorIngo Bürk <ingo.buerk@tngtech.com>
Mon, 29 Jun 2015 21:58:48 +0000 (23:58 +0200)
committerIngo Bürk <ingo.buerk@tngtech.com>
Tue, 30 Jun 2015 18:53:52 +0000 (20:53 +0200)
If the match expression is a plain number (e.g., '99'), the number of a workspace will be compared strictly. Otherwise, the match expression is taken as a regular expression and compared against the workspace's name.
This allows all of the following:

for_window [workspace=5] ...
for_window [workspace="5:foo"] ...
for_window [workspace="foo"] ...

fixes #1769

docs/userguide
include/data.h
parser-specs/commands.spec
parser-specs/config.spec
src/commands.c
src/config_directives.c
src/match.c
testcases/t/165-for_window.t

index 64f614f53cb1e979c0afd53a9faa30b5efe309d8..65d82d977323903576c68b327086e80afe4807a0 100644 (file)
@@ -1597,14 +1597,16 @@ urgent::
        Compares the urgent state of the window. Can be "latest" or "oldest".
        Matches the latest or oldest urgent window, respectively.
        (The following aliases are also available: newest, last, recent, first)
+workspace::
+       Compares the workspace name of the workspace the window belongs to.
 con_mark::
        Compares the mark set for this container, see <<vim_like_marks>>.
 con_id::
        Compares the i3-internal container ID, which you can get via the IPC
        interface. Handy for scripting.
 
-The criteria +class+, +instance+, +role+, +title+ and +mark+ are actually
-regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
+The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are
+actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
 information on how to use them.
 
 [[exec]]
index e08cdd4c484938c1c9dec5d32e12c7fc8dae2557..66000e45462fa03fda2b5f2b9548aa023b14272d 100644 (file)
@@ -417,6 +417,7 @@ struct Match {
     struct regex *instance;
     struct regex *mark;
     struct regex *window_role;
+    struct regex *workspace;
     xcb_atom_t window_type;
     enum {
         U_DONTCHECK = -1,
index c756dd8b0502052d1b6a283acf8e31febd1d9766..94dc630a8c1e0ab6e7de6e54508dacfcdb4e1b2a 100644 (file)
@@ -51,6 +51,7 @@ state CRITERIA:
   ctype = 'con_mark'    -> CRITERION
   ctype = 'title'       -> CRITERION
   ctype = 'urgent'      -> CRITERION
+  ctype = 'workspace'   -> CRITERION
   ']' -> call cmd_criteria_match_windows(); INITIAL
 
 state CRITERION:
index 932be5fc600f7c635a0b18238231079b587414c7..3767acf8a4847ce21ea074b079c0e04e6dbaaa89 100644 (file)
@@ -170,6 +170,7 @@ state CRITERIA:
   ctype = 'con_mark'    -> CRITERION
   ctype = 'title'       -> CRITERION
   ctype = 'urgent'      -> CRITERION
+  ctype = 'workspace'   -> CRITERION
   ']'
       -> call cfg_criteria_pop_state()
 
index 71b48182e61ca1c47d4c100774f8b17d0c443c77..53921e8654849d94b96ef78690c5e5119ed305f6 100644 (file)
@@ -411,6 +411,11 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue) {
         return;
     }
 
+    if (strcmp(ctype, "workspace") == 0) {
+        current_match->workspace = regex_new(cvalue);
+        return;
+    }
+
     ELOG("Unknown criterion: %s\n", ctype);
 }
 
index 0e477b703928ba11d44631141406c1b718c4ba8e..91f408d5e76ba860a3c719795e7150bfbcee3a43 100644 (file)
@@ -137,6 +137,11 @@ CFGFUN(criteria_add, const char *ctype, const char *cvalue) {
         return;
     }
 
+    if (strcmp(ctype, "workspace") == 0) {
+        current_match->workspace = regex_new(cvalue);
+        return;
+    }
+
     ELOG("Unknown criterion: %s\n", ctype);
 }
 
index f1bc8430d45fca43db596b293dd71bfed959304d..03a9cbee32c161f1c98b931e437abe0b93d6ab7b 100644 (file)
@@ -48,6 +48,7 @@ bool match_is_empty(Match *match) {
             match->class == NULL &&
             match->instance == NULL &&
             match->window_role == NULL &&
+            match->workspace == NULL &&
             match->urgent == U_DONTCHECK &&
             match->id == XCB_NONE &&
             match->window_type == UINT32_MAX &&
@@ -78,6 +79,7 @@ void match_copy(Match *dest, Match *src) {
     DUPLICATE_REGEX(class);
     DUPLICATE_REGEX(instance);
     DUPLICATE_REGEX(window_role);
+    DUPLICATE_REGEX(workspace);
 }
 
 /*
@@ -172,6 +174,19 @@ bool match_matches_window(Match *match, i3Window *window) {
         LOG("urgent matches oldest\n");
     }
 
+    if (match->workspace != NULL) {
+        Con *con = con_by_window_id(window->id);
+        assert(con != NULL);
+        Con *ws = con_get_workspace(con);
+        assert(ws != NULL);
+
+        if (regex_matches(match->workspace, ws->name)) {
+            LOG("workspace matches (%s)\n", ws->name);
+        } else {
+            return false;
+        }
+    }
+
     if (match->dock != M_DONTCHECK) {
         if ((window->dock == W_DOCK_TOP && match->dock == M_DOCK_TOP) ||
             (window->dock == W_DOCK_BOTTOM && match->dock == M_DOCK_BOTTOM) ||
index b684d41fca41f7e10c645a6400ad08ddcc4ad806..985a7bfd687ec5e8d44e99c81d6ef64a1bafaeca 100644 (file)
@@ -17,6 +17,8 @@
 use i3test i3_autostart => 0;
 use X11::XCB qw(PROP_MODE_REPLACE);
 
+my (@nodes);
+
 ##############################################################
 # 1: test the following directive:
 #    for_window [class="borderless"] border none
@@ -435,6 +437,27 @@ EOT
 
 }
 
+##############################################################
+# 12: check that the criterion 'workspace' works
+##############################################################
+
+$config = <<"EOT";
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [workspace="trigger"] floating enable, mark triggered
+EOT
+
+$pid = launch_with_config($config);
+
+cmd 'workspace trigger';
+$window = open_window;
+
+@nodes = @{get_ws('trigger')->{floating_nodes}};
+cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
+is($nodes[0]->{nodes}[0]->{mark}, 'triggered', "mark set for workspace criterion");
+
+exit_gracefully($pid);
+
 ##############################################################
 
 done_testing;