From c71f6f8f7c314434f790162a155f910c01233e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Fri, 30 Sep 2016 17:28:02 +0200 Subject: [PATCH] Implement special value 'current' for output. (#2483) This commit introduces the special 'current' value for outputs in both of * move con to output current * move workspace to output current fixes #2357 --- docs/userguide | 8 ++--- include/output.h | 6 ++++ src/commands.c | 15 ++------- src/move.c | 3 +- src/output.c | 37 +++++++++++++++------- src/workspace.c | 11 ++----- testcases/t/504-move-workspace-to-output.t | 25 ++++++++++++--- 7 files changed, 63 insertions(+), 42 deletions(-) diff --git a/docs/userguide b/docs/userguide index 93c54467..ae741b69 100644 --- a/docs/userguide +++ b/docs/userguide @@ -2103,10 +2103,10 @@ To move a container to another RandR output (addressed by names like +LVDS1+ or +right+, +up+ or +down+), there are two commands: *Syntax*: ----------------------------------------------------- -move container to output left|right|down|up| -move workspace to output left|right|down|up| ----------------------------------------------------- +------------------------------------------------------------ +move container to output left|right|down|up|current| +move workspace to output left|right|down|up|current| +------------------------------------------------------------ *Examples*: -------------------------------------------------------- diff --git a/include/output.h b/include/output.h index 8299a19b..03a4fbcf 100644 --- a/include/output.h +++ b/include/output.h @@ -22,6 +22,12 @@ Con *output_get_content(Con *output); */ Output *get_output_from_string(Output *current_output, const char *output_str); +/** + * Returns the output for the given con. + * + */ +Output *get_output_for_con(Con *con); + /** * Iterates over all outputs and pushes sticky windows to the currently visible * workspace on that output. diff --git a/src/commands.c b/src/commands.c index 403c3b3a..58641d6a 100644 --- a/src/commands.c +++ b/src/commands.c @@ -87,17 +87,6 @@ static bool definitelyGreaterThan(float a, float b, float epsilon) { return (a - b) > ((fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon); } -/* - * Returns the output containing the given container. - */ -static Output *get_output_of_con(Con *con) { - Con *output_con = con_get_output(con); - Output *output = get_output_by_name(output_con->name); - assert(output != NULL); - - return output; -} - /* * Checks whether we switched to a new workspace and returns false in that case, * signaling that further workspace switching should be done by the calling function @@ -1036,7 +1025,7 @@ void cmd_move_con_to_output(I3_CMD, const char *name) { TAILQ_FOREACH(current, &owindows, owindows) { DLOG("matching: %p / %s\n", current->con, current->con->name); - Output *current_output = get_output_of_con(current->con); + Output *current_output = get_output_for_con(current->con); assert(current_output != NULL); Output *output = get_output_from_string(current_output, name); @@ -1648,7 +1637,7 @@ void cmd_focus_output(I3_CMD, const char *name) { Output *output; TAILQ_FOREACH(current, &owindows, owindows) - current_output = get_output_of_con(current->con); + current_output = get_output_for_con(current->con); assert(current_output != NULL); output = get_output_from_string(current_output, name); diff --git a/src/move.c b/src/move.c index 87f78ee3..25c658ce 100644 --- a/src/move.c +++ b/src/move.c @@ -101,8 +101,7 @@ static void attach_to_workspace(Con *con, Con *ws, direction_t direction) { */ static void move_to_output_directed(Con *con, direction_t direction) { Con *old_ws = con_get_workspace(con); - Con *current_output_con = con_get_output(con); - Output *current_output = get_output_by_name(current_output_con->name); + Output *current_output = get_output_for_con(con); Output *output = get_output_next(direction, current_output, CLOSEST_OUTPUT); if (!output) { diff --git a/src/output.c b/src/output.c index 62b146a7..1a9f6129 100644 --- a/src/output.c +++ b/src/output.c @@ -31,18 +31,33 @@ Con *output_get_content(Con *output) { * */ Output *get_output_from_string(Output *current_output, const char *output_str) { - Output *output; + if (strcasecmp(output_str, "current") == 0) { + return get_output_for_con(focused); + } else if (strcasecmp(output_str, "left") == 0) { + return get_output_next_wrap(D_LEFT, current_output); + } else if (strcasecmp(output_str, "right") == 0) { + return get_output_next_wrap(D_RIGHT, current_output); + } else if (strcasecmp(output_str, "up") == 0) { + return get_output_next_wrap(D_UP, current_output); + } else if (strcasecmp(output_str, "down") == 0) { + return get_output_next_wrap(D_DOWN, current_output); + } - if (strcasecmp(output_str, "left") == 0) - output = get_output_next_wrap(D_LEFT, current_output); - else if (strcasecmp(output_str, "right") == 0) - output = get_output_next_wrap(D_RIGHT, current_output); - else if (strcasecmp(output_str, "up") == 0) - output = get_output_next_wrap(D_UP, current_output); - else if (strcasecmp(output_str, "down") == 0) - output = get_output_next_wrap(D_DOWN, current_output); - else - output = get_output_by_name(output_str); + return get_output_by_name(output_str); +} + +Output *get_output_for_con(Con *con) { + Con *output_con = con_get_output(con); + if (output_con == NULL) { + ELOG("Could not get the output container for con = %p.\n", con); + return NULL; + } + + Output *output = get_output_by_name(output_con->name); + if (output == NULL) { + ELOG("Could not get output from name \"%s\".\n", output_con->name); + return NULL; + } return output; } diff --git a/src/workspace.c b/src/workspace.c index 0c80f69f..0da0a378 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -911,17 +911,12 @@ Con *workspace_encapsulate(Con *ws) { bool workspace_move_to_output(Con *ws, const char *name) { LOG("Trying to move workspace %p / %s to output \"%s\".\n", ws, ws->name, name); - Con *current_output_con = con_get_output(ws); - if (!current_output_con) { - ELOG("Could not get the output container for workspace %p / %s.\n", ws, ws->name); - return false; - } - - Output *current_output = get_output_by_name(current_output_con->name); - if (!current_output) { + Output *current_output = get_output_for_con(ws); + if (current_output == NULL) { ELOG("Cannot get current output. This is a bug in i3.\n"); return false; } + Output *output = get_output_from_string(current_output, name); if (!output) { ELOG("Could not get output from string \"%s\"\n", name); diff --git a/testcases/t/504-move-workspace-to-output.t b/testcases/t/504-move-workspace-to-output.t index efe0d6e7..c43b8b40 100644 --- a/testcases/t/504-move-workspace-to-output.t +++ b/testcases/t/504-move-workspace-to-output.t @@ -19,9 +19,6 @@ use List::Util qw(first); use i3test i3_autostart => 0; -# TODO: -# introduce 'move workspace 3 to output ' with synonym 'move workspace 3 to ' - # Ensure the pointer is at (0, 0) so that we really start on the first # (the left) workspace. $x->root->warp_pointer(0, 0); @@ -163,6 +160,26 @@ ok(!($empty_ws ~~ @$x0), 'empty_ws not on fake-0'); ok(!($empty_ws ~~ @$x1), 'empty_ws not on fake-1'); ok($other_output_ws ~~ @$x0, 'other_output_ws on fake-0'); -exit_gracefully($pid); +################################################################################ +# Verify that the special word 'current' can be used for the output. +################################################################################ +my $ws1 = fresh_workspace(output => 1); +open_window; +cmd 'mark marked'; + +my $ws0 = fresh_workspace(output => 0); + +($x0, $x1) = workspaces_per_screen(); +ok($ws0 ~~ @$x0, 'ws0 on fake-0'); +ok($ws1 ~~ @$x1, 'ws1 on fake-1'); + +cmd '[con_mark=marked] move workspace to output current'; + +($x0, $x1) = workspaces_per_screen(); +ok($ws1 ~~ @$x0, 'ws1 on fake-0'); + +################################################################################ + +exit_gracefully($pid); done_testing;