From c408fef021aba127f4d627a1bbbd42f6cf04575b Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 4 Jul 2011 17:09:52 +0200 Subject: [PATCH] Implement 'focus floating', 'focus tiling' and 'focus mode_toggle' (+test +docs) --- docs/userguide | 46 ++++++++++++++------------------- src/cmdparse.l | 1 + src/cmdparse.y | 40 ++++++++++++++++++++++++++++ testcases/t/35-floating-focus.t | 46 +++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 26 deletions(-) diff --git a/docs/userguide b/docs/userguide index 6c5ba10b..60d8d63d 100644 --- a/docs/userguide +++ b/docs/userguide @@ -627,6 +627,20 @@ bindsym Mod1+t floating toggle To change the focus, use the focus command: +focus left+, +focus right+, +focus down+ and +focus up+. +There are a few special parameters you can use for the focus command: + +parent:: + Sets focus to the +Parent Container+ of the current +Container+. +child:: + The opposite of +focus parent+, sets the focus to the last focused + child container. +floating:: + Sets focus to the last focused floating container. +tiling:: + Sets focus to the last focused tiling container. +mode_toggle:: + Toggles between floating/tiling containers. + For moving, use +move left+, +move right+, +move down+ and +move up+. *Examples*: @@ -637,6 +651,12 @@ bindsym Mod1+k focus down bindsym Mod1+l focus up bindsym Mod1+semicolon focus right +# Focus parent container +bindsym Mod1+u focus parent + +# Focus last floating/tiling container +bindsym Mod1+g focus mode_toggle + # Move client to the left, bottom, top, right: bindsym Mod1+j move left bindsym Mod1+k move down @@ -758,32 +778,6 @@ Alternatively, if you do not want to mess with +i3-input+, you could create seperate bindings for a specific set of labels and then only use those labels. /////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -TODO: not yet implemented -=== Traveling the focus stack - -This mechanism can be thought of as the opposite of the +jump+ command. -It travels the focus stack and jumps to the window which had focus previously. - -*Syntax*: --------------- -focus [number] | floating | tiling | ft --------------- - -Where +number+ by default is 1 meaning that the next client in the focus stack -will be selected. - -The special values have the following meaning: - -floating:: - The next floating window is selected. -tiling:: - The next tiling window is selected. -ft:: - If the current window is floating, the next tiling window will be - selected; and vice-versa. -/////////////////////////////////////////////////////////////////////////////// - === Changing border style To change the border of the current client, you can use +border normal+ to use the normal diff --git a/src/cmdparse.l b/src/cmdparse.l index 9a0bc903..898416c2 100644 --- a/src/cmdparse.l +++ b/src/cmdparse.l @@ -121,6 +121,7 @@ mode { BEGIN(WANT_QSTRING); return TOK_MODE; } tiling { return TOK_TILING; } floating { return TOK_FLOATING; } toggle { return TOK_TOGGLE; } +mode_toggle { return TOK_MODE_TOGGLE; } workspace { WS_STRING; return TOK_WORKSPACE; } focus { return TOK_FOCUS; } move { return TOK_MOVE; } diff --git a/src/cmdparse.y b/src/cmdparse.y index fbc2307f..95dc27b6 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -135,6 +135,7 @@ char *parse_cmd(const char *new) { %token TOK_MODE "mode" %token TOK_TILING "tiling" %token TOK_FLOATING "floating" +%token TOK_MODE_TOGGLE "mode_toggle" %token TOK_ENABLE "enable" %token TOK_DISABLE "disable" %token TOK_WORKSPACE "workspace" @@ -175,6 +176,7 @@ char *parse_cmd(const char *new) { %type split_direction %type fullscreen_mode %type level +%type window_mode %type boolean %type border_style %type layout_mode @@ -447,6 +449,38 @@ focus: tree_render(); } + | TOK_FOCUS window_mode + { + printf("should focus: "); + + if ($2 == TOK_TILING) + printf("tiling\n"); + else if ($2 == TOK_FLOATING) + printf("floating\n"); + else printf("mode toggle\n"); + + Con *ws = con_get_workspace(focused); + Con *current; + if (ws != NULL) { + int to_focus = $2; + if ($2 == TOK_MODE_TOGGLE) { + current = TAILQ_FIRST(&(ws->focus_head)); + if (current->type == CT_FLOATING_CON) + to_focus = TOK_TILING; + else to_focus = TOK_FLOATING; + } + TAILQ_FOREACH(current, &(ws->focus_head), focused) { + if ((to_focus == TOK_FLOATING && current->type != CT_FLOATING_CON) || + (to_focus == TOK_TILING && current->type == CT_FLOATING_CON)) + continue; + + con_focus(con_descend_focused(current)); + break; + } + } + + tree_render(); + } | TOK_FOCUS level { if ($2 == TOK_PARENT) @@ -457,6 +491,12 @@ focus: } ; +window_mode: + TOK_TILING { $$ = TOK_TILING; } + | TOK_FLOATING { $$ = TOK_FLOATING; } + | TOK_MODE_TOGGLE { $$ = TOK_MODE_TOGGLE; } + ; + level: TOK_PARENT { $$ = TOK_PARENT; } | TOK_CHILD { $$ = TOK_CHILD; } diff --git a/testcases/t/35-floating-focus.t b/testcases/t/35-floating-focus.t index 7d5cf53b..3f820ea5 100644 --- a/testcases/t/35-floating-focus.t +++ b/testcases/t/35-floating-focus.t @@ -125,4 +125,50 @@ sleep 0.25; is($x->input_focus, $first->id, 'first con focused after killing all floating cons'); +############################################################################# +# 5: see if the 'focus tiling' and 'focus floating' commands work +############################################################################# + +$tmp = fresh_workspace; + +$first = open_standard_window($x, '#ff0000'); # window 8 +$second = open_standard_window($x, '#00ff00'); # window 9 + +is($x->input_focus, $second->id, 'second container focused'); + +cmd 'floating enable'; + +is($x->input_focus, $second->id, 'second container focused'); + +cmd 'focus tiling'; + +sleep 0.25; + +is($x->input_focus, $first->id, 'first (tiling) container focused'); + +cmd 'focus floating'; + +sleep 0.25; + +is($x->input_focus, $second->id, 'second (floating) container focused'); + +cmd 'focus floating'; + +sleep 0.25; + +is($x->input_focus, $second->id, 'second (floating) container still focused'); + +cmd 'focus mode_toggle'; + +sleep 0.25; + +is($x->input_focus, $first->id, 'first (tiling) container focused'); + +cmd 'focus mode_toggle'; + +sleep 0.25; + +is($x->input_focus, $second->id, 'second (floating) container focused'); + + done_testing;