Allow -p more than 100%, and account for borders when sizing new panes.

From Dane Jensen.
This commit is contained in:
nicm
2026-06-23 09:29:26 +00:00
parent 3ec115115d
commit 9dba08ac8b
7 changed files with 76 additions and 38 deletions

View File

@@ -998,7 +998,7 @@ args_string_percentage(const char *value, long long minval, long long maxval,
copy = xstrdup(value);
copy[valuelen - 1] = '\0';
ll = strtonum(copy, 0, 100, &errstr);
ll = strtonum(copy, 0, 1000, &errstr);
free(copy);
if (errstr != NULL) {
*cause = xstrdup(errstr);
@@ -1066,7 +1066,7 @@ args_string_percentage_and_expand(const char *value, long long minval,
copy[valuelen - 1] = '\0';
f = format_single_from_target(item, copy);
ll = strtonum(f, 0, 100, &errstr);
ll = strtonum(f, 0, 1000, &errstr);
free(f);
free(copy);
if (errstr != NULL) {

View File

@@ -94,7 +94,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
server_unzoom_window(w);
if (args_has(args, 'x')) {
x = args_percentage(args, 'x', 0, INT_MAX, w->sx, &cause);
x = args_percentage(args, 'x', 0, PANE_MAXIMUM, w->sx, &cause);
if (cause != NULL) {
cmdq_error(item, "width %s", cause);
free(cause);
@@ -112,7 +112,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
}
if (args_has(args, 'y')) {
y = args_percentage(args, 'y', 0, INT_MAX, w->sy, &cause);
y = args_percentage(args, 'y', 0, PANE_MAXIMUM, w->sy, &cause);
if (cause != NULL) {
cmdq_error(item, "height %s", cause);
free(cause);

View File

@@ -88,7 +88,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
int input, empty, is_floating, flags = 0;
const char *template, *style, *value;
char *cause = NULL, *cp, *title;
struct options_entry *oe;
const struct options_table_entry *oe;
struct args_value *av;
enum pane_lines lines;
u_int count = args_count(args);
@@ -118,8 +118,20 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
if (empty)
flags |= SPAWN_EMPTY;
if ((value = args_get(args, 'B')) == NULL)
lines = window_get_pane_lines(w);
else {
oe = options_search("pane-border-lines");
lines = options_find_choice(oe, value, &cause);
if (cause != NULL) {
cmdq_error(item, "pane-border-lines %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
if (is_floating)
lc = layout_get_floating_cell(item, args, w, wp, &cause);
lc = layout_get_floating_cell(item, args, lines, w, wp, &cause);
else
lc = layout_get_tiled_cell(item, args, w, wp, flags, &cause);
if (cause != NULL) {
@@ -156,10 +168,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
cmdq_error(item, "create pane failed: %s", cause);
free(cause);
if (sc.argv != NULL)
cmd_free_argv(sc.argc, sc.argv);
environ_free(sc.environ);
return (CMD_RETURN_ERROR);
goto fail;
}
style = args_get(args, 's');
@@ -167,7 +176,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
if (options_set_string(new_wp->options, "window-style", 0,
"%s", style) == NULL) {
cmdq_error(item, "bad style: %s", style);
return (CMD_RETURN_ERROR);
goto fail;
}
options_set_string(new_wp->options, "window-active-style", 0,
"%s", style);
@@ -179,7 +188,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
if (options_set_string(new_wp->options,
"pane-active-border-style", 0, "%s", style) == NULL) {
cmdq_error(item, "bad active border style: %s", style);
return (CMD_RETURN_ERROR);
goto fail;
}
}
style = args_get(args, 'R');
@@ -188,22 +197,11 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
"%s", style) == NULL) {
cmdq_error(item, "bad inactive border style: %s",
style);
return (CMD_RETURN_ERROR);
goto fail;
}
}
value = args_get(args, 'B');
if (value != NULL) {
oe = options_get(new_wp->options, "pane-border-lines");
lines = options_find_choice(options_table_entry(oe), value,
&cause);
if (cause != NULL) {
cmdq_error(item, "pane-border-lines %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
options_set_number(new_wp->options, "pane-border-lines",
lines);
}
if (args_has(args, 'B'))
options_set_number(new_wp->options, "pane-border-lines", lines);
if (args_has(args, 'k') || args_has(args, 'm')) {
options_set_number(new_wp->options, "remain-on-exit", 3);
if (args_has(args, 'm')) {
@@ -228,10 +226,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
window_remove_pane(wp->window, new_wp);
cmdq_error(item, "%s", cause);
free(cause);
if (sc.argv != NULL)
cmd_free_argv(sc.argc, sc.argv);
environ_free(sc.environ);
return (CMD_RETURN_ERROR);
goto fail;
case 1:
input = 0;
break;
@@ -273,4 +268,13 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_WAIT);
}
return (CMD_RETURN_NORMAL);
fail:
if (sc.argv != NULL)
cmd_free_argv(sc.argc, sc.argv);
environ_free(sc.environ);
layout_destroy_cell(w, lc, &w->layout_root);
return (CMD_RETURN_ERROR);
}

View File

@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -1563,7 +1564,8 @@ layout_get_tiled_cell(struct cmdq_item *item, struct args *args,
/* Get a new floating cell. */
struct layout_cell *
layout_get_floating_cell(struct cmdq_item *item, struct args *args,
struct window *w, struct window_pane *wp, char **cause)
enum pane_lines lines, struct window *w, struct window_pane *wp,
char **cause)
{
struct layout_cell *lcnew;
int sx = w->sx / 2, sy = w->sy / 4;
@@ -1571,22 +1573,26 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
char *error;
if (args_has(args, 'x')) {
sx = args_percentage_and_expand(args, 'x', 0, w->sx - 1, w->sx,
item, &error);
sx = args_percentage_and_expand(args, 'x', 0, PANE_MAXIMUM,
w->sx, item, &error);
if (error != NULL) {
xasprintf(cause, "position %s", error);
free(error);
return (NULL);
}
if (lines != PANE_LINES_NONE)
sx -= 2;
}
if (args_has(args, 'y')) {
sy = args_percentage_and_expand(args, 'y', 0, w->sy - 1, w->sy,
item, &error);
sy = args_percentage_and_expand(args, 'y', 0, PANE_MAXIMUM,
w->sy, item, &error);
if (error != NULL) {
xasprintf(cause, "position %s", error);
free(error);
return (NULL);
}
if (lines != PANE_LINES_NONE)
sy -= 2;
}
if (args_has(args, 'X')) {
ox = args_percentage_and_expand(args, 'X', -sx, w->sx,
@@ -1616,7 +1622,9 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
ox = 4;
}
w->last_new_pane_x = ox;
}
} else
if (lines != PANE_LINES_NONE)
ox += 1;
if (oy == INT_MAX) {
if (w->last_new_pane_y == 0)
oy = 2;
@@ -1626,7 +1634,9 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
oy = 2;
}
w->last_new_pane_y = oy;
}
} else
if (lines != PANE_LINES_NONE)
oy += 1;
if (sx < PANE_MINIMUM || sx > PANE_MAXIMUM) {
*cause = xstrdup("invalid width");

View File

@@ -662,6 +662,18 @@ options_parse_get(struct options *oo, const char *s, int *idx, int only)
return (o);
}
const struct options_table_entry *
options_search(const char *name)
{
const struct options_table_entry *oe;
for (oe = options_table; oe->name != NULL; oe++) {
if (strcmp(oe->name, name) == 0)
return (oe);
}
return (NULL);
}
char *
options_match(const char *s, int *idx, int *ambiguous)
{

5
tmux.h
View File

@@ -2558,6 +2558,7 @@ char *options_to_string(struct options_entry *, int, int);
char *options_parse(const char *, int *);
struct options_entry *options_parse_get(struct options *, const char *, int *,
int);
const struct options_table_entry *options_search(const char *);
char *options_match(const char *, int *, int *);
struct options_entry *options_match_get(struct options *, const char *, int *,
int, int *);
@@ -3472,6 +3473,7 @@ int window_get_bg_client(struct window_pane *);
enum client_theme window_pane_get_theme(struct window_pane *);
void window_pane_send_theme_update(struct window_pane *);
enum pane_lines window_pane_get_pane_lines(struct window_pane *);
enum pane_lines window_get_pane_lines(struct window *);
int window_get_pane_status(struct window *);
int window_pane_get_pane_status(struct window_pane *);
struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
@@ -3535,7 +3537,8 @@ void layout_spread_out(struct window_pane *);
struct layout_cell *layout_get_tiled_cell(struct cmdq_item *, struct args *,
struct window *, struct window_pane *, int, char **);
struct layout_cell *layout_get_floating_cell(struct cmdq_item *, struct args *,
struct window *, struct window_pane *, char **);
enum pane_lines, struct window *, struct window_pane *,
char **);
int layout_remove_tile(struct window *, struct layout_cell *);
/* layout-custom.c */

View File

@@ -2177,6 +2177,15 @@ window_pane_get_pane_lines(struct window_pane *wp)
return (options_get_number(oo, "pane-border-lines"));
}
enum pane_lines
window_get_pane_lines(struct window *w)
{
struct options *oo;
oo = w->options;
return (options_get_number(oo, "pane-border-lines"));
}
int
window_get_pane_status(struct window *w)
{