diff --git a/cmd-break-pane.c b/cmd-break-pane.c index 4be989c3..aad23334 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -96,7 +96,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) } TAILQ_REMOVE(&w->panes, wp, entry); - TAILQ_REMOVE(&w->z_index, wp, zentry); + TAILQ_REMOVE(&w->z_index, wp, zentry); server_client_remove_pane(wp); window_lost_pane(w, wp); layout_close_pane(wp); @@ -105,7 +105,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) options_set_parent(wp->options, w->options); wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); TAILQ_INSERT_HEAD(&w->panes, wp, entry); - TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); + TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); w->active = wp; w->latest = tc; diff --git a/cmd-join-pane.c b/cmd-join-pane.c index 8444a230..4ab05e82 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -146,14 +146,14 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) server_client_remove_pane(src_wp); window_lost_pane(src_w, src_wp); TAILQ_REMOVE(&src_w->panes, src_wp, entry); - TAILQ_REMOVE(&src_w->z_index, src_wp, zentry); + TAILQ_REMOVE(&src_w->z_index, src_wp, zentry); src_wp->window = dst_w; options_set_parent(src_wp->options, dst_w->options); src_wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); if (flags & SPAWN_BEFORE) { TAILQ_INSERT_BEFORE(dst_wp, src_wp, entry); - TAILQ_INSERT_BEFORE(dst_wp, src_wp, zentry); + TAILQ_INSERT_BEFORE(dst_wp, src_wp, zentry); } else { TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry); TAILQ_INSERT_AFTER(&dst_w->z_index, dst_wp, src_wp, zentry); diff --git a/cmd-split-window.c b/cmd-split-window.c index 5859983c..e3cab885 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; @@ -113,7 +115,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); @@ -124,6 +126,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); } @@ -151,7 +154,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; @@ -163,11 +165,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 dfdce707..0216a036 100644 --- a/layout.c +++ b/layout.c @@ -234,6 +234,7 @@ layout_make_node(struct layout_cell *lc, enum layout_type type) lc->wp = NULL; } +/* Fix Z indexes. */ void layout_fix_zindexes(struct window *w, struct layout_cell *lc) { @@ -245,15 +246,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 091d54c1..274205b9 100644 --- a/tmux.h +++ b/tmux.h @@ -1394,6 +1394,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 @@ -3493,12 +3496,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 61d85d9f..4cf2599e 100644 --- a/window.c +++ b/window.c @@ -562,6 +562,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify) } tty_update_window_offset(w); + server_redraw_window(w); if (notify) notify_window("window-pane-changed", w); @@ -610,10 +611,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); @@ -640,8 +638,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) { @@ -652,7 +649,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) { @@ -660,7 +657,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); @@ -835,12 +832,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); } @@ -873,7 +870,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); @@ -941,7 +937,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); @@ -996,8 +992,8 @@ window_printable_flags(struct winlink *wl, int escape) const char * window_pane_printable_flags(struct window_pane *wp) { - static char flags[32]; struct window *w = wp->window; + static char flags[32]; int pos = 0; if (wp == w->active) @@ -1302,7 +1298,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 && @@ -1320,7 +1316,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 && @@ -2118,10 +2114,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; @@ -2245,3 +2242,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); +}