diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next index 39b8d836a..406fbe2a1 100644 --- a/RELEASE-NOTES-next +++ b/RELEASE-NOTES-next @@ -27,6 +27,7 @@ working. Please reach out to us in that case! • update i3bar config when necessary (reduces redraws on bar mode changes) • mention rofi in default config file • i3-input: add different exit codes for when i3-input fails + • allow ppt values in move direction and move position commands ┌────────────────────────────┐ │ Bugfixes │ diff --git a/docs/userguide b/docs/userguide index 881506964..d74897193 100644 --- a/docs/userguide +++ b/docs/userguide @@ -245,7 +245,7 @@ you open a new terminal, it will open below the current one. So, how can you open a new terminal window to the *right* of the current one? The solution is to use +focus parent+, which will focus the +Parent Container+ of -the current +Container+. In default configuration, use +$mod+a+ to navigate one +the current +Container+. In default configuration, use +$mod+a+ to navigate one +Container+ up the tree (you can repeat this multiple times until you get to the +Workspace Container+). In this case, you would focus the +Vertical Split Container+ which is *inside* the horizontally oriented workspace. Thus, now new windows will be @@ -1415,7 +1415,7 @@ button6:: Scroll wheel right. button7:: Scroll wheel left. - + Please note that the old +wheel_up_cmd+ and +wheel_down_cmd+ commands are deprecated and will be removed in a future release. We strongly recommend using the more general @@ -1682,8 +1682,8 @@ When +strip_workspace_name+ is set to +yes+, any workspace that has a name of the form "[n][:][NAME]" will display only the number. The default is to display the full name within the workspace button. Be aware -that the colon in the workspace name is optional, so `[n][NAME]` will also -have the workspace name and number stripped correctly. +that the colon in the workspace name is optional, so `[n][NAME]` will also +have the workspace name and number stripped correctly. *Syntax*: ------------------------------ @@ -2157,12 +2157,15 @@ Use the +move+ command to move a container. # Moves the container into the given direction. # The optional pixel argument specifies how far the # container should be moved if it is floating and -# defaults to 10 pixels. -move [ px] +# defaults to 10 pixels. The optional ppt argument +# means "percentage points", and if specified it indicates +# how many points the container should be moved if it is +# floating rather than by a pixel value. +move [ [px|ppt]] # Moves the container to the specified pos_x and pos_y # coordinates on the screen. -move position [px] [px] +move position [px|ppt] [px|ppt] # Moves the container to the center of the screen. # If 'absolute' is used, it is moved to the center of diff --git a/include/commands.h b/include/commands.h index 00be6672a..4b2f99bc2 100644 --- a/include/commands.h +++ b/include/commands.h @@ -219,10 +219,10 @@ void cmd_fullscreen(I3_CMD, const char *action, const char *fullscreen_mode); void cmd_sticky(I3_CMD, const char *action); /** - * Implementation of 'move [ [px]]'. + * Implementation of 'move [ [px|ppt]]'. * */ -void cmd_move_direction(I3_CMD, const char *direction_str, long move_px); +void cmd_move_direction(I3_CMD, const char *direction_str, long amount, const char *mode); /** * Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'. @@ -267,10 +267,10 @@ void cmd_open(I3_CMD); void cmd_focus_output(I3_CMD, const char *name); /** - * Implementation of 'move [window|container] [to] [absolute] position [px] [px] + * Implementation of 'move [window|container] [to] [absolute] position [ [px|ppt] [px|ppt]] * */ -void cmd_move_window_to_position(I3_CMD, long x, long y); +void cmd_move_window_to_position(I3_CMD, long x, const char *mode_x, long y, const char *mode_y); /** * Implementation of 'move [window|container] [to] [absolute] position center diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index 927b41320..20de3e442 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -149,7 +149,7 @@ state WORKSPACE: -> call cmd_workspace_back_and_forth() 'number' -> WORKSPACE_NUMBER - workspace = string + workspace = string -> call cmd_workspace_name($workspace, $no_auto_back_and_forth) state WORKSPACE_NUMBER: @@ -339,14 +339,15 @@ state RENAME_WORKSPACE_TO_NEW_NAME: new_name = string -> call cmd_rename_workspace($old_name, $new_name) -# move [ [px]] + +# move [ [px|ppt]] # move [window|container] [to] workspace [|next|prev|next_on_output|prev_on_output|current] # move [window|container] [to] output # move [window|container] [to] mark # move [window|container] [to] scratchpad # move workspace to [output] # move scratchpad -# move [window|container] [to] [absolute] position [ [ [px] [px]] | center ] +# move [window|container] [to] [absolute] position [ [ [px|ppt] [px|ppt] ] | center ] # move [window|container] [to] position mouse|cursor|pointer state MOVE: 'window' @@ -373,16 +374,16 @@ state MOVE: -> MOVE_TO_ABSOLUTE_POSITION state MOVE_DIRECTION: - pixels = number - -> MOVE_DIRECTION_PX + amount = number + -> MOVE_DIRECTION_NUMBER end - -> call cmd_move_direction($direction, 10) + -> call cmd_move_direction($direction, 10, "px") -state MOVE_DIRECTION_PX: - 'px' - -> call cmd_move_direction($direction, &pixels) +state MOVE_DIRECTION_NUMBER: + mode = 'px', 'ppt' + -> call cmd_move_direction($direction, &amount, $mode) end - -> call cmd_move_direction($direction, &pixels) + -> call cmd_move_direction($direction, &amount, "px") state MOVE_WORKSPACE: 'to ' @@ -427,14 +428,16 @@ state MOVE_TO_POSITION: -> MOVE_TO_POSITION_X state MOVE_TO_POSITION_X: - 'px' + mode_x = 'px', 'ppt' -> coord_y = number -> MOVE_TO_POSITION_Y state MOVE_TO_POSITION_Y: - 'px', end - -> call cmd_move_window_to_position(&coord_x, &coord_y) + mode_y = 'px', 'ppt' + -> call cmd_move_window_to_position(&coord_x, $mode_x, &coord_y, $mode_y) + end + -> call cmd_move_window_to_position(&coord_x, $mode_x, &coord_y, 0) # mode state MODE: diff --git a/src/commands.c b/src/commands.c index 7d435d17e..26ea876b4 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1490,34 +1490,37 @@ void cmd_sticky(I3_CMD, const char *action) { } /* - * Implementation of 'move [ [px]]'. + * Implementation of 'move [ [px|ppt]]'. * */ -void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) { +void cmd_move_direction(I3_CMD, const char *direction_str, long amount, const char *mode) { owindow *current; HANDLE_EMPTY_MATCH; Con *initially_focused = focused; direction_t direction = parse_direction(direction_str); + const bool is_ppt = mode && strcmp(mode, "ppt") == 0; + + DLOG("moving in direction %s, %ld %s\n", direction_str, amount, mode); TAILQ_FOREACH (current, &owindows, owindows) { - DLOG("moving in direction %s, px %ld\n", direction_str, move_px); if (con_is_floating(current->con)) { - DLOG("floating move with %ld pixels\n", move_px); + DLOG("floating move with %ld %s\n", amount, mode); Rect newrect = current->con->parent->rect; + Con *output = con_get_output(current->con); switch (direction) { case D_LEFT: - newrect.x -= move_px; + newrect.x -= is_ppt ? output->rect.width * ((double)amount / 100.0) : amount; break; case D_RIGHT: - newrect.x += move_px; + newrect.x += is_ppt ? output->rect.width * ((double)amount / 100.0) : amount; break; case D_UP: - newrect.y -= move_px; + newrect.y -= is_ppt ? output->rect.height * ((double)amount / 100.0) : amount; break; case D_DOWN: - newrect.y += move_px; + newrect.y += is_ppt ? output->rect.height * ((double)amount / 100.0) : amount; break; } @@ -1721,10 +1724,10 @@ void cmd_focus_output(I3_CMD, const char *name) { } /* - * Implementation of 'move [window|container] [to] [absolute] position [px] [px] + * Implementation of 'move [window|container] [to] [absolute] position [ [px|ppt] [px|ppt]] * */ -void cmd_move_window_to_position(I3_CMD, long x, long y) { +void cmd_move_window_to_position(I3_CMD, long x, const char *mode_x, long y, const char *mode_y) { bool has_error = false; owindow *current; @@ -1743,10 +1746,11 @@ void cmd_move_window_to_position(I3_CMD, long x, long y) { } Rect newrect = current->con->parent->rect; + Con *output = con_get_output(current->con); - DLOG("moving to position %ld %ld\n", x, y); - newrect.x = x; - newrect.y = y; + newrect.x = mode_x && strcmp(mode_x, "ppt") == 0 ? output->rect.width * ((double)x / 100.0) : x; + newrect.y = mode_y && strcmp(mode_y, "ppt") == 0 ? output->rect.height * ((double)y / 100.0) : y; + DLOG("moving to position %d %s %d %s\n", newrect.x, mode_x, newrect.y, mode_y); if (!floating_reposition(current->con->parent, newrect)) { yerror("Cannot move window/container out of bounds."); diff --git a/testcases/t/124-move.t b/testcases/t/124-move.t index b7ef0b2cf..b4a8ca3e2 100644 --- a/testcases/t/124-move.t +++ b/testcases/t/124-move.t @@ -220,21 +220,49 @@ 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'); +$absolute_before = $absolute; +$top_before = $top; + ###################################################################### -# 6) test moving floating window to a specified position +# 7) test moving floating containers with a specific amount of ppt +###################################################################### + +cmd 'move right 25 ppt'; + +sync_with_i3; + +($absolute, $top) = $floatwin->rect; + +is($absolute->x, int($x->root->rect->width * 0.25) + $absolute_before->x, 'moved 25 ppt to the right'); +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'); + +###################################################################### +# 8) test moving floating window to a specified position # and to absolute center ###################################################################### $tmp = fresh_workspace; open_floating_window; my @floatcon; +# Move to specified position with px 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'); +is($floatcon[0]->{rect}->{x}, 5, 'moved to position 5 (px) x'); +is($floatcon[0]->{rect}->{y}, 15, 'moved to position 15 (px) y'); + +# Move to specified position with ppt +cmd 'move position 20 ppt 20 ppt'; + +@floatcon = @{get_ws($tmp)->{floating_nodes}}; + +is($floatcon[0]->{rect}->{x}, int($x->root->rect->width * 0.20), "moved to position 20 (ppt) x"); +is($floatcon[0]->{rect}->{y}, int($x->root->rect->height * 0.20), "moved to position 20 (ppt) y"); +# Move to absolute center cmd 'move absolute position center'; @floatcon = @{get_ws($tmp)->{floating_nodes}};