diff --git a/cmd-split-window.c b/cmd-split-window.c index 335fe420..c5840fec 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -40,10 +40,11 @@ const struct cmd_entry cmd_new_pane_entry = { .args = { "bc:de:fF:hIkl:Lm:p:PR:s:S:t:vx:X:y:Y:Z", 0, -1, NULL }, .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " - "[-F format] [-l size] [-m message] [-p percentage] [-s style] " - "[-S active-border-style] [-R inactive-border-style] " - "[-x width] [-y height] [-X x-position] [-Y y-position] " - CMD_TARGET_PANE_USAGE " [shell-command [argument ...]]", + "[-F format] [-l size] [-m message] [-p percentage] " + "[-s style] [-S active-border-style] " + "[-R inactive-border-style] [-x width] [-y height] " + "[-X x-position] [-Y y-position] " CMD_TARGET_PANE_USAGE " " + "[shell-command [argument ...]]", .target = { 't', CMD_FIND_PANE, 0 }, @@ -68,21 +69,22 @@ const struct cmd_entry cmd_split_window_entry = { }; static struct layout_cell * -cmd_split_window_get_floating_layout_cell(struct cmdq_item *item, - struct args *args, struct window *w, struct window_pane *wp) +cmd_split_window_get_floating_cell(struct cmdq_item *item, struct args *args, + struct window *w, struct window_pane *wp) { struct layout_cell *lc = NULL; char *cause = NULL; u_int x, y, sx, sy; - if (window_pane_float_geometry(w, wp, &x, &y, &sx, &sy, item, args, &cause) - != 0) { - cmdq_error(item, "invalid float geometry %s", cause); + if (window_pane_floating_geometry(w, wp, &x, &y, &sx, &sy, item, args, + &cause) != 0) { + cmdq_error(item, "invalid floating pane geometry %s", cause); free(cause); return (NULL); } - /* Floating panes sit in layout cells which are not in the layout_root + /* + * Floating panes sit in layout cells which are not in the layout_root * tree so we call it with parent == NULL. */ lc = layout_create_cell(NULL); @@ -95,8 +97,8 @@ cmd_split_window_get_floating_layout_cell(struct cmdq_item *item, } static struct layout_cell * -cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item, - struct args *args, struct window *w, struct window_pane *wp, int flags) +cmd_split_window_get_tiled_cell(struct cmdq_item *item, struct args *args, + struct window *w, struct window_pane *wp, int flags) { enum layout_type type; struct layout_cell *lc = NULL; @@ -108,7 +110,7 @@ cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item, return (NULL); } - if (window_pane_tile_geometry(w, wp, &size, &flags, &type, item, args, + if (window_pane_tiled_geometry(w, wp, &size, &flags, &type, item, args, &cause) != 0) { cmdq_error(item, "invalid tiled geometry %s", cause); free(cause); @@ -119,6 +121,7 @@ cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item, lc = layout_split_pane(wp, type, size, flags); if (lc == NULL) cmdq_error(item, "no space for new pane"); + return (lc); } @@ -146,7 +149,6 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) is_floating = !args_has(args, 'L'); else is_floating = 0; - input = (args_has(args, 'I') && count == 0); flags = is_floating ? SPAWN_FLOATING : 0; @@ -158,11 +160,9 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) flags |= SPAWN_EMPTY; if (is_floating) - lc = cmd_split_window_get_floating_layout_cell(item, args, w, - wp); + lc = cmd_split_window_get_floating_cell(item, args, w, wp); else - lc = cmd_split_window_get_tiled_layout_cell(item, args, w, wp, - flags); + lc = cmd_split_window_get_tiled_cell(item, args, w, wp, flags); if (lc == NULL) return (CMD_RETURN_ERROR); diff --git a/layout-custom.c b/layout-custom.c index 33027738..a52c46be 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -289,9 +289,9 @@ layout_parse(struct window *w, const char *layout, char **cause) if (floating_lc != NULL) layout_assign(&wp, floating_lc, PANE_FLOATING); - /* Fix z indexes. */ - while (!TAILQ_EMPTY(&w->z_index)) { - wp = TAILQ_FIRST(&w->z_index); + /* Fix pane Z indexes. */ + while (!TAILQ_EMPTY(&w->z_index)) { + wp = TAILQ_FIRST(&w->z_index); TAILQ_REMOVE(&w->z_index, wp, zentry); } if (floating_lc != NULL) diff --git a/layout.c b/layout.c index 7c687e51..dced35c1 100644 --- a/layout.c +++ b/layout.c @@ -245,15 +245,15 @@ layout_fix_zindexes(struct window *w, struct layout_cell *lc) switch (lc->type) { case LAYOUT_WINDOWPANE: TAILQ_INSERT_TAIL(&w->z_index, lc->wp, zentry); - break; + break; case LAYOUT_LEFTRIGHT: case LAYOUT_TOPBOTTOM: case LAYOUT_FLOATING: TAILQ_FOREACH(lcchild, &lc->cells, entry) - layout_fix_zindexes(w, lcchild); - return; + layout_fix_zindexes(w, lcchild); + return; default: - fatalx("bad layout type"); + fatalx("bad layout type"); } } diff --git a/tmux.h b/tmux.h index 7683d8da..a39d2a5b 100644 --- a/tmux.h +++ b/tmux.h @@ -1386,6 +1386,9 @@ struct window { u_int new_xpixel; u_int new_ypixel; + u_int last_new_pane_x; + u_int last_new_pane_y; + struct utf8_data *fill_character; int flags; #define WINDOW_BELL 0x1 @@ -3485,12 +3488,12 @@ enum client_theme window_pane_get_theme(struct window_pane *); void window_pane_send_theme_update(struct window_pane *); struct style_range *window_pane_border_status_get_range(struct window_pane *, u_int, u_int); -int window_pane_tile_geometry(struct window *, struct window_pane *, - int *, int *, enum layout_type *, struct cmdq_item *, - struct args *, char **); -int window_pane_float_geometry(struct window *, struct window_pane *, - u_int *, u_int *, u_int *, u_int *, struct cmdq_item *, - struct args *, char **); +int window_pane_tiled_geometry(struct window *, + struct window_pane *, int *, int *, enum layout_type *, + struct cmdq_item *, struct args *, char **); +int window_pane_floating_geometry(struct window *, + struct window_pane *, u_int *, u_int *, u_int *, u_int *, + struct cmdq_item *, struct args *, char **); /* layout.c */ u_int layout_count_cells(struct layout_cell *); diff --git a/window.c b/window.c index ca905238..8679de63 100644 --- a/window.c +++ b/window.c @@ -597,10 +597,7 @@ window_redraw_active_switch(struct window *w, struct window_pane *wp) if (wp == w->active) break; - /* If you want tiled planes to be able to bury - * floating planes then do this regardless of - * wp->flags & PANE_FLOATING or not. A new option? - */ + /* If the pane is floating, move to the front. */ if (wp->flags & PANE_FLOATING) { TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); @@ -627,8 +624,7 @@ window_get_active_at(struct window *w, u_int x, u_int y) continue; window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy); if (~wp->flags & PANE_FLOATING) { - /* Tiled, select up to including bottom or - right border. */ + /* Tiled - to and including bottom or right border. */ if ((int)x < xoff || x > xoff + sx) continue; if (pane_status == PANE_STATUS_TOP) { @@ -639,7 +635,7 @@ window_get_active_at(struct window *w, u_int x, u_int y) continue; } } else { - /* Floating, include top or or left border. */ + /* Floating - include top or or left border. */ if ((int)x < xoff - 1 || x > xoff + sx) continue; if (pane_status == PANE_STATUS_TOP) { @@ -647,7 +643,7 @@ window_get_active_at(struct window *w, u_int x, u_int y) continue; } else { if ((int)y < yoff - 1 || y > yoff + sy) - continue; + continue; } } return (wp); @@ -796,12 +792,12 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit, else TAILQ_INSERT_AFTER(&w->panes, other, wp, entry); } - /* Floating panes are created above tiled planes. */ - if (flags & SPAWN_FLOATING) { + if (~flags & SPAWN_FLOATING) + TAILQ_INSERT_TAIL(&w->z_index, wp, zentry); + else { wp->flags |= PANE_FLOATING; TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); - } else - TAILQ_INSERT_TAIL(&w->z_index, wp, zentry); + } return (wp); } @@ -834,7 +830,6 @@ void window_remove_pane(struct window *w, struct window_pane *wp) { window_lost_pane(w, wp); - TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->z_index, wp, zentry); window_pane_destroy(wp); @@ -902,7 +897,7 @@ window_count_panes(struct window *w, int with_floating) u_int n = 0; TAILQ_FOREACH(wp, &w->panes, entry) { - if (with_floating || ~wp->flags & PANE_FLOATING) + if (with_floating || ~wp->flags & PANE_FLOATING) n++; } return (n); @@ -1260,7 +1255,7 @@ window_pane_reset_mode_all(struct window_pane *wp) static void window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len) { - struct window_pane *loop; + struct window_pane *loop; TAILQ_FOREACH(loop, &wp->window->panes, entry) { if (loop != wp && @@ -1278,7 +1273,7 @@ window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len) static void window_pane_copy_key(struct window_pane *wp, key_code key) { - struct window_pane *loop; + struct window_pane *loop; TAILQ_FOREACH(loop, &wp->window->panes, entry) { if (loop != wp && @@ -2074,10 +2069,11 @@ window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y) return (style_ranges_get_range(srs, x - wp->xoff - 2)); } +/* Work out geometry for tiled panes. */ int -window_pane_tile_geometry(struct window *w, struct window_pane *wp, int *out_size, - int *out_flags, enum layout_type *out_type, struct cmdq_item *item, - struct args *args, char **cause) +window_pane_tiled_geometry(struct window *w, struct window_pane *wp, + int *out_size, int *out_flags, enum layout_type *out_type, + struct cmdq_item *item, struct args *args, char **cause) { int size, flags = *out_flags; enum layout_type type; @@ -2191,3 +2187,62 @@ out: *out_sy = sy; return (0); } + +/* Work out geometry for floating panes. */ +int +window_pane_floating_geometry(struct window *w, __unused struct window_pane *wp, + u_int *out_x, u_int *out_y, u_int *out_sx, u_int *out_sy, + struct cmdq_item *item, struct args *args, char **cause) +{ + u_int x, y, sx = w->sx / 2, sy = w->sy / 2; + + if (args_has(args, 'x')) { + sx = args_percentage_and_expand(args, 'x', 0, USHRT_MAX, w->sx, + item, cause); + if (*cause != NULL) + return (-1); + } + if (args_has(args, 'y')) { + sy = args_percentage_and_expand(args, 'y', 0, USHRT_MAX, w->sy, + item, cause); + if (*cause != NULL) + return (-1); + } + + if (args_has(args, 'X')) { + x = args_percentage_and_expand(args, 'X', 0, USHRT_MAX, w->sx, + item, cause); + if (*cause != NULL) + return (-1); + } else { + if (w->last_new_pane_x == 0) + x = 4; + else { + x = w->last_new_pane_x + 4; + if (w->last_new_pane_x > w->sx) + x = 4; + } + w->last_new_pane_x = x; + } + if (args_has(args, 'Y')) { + y = args_percentage_and_expand(args, 'Y', 0, USHRT_MAX, w->sy, + item, cause); + if (*cause != NULL) + return (-1); + } else { + if (w->last_new_pane_y == 0) + y = 2; + else { + y = w->last_new_pane_y + 2; + if (w->last_new_pane_y > w->sy) + y = 2; + } + w->last_new_pane_y = y; + } + + *out_x = x; + *out_y = y; + *out_sx = sx; + *out_sy = sy; + return (0); +}