diff --git a/docs/userguide b/docs/userguide index 5a0e8f8a..674d2b2a 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1,7 +1,7 @@ i3 User’s Guide =============== Michael Stapelberg -October 2011 +January 2012 This document contains all the information you need to configure and use the i3 window manager. If it does not, please contact us on IRC (preferred) or post your @@ -1168,7 +1168,8 @@ bindsym mod+t floating toggle === Focusing/Moving containers -To change the focus, use the focus command: +focus left+, +focus right+, +focus down+ and +focus up+. +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: @@ -1183,6 +1184,9 @@ tiling:: Sets focus to the last focused tiling container. mode_toggle:: Toggles between floating/tiling containers. +output:: + Followed by a direction or an output name, this will focus the + corresponding output. For moving, use +move left+, +move right+, +move down+ and +move up+. @@ -1190,6 +1194,7 @@ For moving, use +move left+, +move right+, +move down+ and +move up+. ----------------------------------- focus focus +focus output <|output> move [ px] ----------------------------------- @@ -1210,6 +1215,12 @@ bindsym mod+u focus parent # Focus last floating/tiling container bindsym mod+g focus mode_toggle +# Focus the output right to the current one +bindsym mod+x focus output right + +# Focus the big output +bindsym mod+x focus output HDMI-2 + # Move container to the left, bottom, top, right: bindsym mod+j move left bindsym mod+k move down diff --git a/src/cmdparse.y b/src/cmdparse.y index 7425c31d..3f13c72b 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -3,7 +3,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) * * cmdparse.y: the parser for commands you send to i3 (or bind on keys) * @@ -528,6 +528,54 @@ focus: tree_render(); } + | TOK_FOCUS TOK_OUTPUT STR + { + owindow *current; + + HANDLE_EMPTY_MATCH; + + /* get the output */ + Output *current_output = NULL; + Output *output; + + TAILQ_FOREACH(current, &owindows, owindows) + current_output = get_output_containing(current->con->rect.x, current->con->rect.y); + assert(current_output != NULL); + + if (strcasecmp($3, "left") == 0) { + output = get_output_next(D_LEFT, current_output); + if (!output) + output = get_output_most(D_RIGHT, current_output); + } else if (strcasecmp($3, "right") == 0) { + output = get_output_next(D_RIGHT, current_output); + if (!output) + output = get_output_most(D_LEFT, current_output); + } else if (strcasecmp($3, "up") == 0) { + output = get_output_next(D_UP, current_output); + if (!output) + output = get_output_most(D_DOWN, current_output); + } else if (strcasecmp($3, "down") == 0) { + output = get_output_next(D_DOWN, current_output); + if (!output) + output = get_output_most(D_UP, current_output); + } else output = get_output_by_name($3); + + free($3); + + if (!output) { + printf("No such output found.\n"); + break; + } + + /* get visible workspace on output */ + Con *ws = NULL; + GREP_FIRST(ws, output_get_content(output->con), workspace_is_visible(child)); + if (!ws) + break; + + workspace_show(ws); + tree_render(); + } | TOK_FOCUS window_mode { if (focused && diff --git a/testcases/t/502-focus-output.t b/testcases/t/502-focus-output.t new file mode 100644 index 00000000..139b670a --- /dev/null +++ b/testcases/t/502-focus-output.t @@ -0,0 +1,50 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Verifies the 'focus output' command works properly. + +use i3test; +use List::Util qw(first); + +my $tmp = fresh_workspace; +my $i3 = i3(get_socket_path()); + +################################################################################ +# use 'focus output' and verify that focus gets changed appropriately +################################################################################ + +sub focused_output { + my $tree = $i3->get_tree->recv; + my $focused = $tree->{focus}->[0]; + my $output = first { $_->{id} == $focused } @{$tree->{nodes}}; + return $output->{name}; +} + +is(focused_output, 'xinerama-0', 'focus on first output'); + +cmd 'focus output right'; +is(focused_output, 'xinerama-1', 'focus on second output'); + +# focus should wrap when we focus to the right again. +cmd 'focus output right'; +is(focused_output, 'xinerama-0', 'focus on first output again'); + +cmd 'focus output left'; +is(focused_output, 'xinerama-1', 'focus back on second output'); + +cmd 'focus output left'; +is(focused_output, 'xinerama-0', 'focus on first output again'); + +cmd 'focus output up'; +is(focused_output, 'xinerama-0', 'focus still on first output'); + +cmd 'focus output down'; +is(focused_output, 'xinerama-0', 'focus still on first output'); + +cmd 'focus output xinerama-1'; +is(focused_output, 'xinerama-1', 'focus on second output'); + +cmd 'focus output xinerama-0'; +is(focused_output, 'xinerama-0', 'focus on first output'); + +done_testing;