From 92cc4494aa0a273d1c0bb170051b450b82437884 Mon Sep 17 00:00:00 2001 From: Noe Rubinstein Date: Sun, 2 Oct 2011 17:54:23 +0200 Subject: [PATCH 1/5] refactor workspace_show and friends --- include/workspace.h | 11 ++++++----- src/cmdparse.y | 8 ++++---- src/con.c | 4 ++-- src/randr.c | 6 +++--- src/tree.c | 2 +- src/workspace.c | 35 +++++++++++++++++++++-------------- 6 files changed, 37 insertions(+), 29 deletions(-) diff --git a/include/workspace.h b/include/workspace.h index aebf1365..7eee9d3d 100644 --- a/include/workspace.h +++ b/include/workspace.h @@ -47,19 +47,20 @@ void workspace_set_name(Workspace *ws, const char *name); bool workspace_is_visible(Con *ws); /** Switches to the given workspace */ -void workspace_show(const char *num); +void workspace_show(Con *ws); +void workspace_show_by_name(const char *num); /** - * Focuses the next workspace. + * Returns the next workspace. * */ -void workspace_next(); +Con* workspace_next(); /** - * Focuses the previous workspace. + * Returns the previous workspace. * */ -void workspace_prev(); +Con* workspace_prev(); #if 0 /** diff --git a/src/cmdparse.y b/src/cmdparse.y index 04e8b3ca..252f6dff 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -440,7 +440,7 @@ focus: int count = 0; TAILQ_FOREACH(current, &owindows, owindows) { Con *ws = con_get_workspace(current->con); - workspace_show(ws->name); + workspace_show(ws); LOG("focusing %p / %s\n", current->con, current->con->name); con_focus(current->con); count++; @@ -561,18 +561,18 @@ optional_kill_mode: workspace: TOK_WORKSPACE TOK_NEXT { - workspace_next(); + workspace_show(workspace_next()); tree_render(); } | TOK_WORKSPACE TOK_PREV { - workspace_prev(); + workspace_show(workspace_prev()); tree_render(); } | TOK_WORKSPACE STR { printf("should switch to workspace %s\n", $2); - workspace_show($2); + workspace_show_by_name($2); free($2); tree_render(); diff --git a/src/con.c b/src/con.c index 8fbedd3d..805d33b8 100644 --- a/src/con.c +++ b/src/con.c @@ -632,7 +632,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool * focused. Must do before attaching because workspace_show checks to see * if focused container is in its area. */ if (workspace_is_visible(workspace)) { - workspace_show(workspace->name); + workspace_show(workspace); /* Don’t warp if told so (when dragging floating windows with the * mouse for example) */ @@ -668,7 +668,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool /* Descend focus stack in case focus_next is a workspace which can * occur if we move to the same workspace. Also show current workspace * to ensure it is focused. */ - workspace_show(con_get_workspace(focus_next)->name); + workspace_show(con_get_workspace(focus_next)); con_focus(con_descend_focused(focus_next)); } diff --git a/src/randr.c b/src/randr.c index 2b8757e5..f5f5d198 100644 --- a/src/randr.c +++ b/src/randr.c @@ -363,7 +363,7 @@ void init_ws_for_output(Output *output, Con *content) { if (visible && (previous = TAILQ_NEXT(workspace, focused))) { LOG("Switching to previously used workspace \"%s\" on output \"%s\"\n", previous->name, workspace_out->name); - workspace_show(previous->name); + workspace_show(previous); } con_detach(workspace); @@ -390,7 +390,7 @@ void init_ws_for_output(Output *output, Con *content) { if (!visible) { visible = TAILQ_FIRST(&(content->nodes_head)); focused = content; - workspace_show(visible->name); + workspace_show(visible); } return; } @@ -403,7 +403,7 @@ void init_ws_for_output(Output *output, Con *content) { LOG("Initializing first assigned workspace \"%s\" for output \"%s\"\n", assignment->name, assignment->output); focused = content; - workspace_show(assignment->name); + workspace_show_by_name(assignment->name); return; } diff --git a/src/tree.c b/src/tree.c index 4baba58e..8c73b6ab 100644 --- a/src/tree.c +++ b/src/tree.c @@ -420,7 +420,7 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) if (!workspace) return false; - workspace_show(workspace->name); + workspace_show(workspace); Con *focus = con_descend_direction(workspace, direction); if (focus) { con_focus(focus); diff --git a/src/workspace.c b/src/workspace.c index 32564459..a89029c4 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -180,11 +180,8 @@ static void workspace_reassign_sticky(Con *con) { * Switches to the given workspace * */ -void workspace_show(const char *num) { - Con *workspace, *current, *old = NULL; - - bool changed_num_workspaces; - workspace = workspace_get(num, &changed_num_workspaces); +void workspace_show_changed(Con *workspace, bool changed_num_workspaces) { + Con *current, *old = NULL; /* disable fullscreen for the other workspaces and get the workspace we are * currently on. */ @@ -238,11 +235,22 @@ void workspace_show(const char *num) { ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"focus\"}"); } +void workspace_show(Con *workspace) { + workspace_show_changed(workspace, false); +} + +void workspace_show_by_name(const char *num) { + Con *workspace; + bool changed_num_workspaces; + workspace = workspace_get(num, &changed_num_workspaces); + workspace_show_changed(workspace, changed_num_workspaces); +} + /* * Focuses the next workspace. * */ -void workspace_next() { +Con* workspace_next() { Con *current = con_get_workspace(focused); Con *next = NULL; Con *output; @@ -277,7 +285,7 @@ void workspace_next() { found_current = 1; } else if (child->num == -1 && (current->num != -1 || found_current)) { next = child; - goto workspace_next_show; + goto workspace_next_end; } } } @@ -292,16 +300,15 @@ void workspace_next() { next = child; } } - -workspace_next_show: - workspace_show(next->name); +workspace_next_end: + return next; } /* * Focuses the previous workspace. * */ -void workspace_prev() { +Con* workspace_prev() { Con *current = con_get_workspace(focused); Con *prev = NULL; Con *output; @@ -336,7 +343,7 @@ void workspace_prev() { found_current = 1; } else if (child->num == -1 && (current->num != -1 || found_current)) { prev = child; - goto workspace_prev_show; + goto workspace_prev_end; } } } @@ -352,8 +359,8 @@ void workspace_prev() { } } -workspace_prev_show: - workspace_show(prev->name); +workspace_prev_end: + return prev; } static bool get_urgency_flag(Con *con) { From b2ad9a77c8ad83b9d464f190a3e8607a0daa819f Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 2 Oct 2011 22:03:16 +0100 Subject: [PATCH 2/5] rename the internal function to _workspace_show, add a comment to workspace_show_by_name --- include/workspace.h | 10 +++++++++- src/workspace.c | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/include/workspace.h b/include/workspace.h index 7eee9d3d..3f0e83c2 100644 --- a/include/workspace.h +++ b/include/workspace.h @@ -46,8 +46,16 @@ void workspace_set_name(Workspace *ws, const char *name); */ bool workspace_is_visible(Con *ws); -/** Switches to the given workspace */ +/** + * Switches to the given workspace + * + */ void workspace_show(Con *ws); + +/** + * Looks up the workspace by name and switches to it. + * + */ void workspace_show_by_name(const char *num); /** diff --git a/src/workspace.c b/src/workspace.c index a89029c4..b4ed5530 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -176,11 +176,8 @@ static void workspace_reassign_sticky(Con *con) { workspace_reassign_sticky(current); } -/* - * Switches to the given workspace - * - */ -void workspace_show_changed(Con *workspace, bool changed_num_workspaces) { + +static void _workspace_show(Con *workspace, bool changed_num_workspaces) { Con *current, *old = NULL; /* disable fullscreen for the other workspaces and get the workspace we are @@ -235,15 +232,23 @@ void workspace_show_changed(Con *workspace, bool changed_num_workspaces) { ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"focus\"}"); } -void workspace_show(Con *workspace) { - workspace_show_changed(workspace, false); +/* + * Switches to the given workspace + * + */ +void workspace_show(Con *workspace) { + _workspace_show(workspace, false); } +/* + * Looks up the workspace by name and switches to it. + * + */ void workspace_show_by_name(const char *num) { Con *workspace; bool changed_num_workspaces; workspace = workspace_get(num, &changed_num_workspaces); - workspace_show_changed(workspace, changed_num_workspaces); + _workspace_show(workspace, changed_num_workspaces); } /* From 1eab86b9164a0309338ca72a716437738b9b0ef8 Mon Sep 17 00:00:00 2001 From: Noe Rubinstein Date: Sun, 2 Oct 2011 17:55:19 +0200 Subject: [PATCH 3/5] add "move workspace next" and "move workspace prev" some factorization would be better here, however I don't really know my way around bison --- src/cmdparse.y | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/cmdparse.y b/src/cmdparse.y index 252f6dff..da962cf4 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -715,6 +715,38 @@ move: tree_render(); } + | TOK_MOVE TOK_WORKSPACE TOK_NEXT + { + owindow *current; + + /* get the workspace */ + Con *ws = workspace_next(); + + HANDLE_EMPTY_MATCH; + + TAILQ_FOREACH(current, &owindows, owindows) { + printf("matching: %p / %s\n", current->con, current->con->name); + con_move_to_workspace(current->con, ws, true, false); + } + + tree_render(); + } + | TOK_MOVE TOK_WORKSPACE TOK_PREV + { + owindow *current; + + /* get the workspace */ + Con *ws = workspace_prev(); + + HANDLE_EMPTY_MATCH; + + TAILQ_FOREACH(current, &owindows, owindows) { + printf("matching: %p / %s\n", current->con, current->con->name); + con_move_to_workspace(current->con, ws, true, false); + } + + tree_render(); + } | TOK_MOVE TOK_OUTPUT STR { owindow *current; From 32ea923721f840954567708b4bc8128dfdc984dc Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 2 Oct 2011 22:18:21 +0100 Subject: [PATCH 4/5] add a test for the 'move workspace next/prev' command --- testcases/t/32-move-workspace.t | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/testcases/t/32-move-workspace.t b/testcases/t/32-move-workspace.t index 3b50e39b..82e59dd1 100644 --- a/testcases/t/32-move-workspace.t +++ b/testcases/t/32-move-workspace.t @@ -37,6 +37,39 @@ is($focus->[0], $second, 'same container on different ws'); ($nodes, $focus) = get_ws_content($tmp); ok($nodes->[0]->{focused}, 'first container focused on first ws'); +################################################################### +# check if 'move workspace next' and 'move workspace prev' work +################################################################### + +# Open two containers on the first workspace, one container on the second +# workspace. Because the workspaces are named, they will be sorted by order of +# creation. +$tmp = get_unused_workspace(); +$tmp2 = get_unused_workspace(); +cmd "workspace $tmp"; +ok(@{get_ws_content($tmp)} == 0, 'no containers yet'); +$first = open_empty_con($i3); +$second = open_empty_con($i3); +ok(@{get_ws_content($tmp)} == 2, 'two containers on first ws'); + +cmd "workspace $tmp2"; +ok(@{get_ws_content($tmp2)} == 0, 'no containers yet'); +my $third = open_empty_con($i3); +ok(@{get_ws_content($tmp2)} == 1, 'one container on second ws'); + +# go back to the first workspace, move one of the containers to the next one +cmd "workspace $tmp"; +cmd 'move workspace next'; +ok(@{get_ws_content($tmp)} == 1, 'one container on first ws'); +ok(@{get_ws_content($tmp2)} == 2, 'two containers on second ws'); + +# go to the second workspace and move two containers to the first one +cmd "workspace $tmp2"; +cmd 'move workspace prev'; +cmd 'move workspace prev'; +ok(@{get_ws_content($tmp)} == 3, 'three containers on first ws'); +ok(@{get_ws_content($tmp2)} == 0, 'no containers on second ws'); + ################################################################### # check if floating cons are moved to new workspaces properly # (that is, if they are floating on the target ws, too) From b829fce813bf2d08dc5bb1573a365f91e85e84f1 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 2 Oct 2011 22:21:38 +0100 Subject: [PATCH 5/5] Mention 'move workspace next/prev' in the userguide --- docs/userguide | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/userguide b/docs/userguide index 8b3a6859..27e3b9ed 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1,7 +1,7 @@ i3 User’s Guide =============== Michael Stapelberg -September 2011 +October 2011 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 @@ -889,7 +889,8 @@ number or name of the workspace. To move containers to specific workspaces, use You can also switch to the next and previous workspace with the commands +workspace next+ and +workspace prev+, which is handy, for example, if you have workspace 1, 3, 4 and 9 and you want to cycle through them with a single key -combination. +combination. Similarily, you can use +move workspace next+ and +move workspace +prev+ to move a container to the next/previous workspace. To move a container to another xrandr output such as +LVDS1+ or +VGA1+, you can use the +move output+ command followed by the name of the target output. You