mirror of
https://github.com/tmux/tmux.git
synced 2026-10-08 02:34:28 +00:00
Add hidden panes and a "show desktop" button to the pane list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -65,13 +65,15 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args,
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
layout_remove_tile(w, lc);
|
||||
/* A hidden pane has already given up its space. */
|
||||
if (~wp->flags & PANE_HIDDEN)
|
||||
layout_remove_tile(w, lc);
|
||||
layout_set_size(lc, fg->sx, fg->sy, fg->xoff, fg->yoff);
|
||||
|
||||
lc->flags |= LAYOUT_CELL_FLOATING;
|
||||
window_raise_pane(wp);
|
||||
|
||||
if (!args_has(args, 'd'))
|
||||
if (!args_has(args, 'd') && (~wp->flags & PANE_HIDDEN))
|
||||
window_set_active_pane(w, wp, 1);
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
@@ -149,6 +151,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
window_lost_pane(w, wp);
|
||||
layout_close_pane(wp);
|
||||
|
||||
wp->flags &= ~(PANE_HIDDEN|PANE_HIDDENALL);
|
||||
w = wp->window = window_create(w->sx, w->sy, w->xpixel, w->ypixel);
|
||||
window_add_ref(w, __func__);
|
||||
options_set_parent(wp->options, w->options);
|
||||
|
||||
@@ -429,7 +429,12 @@ cmd_join_pane_tile(struct cmdq_item *item, struct args *args, struct window *w,
|
||||
lc->fg.xoff = lc->g.xoff;
|
||||
lc->fg.yoff = lc->g.yoff;
|
||||
|
||||
if (layout_insert_tile(w, lc) != 0) {
|
||||
if (wp->flags & PANE_HIDDEN) {
|
||||
/* It takes its space when it is shown. */
|
||||
if (lc->parent != NULL)
|
||||
layout_set_size(lc, 0, 0, 0, 0);
|
||||
lc->tg.sx = UINT_MAX;
|
||||
} else if (layout_insert_tile(w, lc) != 0) {
|
||||
cmdq_error(item, "no space for a new pane");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
@@ -440,7 +445,7 @@ cmd_join_pane_tile(struct cmdq_item *item, struct args *args, struct window *w,
|
||||
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
|
||||
}
|
||||
|
||||
if (!args_has(args, 'd'))
|
||||
if (!args_has(args, 'd') && (~wp->flags & PANE_HIDDEN))
|
||||
window_set_active_pane(w, wp, 1);
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
@@ -545,6 +550,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
TAILQ_REMOVE(&src_w->z_index, src_wp, zentry);
|
||||
|
||||
src_wp->window = dst_w;
|
||||
src_wp->flags &= ~(PANE_HIDDEN|PANE_HIDDENALL);
|
||||
options_set_parent(src_wp->options, dst_w->options);
|
||||
src_wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED);
|
||||
if (flags & SPAWN_BEFORE)
|
||||
|
||||
@@ -41,8 +41,8 @@ const struct cmd_entry cmd_resize_pane_entry = {
|
||||
.name = "resize-pane",
|
||||
.alias = "resizep",
|
||||
|
||||
.args = { "aD::L::MR::Tt:U::x:y:Z", 0, 1, NULL },
|
||||
.usage = "[-aMTZ] [-D lines] [-L columns] [-R columns] [-U lines] "
|
||||
.args = { "aD::HL::MR::Tt:U::x:y:Z", 0, 1, NULL },
|
||||
.usage = "[-aHMTZ] [-D lines] [-L columns] [-R columns] [-U lines] "
|
||||
"[-x width] [-y height] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
@@ -51,6 +51,35 @@ const struct cmd_entry cmd_resize_pane_entry = {
|
||||
.exec = cmd_resize_pane_exec
|
||||
};
|
||||
|
||||
/*
|
||||
* Show the desktop: hide every pane above the layout, remembering which, or if
|
||||
* any were hidden like that show just those again.
|
||||
*/
|
||||
static void
|
||||
cmd_resize_pane_desktop(struct window *w)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
int marked = 0;
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->flags & PANE_HIDDENALL)
|
||||
marked = 1;
|
||||
}
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (marked) {
|
||||
if (wp->flags & PANE_HIDDENALL)
|
||||
window_show_pane(wp);
|
||||
continue;
|
||||
}
|
||||
if (wp == w->modal || (wp->flags & PANE_HIDDEN))
|
||||
continue;
|
||||
if (!window_pane_is_raised(wp))
|
||||
continue;
|
||||
window_hide_pane(wp);
|
||||
wp->flags |= PANE_HIDDENALL;
|
||||
}
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
@@ -83,6 +112,16 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (args_has(args, 'M'))
|
||||
return (cmd_resize_pane_mouse_update(self, item));
|
||||
|
||||
if (args_has(args, 'H')) {
|
||||
if (args_has(args, 'a'))
|
||||
cmd_resize_pane_desktop(w);
|
||||
else if (wp->flags & PANE_HIDDEN)
|
||||
window_set_active_pane(w, wp, 1);
|
||||
else
|
||||
window_hide_pane(wp);
|
||||
server_redraw_window(w);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
if (args_has(args, 'Z')) {
|
||||
if (args_has(args, 'a'))
|
||||
window_unzoom(w, 1);
|
||||
@@ -93,6 +132,8 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
server_redraw_window(w);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
if ((wp->flags & PANE_HIDDEN) && !window_pane_is_floating(wp))
|
||||
window_show_pane(wp);
|
||||
if (wp->flags & PANE_ZOOMED)
|
||||
window_unzoom_pane(wp, 1);
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (wp == w->active)
|
||||
if (wp == w->active && (~wp->flags & PANE_HIDDEN))
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
visible = 1;
|
||||
|
||||
@@ -101,6 +101,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
else {
|
||||
is_floating = window_pane_is_floating(wp);
|
||||
flags |= SPAWN_SPLIT;
|
||||
if (!is_floating && (wp->flags & PANE_HIDDEN))
|
||||
window_show_pane(wp);
|
||||
}
|
||||
|
||||
if (args_has(args, 'O')) {
|
||||
|
||||
@@ -75,7 +75,8 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct window_pane *tmp_wp, *src_wp, *dst_wp;
|
||||
struct layout_cell *src_lc, *dst_lc;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
int src_idx, dst_idx, src_zoomed, dst_zoomed;
|
||||
int src_idx, dst_idx, flags;
|
||||
int src_zoomed, dst_zoomed;
|
||||
|
||||
dst_w = target->wl->window;
|
||||
dst_wp = target->wp;
|
||||
@@ -119,7 +120,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
src_zoomed = (args_has(args, 'Z') && (src_w->flags & WINDOW_ZOOMED));
|
||||
|
||||
if (src_wp == dst_wp)
|
||||
if (src_wp == NULL || src_wp == dst_wp)
|
||||
goto out;
|
||||
|
||||
server_client_remove_pane(src_wp);
|
||||
@@ -145,11 +146,11 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
else
|
||||
TAILQ_INSERT_AFTER(&dst_w->z_index, tmp_wp, src_wp, zentry);
|
||||
|
||||
/* Zoom belongs to the position in the window, like the cell. */
|
||||
if ((src_wp->flags ^ dst_wp->flags) & PANE_ZOOMED) {
|
||||
src_wp->flags ^= PANE_ZOOMED;
|
||||
dst_wp->flags ^= PANE_ZOOMED;
|
||||
}
|
||||
/* Zoom and being hidden belong to the position, like the cell. */
|
||||
flags = (src_wp->flags ^ dst_wp->flags) &
|
||||
(PANE_ZOOMED|PANE_HIDDEN|PANE_HIDDENALL);
|
||||
src_wp->flags ^= flags;
|
||||
dst_wp->flags ^= flags;
|
||||
|
||||
src_lc = src_wp->layout_cell;
|
||||
dst_lc = dst_wp->layout_cell;
|
||||
|
||||
17
format.c
17
format.c
@@ -1110,6 +1110,20 @@ format_cb_pane_floating_flag(struct format_tree *ft)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Callback for pane_hidden_flag. */
|
||||
static void *
|
||||
format_cb_pane_hidden_flag(struct format_tree *ft)
|
||||
{
|
||||
struct window_pane *wp = ft->wp;
|
||||
|
||||
if (wp != NULL) {
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
return (xstrdup("1"));
|
||||
return (xstrdup("0"));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Callback for pane_modal_flag. */
|
||||
static void *
|
||||
format_cb_pane_modal_flag(struct format_tree *ft)
|
||||
@@ -3831,6 +3845,9 @@ static const struct format_table_entry format_table[] = {
|
||||
{ "pane_height", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_height
|
||||
},
|
||||
{ "pane_hidden_flag", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_hidden_flag
|
||||
},
|
||||
{ "pane_id", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_id
|
||||
},
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
" 'Respawn' 'R' {respawn-pane -k}" \
|
||||
" '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}" \
|
||||
" '#{?#{>:#{window_panes},1},,-}#{?pane_zoomed_flag,Unzoom,Zoom}' 'z' {resize-pane -Z}" \
|
||||
" 'Hide' 'H' {resize-pane -H}" \
|
||||
" '#{?#{||:#{pane_floating_flag},#{pane_zoomed_flag}},Bring To Front,}' 'F' {move-pane -P front}"
|
||||
#define DEFAULT_MOVE_MENU \
|
||||
" 'Centre' 'c' {move-pane -P centre}" \
|
||||
@@ -397,6 +398,7 @@ key_bindings_init(void)
|
||||
"bind -N 'Kill current window' & { confirm-before -p\"kill-window #W? (y/n)\" kill-window }",
|
||||
"bind -N 'Prompt for window index to select' \"'\" { command-prompt -pindex { select-window -t ':%%' } }",
|
||||
"bind -N 'New floating pane' * { new-pane }",
|
||||
"bind -N 'Hide pane' _ { resize-pane -H }",
|
||||
"bind -N 'Toggle pane between floating and tiled' @ { if -F '#{pane_floating_flag}' { join-pane } { break-pane -W } }",
|
||||
"bind -N 'Switch to previous client' ( { switch-client -p }",
|
||||
"bind -N 'Switch to next client' ) { switch-client -n }",
|
||||
@@ -531,7 +533,7 @@ key_bindings_init(void)
|
||||
"bind -n M-MouseDrag1Border { move-pane -M }",
|
||||
|
||||
/* Mouse button 1 down on status line. */
|
||||
"bind -n MouseDown1Status { switch-client -t= }",
|
||||
"bind -n MouseDown1Status { if -F '#{==:#{mouse_status_range},desktop}' { resize-pane -a -H } { if -Ft= '#{&&:#{==:#{mouse_status_range},pane},#{&&:#{pane_active},#{!:#{pane_hidden_flag}}}}' { resize-pane -H -t= } { switch-client -t= } } }",
|
||||
"bind -n C-MouseDown1Status { swap-window -t@ }",
|
||||
|
||||
/* Mouse button 1 down on default pane-border-format */
|
||||
|
||||
@@ -75,6 +75,7 @@ struct layout_parse_cell_ctx {
|
||||
int index;
|
||||
int zindex;
|
||||
int zoomed;
|
||||
int hidden;
|
||||
};
|
||||
|
||||
/* Layout parse context. */
|
||||
@@ -221,7 +222,7 @@ layout_parse_free_ctx(struct layout_parse_ctx *pctx)
|
||||
/* Add a cell context to the parse context. */
|
||||
static void
|
||||
layout_parse_add_cctx(struct layout_parse_ctx *pctx, struct layout_cell *lc,
|
||||
int active, int last, int index, int zindex, int zoomed)
|
||||
int active, int last, int index, int zindex, int zoomed, int hidden)
|
||||
{
|
||||
struct layout_parse_cell_ctx *cctx;
|
||||
|
||||
@@ -238,6 +239,7 @@ layout_parse_add_cctx(struct layout_parse_ctx *pctx, struct layout_cell *lc,
|
||||
cctx->index = index;
|
||||
cctx->zindex = zindex;
|
||||
cctx->zoomed = zoomed;
|
||||
cctx->hidden = hidden;
|
||||
}
|
||||
|
||||
/* Remove a cell context from the parse context. Does not preserve ordering. */
|
||||
@@ -429,6 +431,8 @@ layout_append_v2(struct layout_cell *lc, struct layout_string *ls)
|
||||
layout_string_write(ls, ",\"i\":%u", i);
|
||||
if (wp->flags & PANE_ZOOMED)
|
||||
layout_string_write(ls, ",\"Z\":true");
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
layout_string_write(ls, ",\"H\":true");
|
||||
if (lc->flags & LAYOUT_CELL_FLOATING) {
|
||||
z = layout_cell_zindex(lc);
|
||||
layout_string_write(ls, ",\"z\":%u", z);
|
||||
@@ -481,18 +485,23 @@ layout_append_v1(struct layout_cell *lc, struct layout_string *ls)
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies the tiled part of a layout. Only populates what is necessary to dump a
|
||||
* V1 layout string.
|
||||
* Copies the part of a layout that is shown, which leaves out hidden tiled
|
||||
* panes and, unless asked to keep them, floating panes. Only populates what is
|
||||
* necessary to dump a layout string.
|
||||
*/
|
||||
static struct layout_cell *
|
||||
layout_custom_copy_layout(struct layout_cell *lc)
|
||||
layout_custom_copy_layout(struct layout_cell *lc, int keep_floating)
|
||||
{
|
||||
struct layout_cell *lcchild, *lcnewchild, *lconly;
|
||||
struct layout_cell *lcnew;
|
||||
|
||||
if (lc->type == LAYOUT_WINDOWPANE &&
|
||||
(lc->flags & LAYOUT_CELL_FLOATING))
|
||||
return (NULL);
|
||||
if (lc->type == LAYOUT_WINDOWPANE) {
|
||||
if (lc->flags & LAYOUT_CELL_FLOATING) {
|
||||
if (!keep_floating)
|
||||
return (NULL);
|
||||
} else if (lc->wp != NULL && (lc->wp->flags & PANE_HIDDEN))
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
lcnew = layout_create_cell(NULL);
|
||||
|
||||
@@ -508,7 +517,8 @@ layout_custom_copy_layout(struct layout_cell *lc)
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
lcnewchild = layout_custom_copy_layout(lcchild);
|
||||
lcnewchild = layout_custom_copy_layout(lcchild,
|
||||
keep_floating);
|
||||
if (lcnewchild == NULL)
|
||||
continue;
|
||||
TAILQ_INSERT_TAIL(&lcnew->cells, lcnewchild, entry);
|
||||
@@ -534,11 +544,11 @@ layout_custom_copy_layout(struct layout_cell *lc)
|
||||
|
||||
/* Create a compatibility layout for dumping a V1 layout string. */
|
||||
static struct layout_cell *
|
||||
layout_custom_create_compat(struct layout_cell *lcroot)
|
||||
layout_custom_create_compat(struct layout_cell *lcroot, int keep_floating)
|
||||
{
|
||||
struct layout_cell *lccompat;
|
||||
|
||||
lccompat = layout_custom_copy_layout(lcroot);
|
||||
lccompat = layout_custom_copy_layout(lcroot, keep_floating);
|
||||
if (lccompat != NULL && layout_cell_is_tiled(lccompat)) {
|
||||
lccompat->g.xoff = 0;
|
||||
lccompat->g.yoff = 0;
|
||||
@@ -586,11 +596,18 @@ layout_append(struct layout_cell *lcroot, struct layout_string *ls, int flags)
|
||||
if (!layout_cell_is_tiled(lcroot) &&
|
||||
!layout_cell_has_tiled_child(lcroot))
|
||||
return (-1);
|
||||
lccompat = layout_custom_create_compat(lcroot);
|
||||
lccompat = layout_custom_create_compat(lcroot, 0);
|
||||
result = layout_append_v1(lccompat, ls);
|
||||
layout_custom_free_compat(lccompat);
|
||||
} else
|
||||
result = layout_append_v2(lcroot, ls);
|
||||
} else {
|
||||
lccompat = layout_custom_create_compat(lcroot, 1);
|
||||
if (lccompat == NULL)
|
||||
result = layout_append_v2(lcroot, ls);
|
||||
else {
|
||||
result = layout_append_v2(lccompat, ls);
|
||||
layout_custom_free_compat(lccompat);
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
@@ -743,6 +760,12 @@ layout_parse(struct window *w, const char *input, char **cause)
|
||||
}
|
||||
}
|
||||
|
||||
/* Hidden tiled panes are in the new layout like the rest. */
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (!window_pane_is_floating(wp))
|
||||
wp->flags &= ~(PANE_HIDDEN|PANE_HIDDENALL);
|
||||
}
|
||||
|
||||
/* Destroy the old layout and swap to the new. */
|
||||
layout_free_cell(w->layout_root, 0);
|
||||
w->layout_root = lc;
|
||||
@@ -1018,7 +1041,7 @@ layout_parse_json_layout(struct json_node *node, struct layout_cell *lcparent,
|
||||
int64_t num;
|
||||
char **cause = pctx->cause;
|
||||
int boolean, index, zindex, active = -1;
|
||||
int last = -1, zoomed = 0;
|
||||
int last = -1, zoomed, hidden;
|
||||
|
||||
if (json_find_string(node, "t", &str, cause) != 0)
|
||||
goto fail;
|
||||
@@ -1108,14 +1131,20 @@ layout_parse_json_layout(struct json_node *node, struct layout_cell *lcparent,
|
||||
} else
|
||||
zindex = INT_MAX;
|
||||
|
||||
zoomed = hidden = 0;
|
||||
if (json_find(node, "Z") != NULL) {
|
||||
if (json_find_boolean(node, "Z", &boolean, cause) != 0)
|
||||
goto fail;
|
||||
zoomed = boolean;
|
||||
}
|
||||
if (json_find(node, "H") != NULL) {
|
||||
if (json_find_boolean(node, "H", &boolean, cause) != 0)
|
||||
goto fail;
|
||||
hidden = boolean;
|
||||
}
|
||||
|
||||
layout_parse_add_cctx(pctx, lc, active, last, index, zindex,
|
||||
zoomed);
|
||||
zoomed, hidden);
|
||||
} else {
|
||||
if (json_find_array(node, "c", &array, cause) != 0)
|
||||
goto fail;
|
||||
@@ -1225,11 +1254,18 @@ layout_parse_apply_ctx(struct window *w, struct layout_parse_ctx *pctx)
|
||||
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
|
||||
}
|
||||
|
||||
/* Zoom panes. */
|
||||
/* Zoom and hide panes. */
|
||||
for (i = 0; i < pctx->size; i++) {
|
||||
cctx = &pctx->cctxs[i];
|
||||
wp = cctx->lc->wp;
|
||||
if (cctx->zoomed)
|
||||
window_zoom(cctx->lc->wp);
|
||||
window_zoom(wp);
|
||||
}
|
||||
for (i = 0; i < pctx->size; i++) {
|
||||
cctx = &pctx->cctxs[i];
|
||||
wp = cctx->lc->wp;
|
||||
if (cctx->hidden && window_pane_is_floating(wp))
|
||||
window_hide_pane(wp);
|
||||
}
|
||||
|
||||
/* Set the active pane. */
|
||||
|
||||
6
layout.c
6
layout.c
@@ -79,6 +79,7 @@ layout_create_cell(struct layout_cell *lcparent)
|
||||
|
||||
layout_geometry_init(&lc->g);
|
||||
layout_geometry_init(&lc->fg);
|
||||
layout_geometry_init(&lc->tg);
|
||||
|
||||
return (lc);
|
||||
}
|
||||
@@ -238,8 +239,9 @@ layout_cell_is_tiled(struct layout_cell *lc)
|
||||
{
|
||||
int is_leaf = lc->type == LAYOUT_WINDOWPANE;
|
||||
int is_floating = lc->flags & LAYOUT_CELL_FLOATING;
|
||||
int is_hidden = lc->wp != NULL && (lc->wp->flags & PANE_HIDDEN);
|
||||
|
||||
return is_leaf && !is_floating;
|
||||
return is_leaf && !is_floating && !is_hidden;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -499,6 +501,8 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->layout_cell == NULL || wp == skip)
|
||||
continue;
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
continue;
|
||||
|
||||
old_xoff = wp->xoff;
|
||||
old_yoff = wp->yoff;
|
||||
|
||||
@@ -209,7 +209,10 @@ static const char *options_table_copy_mode_line_numbers_list[] = {
|
||||
"#{T:window-pane-current-status-format}" \
|
||||
"#[pop-default]" \
|
||||
"#[norange list=on default] " \
|
||||
"}"
|
||||
"}" \
|
||||
"#[nolist align=right range=user|desktop]" \
|
||||
"[_]" \
|
||||
"#[norange default]"
|
||||
#define OPTIONS_TABLE_STATUS_FORMAT3 \
|
||||
"#[align=left]#{R: ,#{n:#{session_name}}}S: " \
|
||||
"#[norange default]" \
|
||||
|
||||
25
tmux.1
25
tmux.1
@@ -364,6 +364,8 @@ Choose the current window interactively.
|
||||
Kill the current pane.
|
||||
.It z
|
||||
Toggle zoom state of the current pane.
|
||||
.It _
|
||||
Hide the current pane.
|
||||
.It Tab
|
||||
Choose a new window and session by fuzzy matching.
|
||||
.It {
|
||||
@@ -2794,7 +2796,7 @@ If
|
||||
.Fl d
|
||||
is given, the active pane is not changed.
|
||||
The pane must not already be floating.
|
||||
A zoomed pane stays zoomed.
|
||||
A hidden or zoomed pane stays hidden or zoomed.
|
||||
.Tg capturep
|
||||
.It Xo Ic capture\-pane
|
||||
.Op Fl aeFHILpPRqCJMN
|
||||
@@ -3836,7 +3838,7 @@ if specified, to
|
||||
.Ar new\-name .
|
||||
.Tg resizep
|
||||
.It Xo Ic resize\-pane
|
||||
.Op Fl aMTZ
|
||||
.Op Fl aHMTZ
|
||||
.Op Fl D Ar lines
|
||||
.Op Fl L Ar columns
|
||||
.Op Fl R Ar columns
|
||||
@@ -3893,6 +3895,19 @@ with
|
||||
.Fl Z
|
||||
unzooms every pane in the window.
|
||||
.Pp
|
||||
.Fl H
|
||||
hides the target pane, or shows it if it is hidden.
|
||||
A hidden pane is not shown, cannot be selected with the mouse and is skipped
|
||||
when moving to the next or previous pane, but it is otherwise unchanged: a
|
||||
hidden tiled pane gives its space to a neighbour and takes it back when shown,
|
||||
and a pane that is zoomed or floating is still zoomed or floating when shown.
|
||||
Selecting a hidden pane shows it.
|
||||
.Fl a
|
||||
with
|
||||
.Fl H
|
||||
hides every floating or zoomed pane in the window, or, if any were hidden in
|
||||
this way, shows just those again.
|
||||
.Pp
|
||||
.Fl M
|
||||
begins mouse resizing (only valid if bound to a mouse key binding, see
|
||||
.Sx MOUSE SUPPORT ) .
|
||||
@@ -6058,8 +6073,9 @@ also raises zoomed panes and
|
||||
.Ic off
|
||||
raises none.
|
||||
A floating or zoomed pane that is covered by a zoomed pane is always raised
|
||||
when it is made active; a tiled pane that is covered unzooms every pane
|
||||
instead.
|
||||
when it is made active, and a hidden pane is shown; a tiled pane that is
|
||||
covered hides the zoomed panes instead, as the desktop does, so that the tiled
|
||||
panes are shown, and the desktop shows them again.
|
||||
Moving the mouse onto a pane with
|
||||
.Ic focus\-follows\-mouse
|
||||
makes it active without raising it, so
|
||||
@@ -7445,6 +7461,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "pane_floating_flag" Ta "" Ta "1 if pane is floating"
|
||||
.It Li "pane_format" Ta "" Ta "1 if format is for a pane"
|
||||
.It Li "pane_height" Ta "" Ta "Height of pane"
|
||||
.It Li "pane_hidden_flag" Ta "" Ta "1 if pane is hidden"
|
||||
.It Li "pane_id" Ta "#D" Ta "Unique pane ID"
|
||||
.It Li "pane_in_mode" Ta "" Ta "Number of modes pane is in"
|
||||
.It Li "pane_index" Ta "#P" Ta "Index of pane"
|
||||
|
||||
5
tmux.h
5
tmux.h
@@ -1348,6 +1348,8 @@ struct window_pane {
|
||||
#define PANE_CAPTUREALLKEYS 0x100000
|
||||
#define PANE_FLOATOVERZOOM 0x200000
|
||||
#define PANE_CLOSEONCANCEL 0x400000
|
||||
#define PANE_HIDDEN 0x800000
|
||||
#define PANE_HIDDENALL 0x1000000
|
||||
|
||||
bitstr_t *sync_dirty;
|
||||
u_int sync_dirty_size;
|
||||
@@ -1593,6 +1595,7 @@ struct layout_cell {
|
||||
|
||||
struct layout_geometry g;
|
||||
struct layout_geometry fg; /* saved floating pane */
|
||||
struct layout_geometry tg; /* saved tiled pane, when hidden */
|
||||
|
||||
struct window_pane *wp;
|
||||
struct layout_cells cells;
|
||||
@@ -3721,6 +3724,8 @@ struct window_pane *window_add_pane(struct window *, struct window_pane *,
|
||||
u_int, int);
|
||||
void window_resize(struct window *, u_int, u_int, int, int);
|
||||
void window_pane_send_resize(struct window_pane *, u_int, u_int);
|
||||
void window_hide_pane(struct window_pane *);
|
||||
int window_show_pane(struct window_pane *);
|
||||
void window_raise_pane(struct window_pane *);
|
||||
void window_lower_pane(struct window_pane *);
|
||||
int window_zoom(struct window_pane *);
|
||||
|
||||
116
window.c
116
window.c
@@ -677,7 +677,7 @@ window_pane_floating_overlaps(struct window_pane *fwp, struct window_pane *wp)
|
||||
int fxoff, fyoff, xoff, yoff, border = 0;
|
||||
u_int fsx, fsy, sx, sy;
|
||||
|
||||
if (!window_pane_is_raised(fwp))
|
||||
if (!window_pane_is_raised(fwp) || !window_pane_is_visible(fwp))
|
||||
return (0);
|
||||
|
||||
window_pane_full_size_offset(fwp, &fxoff, &fyoff, &fsx, &fsy);
|
||||
@@ -763,10 +763,12 @@ window_activate_pane(struct window *w, struct window_pane *wp, int notify,
|
||||
|
||||
log_debug("%s: pane %%%u", __func__, wp->id);
|
||||
|
||||
if (wp == w->active)
|
||||
return (0);
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
return (0);
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
window_show_pane(wp);
|
||||
if (wp == w->active)
|
||||
return (0);
|
||||
if (!window_pane_is_visible(wp)) {
|
||||
/*
|
||||
* The pane is covered by a zoomed pane. A tiled pane that is
|
||||
@@ -1012,6 +1014,82 @@ window_raise_pane(struct window_pane *wp)
|
||||
redraw_invalidate_scene(w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hide a pane. It keeps its place in the layout and in the stacking order and
|
||||
* stays zoomed or floating, so showing it again puts it back as it was.
|
||||
*/
|
||||
void
|
||||
window_hide_pane(struct window_pane *wp)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct layout_cell *lc = wp->layout_cell;
|
||||
struct window_pane *wp1;
|
||||
|
||||
if ((wp->flags & PANE_HIDDEN) || wp == w->modal || lc == NULL)
|
||||
return;
|
||||
|
||||
/* A tiled pane gives its space to a neighbour. */
|
||||
if (layout_cell_is_tiled(lc)) {
|
||||
memcpy(&lc->tg, &lc->g, sizeof lc->tg);
|
||||
layout_remove_tile(w, lc);
|
||||
}
|
||||
wp->flags |= PANE_HIDDEN;
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
/* Move the focus to the last used pane or the top one that is seen. */
|
||||
if (wp == w->active) {
|
||||
TAILQ_FOREACH(wp1, &w->last_panes, sentry) {
|
||||
if (wp1 != wp && window_pane_is_visible(wp1))
|
||||
break;
|
||||
}
|
||||
if (wp1 == NULL) {
|
||||
TAILQ_FOREACH(wp1, &w->z_index, zentry) {
|
||||
if (wp1 != wp && window_pane_is_visible(wp1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wp1 != NULL)
|
||||
window_set_active_pane(w, wp1, 1);
|
||||
}
|
||||
|
||||
events_fire_window("window-layout-changed", w);
|
||||
redraw_invalidate_scene(w);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
|
||||
/* Show a hidden pane. Returns -1 if a tiled pane has no room. */
|
||||
int
|
||||
window_show_pane(struct window_pane *wp)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct layout_cell *lc = wp->layout_cell;
|
||||
int tiled;
|
||||
|
||||
if (~wp->flags & PANE_HIDDEN)
|
||||
return (0);
|
||||
|
||||
tiled = (lc != NULL && !window_pane_is_floating(wp));
|
||||
if (tiled && layout_insert_tile(w, lc) != 0)
|
||||
return (-1);
|
||||
wp->flags &= ~(PANE_HIDDEN|PANE_HIDDENALL);
|
||||
|
||||
/* Try to get back the size the pane had. */
|
||||
if (tiled && lc->parent != NULL && lc->tg.sx != UINT_MAX) {
|
||||
if (lc->parent->type == LAYOUT_LEFTRIGHT)
|
||||
layout_resize_pane_to(wp, lc->parent->type, lc->tg.sx);
|
||||
else
|
||||
layout_resize_pane_to(wp, lc->parent->type, lc->tg.sy);
|
||||
}
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
events_fire_window("window-layout-changed", w);
|
||||
redraw_invalidate_scene(w);
|
||||
server_redraw_window(w);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Move a pane to the back of the panes it is stacked with. */
|
||||
void
|
||||
window_lower_pane(struct window_pane *wp)
|
||||
@@ -1150,7 +1228,7 @@ window_zoomed_pane(struct window *w)
|
||||
if (~w->flags & WINDOW_ZOOMED)
|
||||
return (NULL);
|
||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||
if (wp->flags & PANE_ZOOMED)
|
||||
if ((wp->flags & PANE_ZOOMED) && (~wp->flags & PANE_HIDDEN))
|
||||
return (wp);
|
||||
}
|
||||
return (NULL);
|
||||
@@ -1296,9 +1374,14 @@ window_pane_at_index(struct window *w, u_int idx)
|
||||
struct window_pane *
|
||||
window_pane_next_by_number(struct window *w, struct window_pane *wp, u_int n)
|
||||
{
|
||||
struct window_pane *start;
|
||||
|
||||
for (; n > 0; n--) {
|
||||
if ((wp = TAILQ_NEXT(wp, entry)) == NULL)
|
||||
wp = TAILQ_FIRST(&w->panes);
|
||||
start = wp;
|
||||
do {
|
||||
if ((wp = TAILQ_NEXT(wp, entry)) == NULL)
|
||||
wp = TAILQ_FIRST(&w->panes);
|
||||
} while ((wp->flags & PANE_HIDDEN) && wp != start);
|
||||
}
|
||||
|
||||
return (wp);
|
||||
@@ -1308,9 +1391,15 @@ struct window_pane *
|
||||
window_pane_previous_by_number(struct window *w, struct window_pane *wp,
|
||||
u_int n)
|
||||
{
|
||||
struct window_pane *start;
|
||||
|
||||
for (; n > 0; n--) {
|
||||
if ((wp = TAILQ_PREV(wp, window_panes, entry)) == NULL)
|
||||
wp = TAILQ_LAST(&w->panes, window_panes);
|
||||
start = wp;
|
||||
do {
|
||||
wp = TAILQ_PREV(wp, window_panes, entry);
|
||||
if (wp == NULL)
|
||||
wp = TAILQ_LAST(&w->panes, window_panes);
|
||||
} while ((wp->flags & PANE_HIDDEN) && wp != start);
|
||||
}
|
||||
|
||||
return (wp);
|
||||
@@ -1375,7 +1464,10 @@ window_count_panes(struct window *w, int with_floating)
|
||||
u_int n = 0;
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (with_floating || !window_pane_is_floating(wp))
|
||||
if (with_floating)
|
||||
n++;
|
||||
else if (!window_pane_is_floating(wp) &&
|
||||
(~wp->flags & PANE_HIDDEN))
|
||||
n++;
|
||||
}
|
||||
return (n);
|
||||
@@ -1444,6 +1536,8 @@ window_pane_printable_flags(struct window_pane *wp)
|
||||
flags[pos++] = 'Z';
|
||||
if (window_pane_is_floating(wp))
|
||||
flags[pos++] = 'F';
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
flags[pos++] = 'H';
|
||||
if (wp->flags & PANE_FLOATOVERZOOM)
|
||||
flags[pos++] = 'A';
|
||||
if (wp == w->modal)
|
||||
@@ -2155,6 +2249,8 @@ window_pane_is_visible(struct window_pane *wp)
|
||||
struct window *w = wp->window;
|
||||
struct window_pane *wp1;
|
||||
|
||||
if (wp->flags & PANE_HIDDEN)
|
||||
return (0);
|
||||
if (~w->flags & WINDOW_ZOOMED)
|
||||
return (1);
|
||||
|
||||
@@ -2162,7 +2258,7 @@ window_pane_is_visible(struct window_pane *wp)
|
||||
TAILQ_FOREACH(wp1, &w->z_index, zentry) {
|
||||
if (wp1 == wp)
|
||||
return (1);
|
||||
if (wp1->flags & PANE_ZOOMED)
|
||||
if ((wp1->flags & PANE_ZOOMED) && (~wp1->flags & PANE_HIDDEN))
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
|
||||
Reference in New Issue
Block a user