From 6a8fb69eff913e4ebb9a07cb2f77f59320d93805 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Wed, 28 Sep 2016 04:04:00 +0200 Subject: [PATCH] Added new criteria 'tiling' / 'floating'. (#2481) These criteria allow selecting only windows in a specific mode, i.e., tiling and floating, respectively. fixes #2406 --- docs/userguide | 7 +++++++ include/data.h | 6 +++--- parser-specs/commands.spec | 2 ++ parser-specs/config.spec | 2 ++ src/match.c | 28 +++++++++++++++++++++++++++- testcases/t/165-for_window.t | 27 +++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/userguide b/docs/userguide index 9472fdd7..93c54467 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1679,6 +1679,9 @@ bindsym $mod+x [class="Firefox" window_role="About"] kill # enable floating mode and move container to workspace 4 for_window [class="^evil-app$"] floating enable, move container to workspace 4 + +# move all floating windows to the scratchpad +bindsym $mod+x [floating] move scratchpad ------------------------------------ The criteria which are currently implemented are: @@ -1721,6 +1724,10 @@ con_id:: Compares the i3-internal container ID, which you can get via the IPC interface. Handy for scripting. Use the special value +\_\_focused__+ to match only the currently focused window. +floating:: + Only matches floating windows. This criterion requires no value. +tiling:: + Only matches tiling windows. This criterion requires no value. The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for diff --git a/include/data.h b/include/data.h index 247cd3c5..70edd222 100644 --- a/include/data.h +++ b/include/data.h @@ -474,9 +474,9 @@ struct Match { M_DOCK_BOTTOM = 3 } dock; xcb_window_t id; - enum { M_ANY = 0, - M_TILING, - M_FLOATING } floating; + enum { WM_ANY = 0, + WM_TILING, + WM_FLOATING } window_mode; Con *con_id; /* Where the window looking for a match should be inserted: diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index ec7fbabf..d4b3dbc6 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -53,6 +53,8 @@ state CRITERIA: ctype = 'title' -> CRITERION ctype = 'urgent' -> CRITERION ctype = 'workspace' -> CRITERION + ctype = 'tiling', 'floating' + -> call cmd_criteria_add($ctype, NULL); CRITERIA ']' -> call cmd_criteria_match_windows(); INITIAL state CRITERION: diff --git a/parser-specs/config.spec b/parser-specs/config.spec index eeafaac8..90296819 100644 --- a/parser-specs/config.spec +++ b/parser-specs/config.spec @@ -173,6 +173,8 @@ state CRITERIA: ctype = 'title' -> CRITERION ctype = 'urgent' -> CRITERION ctype = 'workspace' -> CRITERION + ctype = 'tiling', 'floating' + -> call cfg_criteria_add($ctype, NULL); CRITERIA ']' -> call cfg_criteria_pop_state() diff --git a/src/match.c b/src/match.c index ba87eb23..ac9ddaf9 100644 --- a/src/match.c +++ b/src/match.c @@ -28,6 +28,7 @@ void match_init(Match *match) { memset(match, 0, sizeof(Match)); match->urgent = U_DONTCHECK; + match->window_mode = WM_ANY; /* we use this as the placeholder value for "not set". */ match->window_type = UINT32_MAX; } @@ -53,7 +54,7 @@ bool match_is_empty(Match *match) { match->window_type == UINT32_MAX && match->con_id == NULL && match->dock == M_NODOCK && - match->floating == M_ANY); + match->window_mode == WM_ANY); } /* @@ -243,6 +244,21 @@ bool match_matches_window(Match *match, i3Window *window) { } } + if (match->window_mode != WM_ANY) { + if ((con = con_by_window_id(window->id)) == NULL) + return false; + + const bool floating = (con_inside_floating(con) != NULL); + + if ((match->window_mode == WM_TILING && floating) || + (match->window_mode == WM_FLOATING && !floating)) { + LOG("window_mode does not match\n"); + return false; + } + + LOG("window_mode matches\n"); + } + return true; } @@ -384,5 +400,15 @@ void match_parse_property(Match *match, const char *ctype, const char *cvalue) { return; } + if (strcmp(ctype, "tiling") == 0) { + match->window_mode = WM_TILING; + return; + } + + if (strcmp(ctype, "floating") == 0) { + match->window_mode = WM_FLOATING; + return; + } + ELOG("Unknown criterion: %s\n", ctype); } diff --git a/testcases/t/165-for_window.t b/testcases/t/165-for_window.t index 025fe21c..bc3df114 100644 --- a/testcases/t/165-for_window.t +++ b/testcases/t/165-for_window.t @@ -459,6 +459,33 @@ is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'triggered' ], "mark set for workspa exit_gracefully($pid); +############################################################## +# 13: check that the tiling / floating criteria work. +############################################################## + +$config = <<"EOT"; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +for_window [tiling] mark tiled +for_window [floating] mark floated +EOT + +$pid = launch_with_config($config); +$tmp = fresh_workspace; + +open_window; +open_floating_window; + +@nodes = @{get_ws($tmp)->{nodes}}; +cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace'); +is_deeply($nodes[0]->{marks}, [ 'tiled' ], "mark set for 'tiling' criterion"); + +@nodes = @{get_ws($tmp)->{floating_nodes}}; +cmp_ok(@nodes, '==', 1, 'one floating container on this workspace'); +is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floated' ], "mark set for 'floating' criterion"); + +exit_gracefully($pid); + ############################################################## done_testing; -- 2.39.5