From f78f137ed00f4e31f4752f3e26a8e133809b9f00 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pavel=20L=C3=B6bl?= Date: Fri, 23 Mar 2012 13:39:17 +0100 Subject: [PATCH] Extends move command for floating windows --- docs/userguide | 5 ++ include/commands.h | 12 +++++ parser-specs/commands.spec | 25 ++++++++++ src/commands.c | 79 +++++++++++++++++++++++++++++++ testcases/t/124-move.t | 23 +++++++++ testcases/t/187-commands-parser.t | 2 +- 6 files changed, 145 insertions(+), 1 deletion(-) diff --git a/docs/userguide b/docs/userguide index 75a5b645..957d0c7f 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1233,6 +1233,7 @@ focus focus focus output <|output> move [ px] +move [absolute] position [[ px] [ px]|center] ----------------------------------- Note that the amount of pixels you can specify for the +move+ command is only @@ -1267,6 +1268,10 @@ bindsym mod+semicolon move right # Move container, but make floating containers # move more than the default bindsym mod+j move left 20 px + +# Move floating container to the center +# of all outputs +bindsym mod+c move absolute position center ---------------------- === Changing (named) workspaces/moving to workspaces diff --git a/include/commands.h b/include/commands.h index 2b69422d..88521d31 100644 --- a/include/commands.h +++ b/include/commands.h @@ -223,6 +223,18 @@ void cmd_open(I3_CMD); */ void cmd_focus_output(I3_CMD, char *name); +/** + * Implementation of 'move [window|container] [to] [absolute] position [px] [px] + * + */ +void cmd_move_window_to_position(I3_CMD, char *method, char *x, char *y); + +/** + * Implementation of 'move [window|container] [to] [absolute] position center + * + */ +void cmd_move_window_to_center(I3_CMD, char *method); + /** * Implementation of 'move scratchpad'. * diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index bbd7ab28..490e4972 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -172,6 +172,7 @@ state RESIZE_TILING_OR: # move [window|container] [to] scratchpad # move workspace to [output] # move scratchpad +# move [window|container] [to] [absolute] position [ [ [px] [px]] | center ] state MOVE: 'window' -> @@ -187,6 +188,10 @@ state MOVE: -> call cmd_move_scratchpad() direction = 'left', 'right', 'up', 'down' -> MOVE_DIRECTION + method = 'position' + -> MOVE_TO_POSITION + method = 'absolute' + -> MOVE_TO_ABSOLUTE_POSITION state MOVE_DIRECTION: pixels = word @@ -218,6 +223,26 @@ state MOVE_WORKSPACE_TO_OUTPUT: output = string -> call cmd_move_workspace_to_output($output) +state MOVE_TO_ABSOLUTE_POSITION: + 'position' + -> MOVE_TO_POSITION + +state MOVE_TO_POSITION: + 'center' + -> call cmd_move_window_to_center($method) + coord_x = word + -> MOVE_TO_POSITION_X + +state MOVE_TO_POSITION_X: + 'px' + -> + coord_y = word + -> MOVE_TO_POSITION_Y + +state MOVE_TO_POSITION_Y: + 'px', end + -> call cmd_move_window_to_position($method, $coord_x, $coord_y) + # mode state MODE: mode = string diff --git a/src/commands.c b/src/commands.c index 8fc80a19..8111b54c 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1255,6 +1255,85 @@ void cmd_focus_output(I3_CMD, char *name) { cmd_output->json_output = sstrdup("{\"success\": true}"); } +/* + * Implementation of 'move [window|container] [to] [absolute] position [px] [px] + * + */ +void cmd_move_window_to_position(I3_CMD, char *method, char *cx, char *cy) { + + int x = atoi(cx); + int y = atoi(cy); + + if (!con_is_floating(focused)) { + ELOG("Cannot change position. The window/container is not floating\n"); + sasprintf(&(cmd_output->json_output), + "{\"success\":false, \"error\":\"Cannot change position. " + "The window/container is not floating.\"}"); + return; + } + + if (strcmp(method, "absolute") == 0) { + focused->parent->rect.x = x; + focused->parent->rect.y = y; + + DLOG("moving to absolute position %d %d\n", x, y); + floating_maybe_reassign_ws(focused->parent); + cmd_output->needs_tree_render = true; + } + + if (strcmp(method, "position") == 0) { + Rect newrect = focused->parent->rect; + + DLOG("moving to position %d %d\n", x, y); + newrect.x = x; + newrect.y = y; + + floating_reposition(focused->parent, newrect); + } + + // XXX: default reply for now, make this a better reply + cmd_output->json_output = sstrdup("{\"success\": true}"); +} + +/* + * Implementation of 'move [window|container] [to] [absolute] position center + * + */ +void cmd_move_window_to_center(I3_CMD, char *method) { + + if (!con_is_floating(focused)) { + ELOG("Cannot change position. The window/container is not floating\n"); + sasprintf(&(cmd_output->json_output), + "{\"success\":false, \"error\":\"Cannot change position. " + "The window/container is not floating.\"}"); + } + + if (strcmp(method, "absolute") == 0) { + Rect *rect = &focused->parent->rect; + + DLOG("moving to absolute center\n"); + rect->x = croot->rect.width/2 - rect->width/2; + rect->y = croot->rect.height/2 - rect->height/2; + + floating_maybe_reassign_ws(focused->parent); + cmd_output->needs_tree_render = true; + } + + if (strcmp(method, "position") == 0) { + Rect *wsrect = &con_get_workspace(focused)->rect; + Rect newrect = focused->parent->rect; + + DLOG("moving to center\n"); + newrect.x = wsrect->width/2 - newrect.width/2; + newrect.y = wsrect->height/2 - newrect.height/2; + + floating_reposition(focused->parent, newrect); + } + + // XXX: default reply for now, make this a better reply + cmd_output->json_output = sstrdup("{\"success\": true}"); +} + /* * Implementation of 'move scratchpad'. * diff --git a/testcases/t/124-move.t b/testcases/t/124-move.t index ae989f06..052cdbff 100644 --- a/testcases/t/124-move.t +++ b/testcases/t/124-move.t @@ -200,6 +200,29 @@ is($absolute->y, $absolute_before->y, 'y not changed'); is($absolute->width, $absolute_before->width, 'width not changed'); is($absolute->height, $absolute_before->height, 'height not changed'); +###################################################################### +# 6) test moving floating window to a specified position +# and to absolute center +###################################################################### + +$tmp = fresh_workspace; +open_floating_window; my @floatcon; + +cmd 'move position 5 px 15 px'; + +@floatcon = @{get_ws($tmp)->{floating_nodes}}; + +is($floatcon[0]->{rect}->{x}, 5, 'moved to position 5 x'); +is($floatcon[0]->{rect}->{y}, 15, 'moved to position 15 y'); + +cmd 'move absolute position center'; + +@floatcon = @{get_ws($tmp)->{floating_nodes}}; + +my $center_x = int($x->root->rect->width/2) - int($floatcon[0]->{rect}->{width}/2); +my $center_y = int($x->root->rect->height/2) - int($floatcon[0]->{rect}->{height}/2); +is($floatcon[0]->{rect}->{x}, $center_x, "moved to center at position $center_x x"); +is($floatcon[0]->{rect}->{y}, $center_y, "moved to center at position $center_y y"); done_testing; diff --git a/testcases/t/187-commands-parser.t b/testcases/t/187-commands-parser.t index b0e543ba..7e6f97bd 100644 --- a/testcases/t/187-commands-parser.t +++ b/testcases/t/187-commands-parser.t @@ -133,7 +133,7 @@ is(parser_calls('unknown_literal'), 'error for unknown literal ok'); is(parser_calls('move something to somewhere'), - "Expected one of these tokens: 'window', 'container', 'to', 'workspace', 'output', 'scratchpad', 'left', 'right', 'up', 'down'\n" . + "Expected one of these tokens: 'window', 'container', 'to', 'workspace', 'output', 'scratchpad', 'left', 'right', 'up', 'down', 'position', 'absolute'\n" . "Your command: move something to somewhere\n" . " ^^^^^^^^^^^^^^^^^^^^^^", 'error for unknown literal ok'); -- 2.39.5