mirror of
https://github.com/tmux/tmux.git
synced 2026-10-06 17:49:52 +00:00
Hide the zoomed panes when a covered tiled pane is activated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,8 +77,18 @@ cmd_resize_pane_desktop(struct window *w)
|
||||
shown = 1;
|
||||
}
|
||||
}
|
||||
if (shown)
|
||||
if (shown) {
|
||||
/* Do not leave the active pane covered by a pane just shown. */
|
||||
if (!window_pane_is_visible(w->active)) {
|
||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||
if (window_pane_is_visible(wp))
|
||||
break;
|
||||
}
|
||||
if (wp != NULL)
|
||||
window_set_active_pane(w, wp, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp == w->modal || (wp->flags & PANE_HIDDEN))
|
||||
|
||||
@@ -121,10 +121,10 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
if (active != -1) {
|
||||
wp = rotated[active];
|
||||
window_set_active_pane(w, wp, 1);
|
||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||
if (zwp != NULL)
|
||||
window_zoom_move(zwp, wp);
|
||||
window_set_active_pane(w, wp, 1);
|
||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||
}
|
||||
redraw_invalidate_scene(w);
|
||||
server_redraw_window(w);
|
||||
|
||||
@@ -193,14 +193,15 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (!visible && Zflag)
|
||||
zwp = window_zoomed_pane(w);
|
||||
window_redraw_active_switch(w, lastwp);
|
||||
if (window_set_active_pane(w, lastwp, 1)) {
|
||||
cmd_find_from_winlink(current, wl, 0);
|
||||
cmd_select_pane_redraw(w);
|
||||
}
|
||||
if (zwp != NULL) {
|
||||
window_zoom_move(zwp, lastwp);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
if (window_set_active_pane(w, lastwp, 1) ||
|
||||
zwp != NULL) {
|
||||
cmd_find_from_winlink(current, wl, 0);
|
||||
cmd_select_pane_redraw(w);
|
||||
}
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -273,14 +274,14 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (!visible && Zflag)
|
||||
zwp = window_zoomed_pane(w);
|
||||
window_redraw_active_switch(w, wp);
|
||||
if (window_set_active_pane(w, wp, 1))
|
||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||
cmdq_insert_hook(s, item, current, "after-select-pane");
|
||||
cmd_select_pane_redraw(w);
|
||||
if (zwp != NULL) {
|
||||
window_zoom_move(zwp, wp);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
if (window_set_active_pane(w, wp, 1) || zwp != NULL)
|
||||
cmd_find_from_winlink_pane(current, wl, wp, 0);
|
||||
cmdq_insert_hook(s, item, current, "after-select-pane");
|
||||
cmd_select_pane_redraw(w);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -147,11 +147,11 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (!visible && Zflag)
|
||||
zwp = window_zoomed_pane(w);
|
||||
window_redraw_active_switch(w, wp);
|
||||
window_set_active_pane(w, wp, 1);
|
||||
if (zwp != NULL) {
|
||||
window_zoom_move(zwp, wp);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
window_set_active_pane(w, wp, 1);
|
||||
}
|
||||
if (wl != NULL) {
|
||||
session_set_current(s, wl);
|
||||
|
||||
@@ -144,17 +144,32 @@ zoomed "$Y" 1
|
||||
zoomed "$A" 1
|
||||
window_zoomed "$X" 1
|
||||
|
||||
# Activating a tiled pane that is not zoomed unzooms every pane but the
|
||||
# floats stay floats.
|
||||
# Activating a tiled pane that is not zoomed hides the zoomed panes, as the
|
||||
# desktop does, and shows the tiles. They stay zoomed, and floats that are not
|
||||
# zoomed stay where they are.
|
||||
run select-pane -t "$B"
|
||||
check "$B" '#{pane_active}' 1
|
||||
for p in "$A" "$B" "$X" "$Y"; do
|
||||
for p in "$A" "$Y"; do
|
||||
zoomed "$p" 1
|
||||
check "$p" '#{pane_hidden_flag}' 1
|
||||
done
|
||||
for p in "$B" "$X"; do
|
||||
zoomed "$p" 0
|
||||
check "$p" '#{pane_hidden_flag}' 0
|
||||
done
|
||||
window_zoomed "$B" 0
|
||||
check "$X" '#{pane_floating_flag}' 1
|
||||
check "$Y" '#{pane_floating_flag}' 1
|
||||
|
||||
# The desktop shows them again.
|
||||
run resize-pane -a -H -t "$A"
|
||||
for p in "$A" "$Y"; do
|
||||
zoomed "$p" 1
|
||||
check "$p" '#{pane_hidden_flag}' 0
|
||||
done
|
||||
window_zoomed "$B" 1
|
||||
run resize-pane -a -Z -t "$A"
|
||||
|
||||
# Activating a tiled pane that is itself zoomed does not unzoom it.
|
||||
run resize-pane -Z -t "$A"
|
||||
run select-pane -t "$A"
|
||||
|
||||
@@ -237,6 +237,48 @@ run resize-pane -a -H -t "$A"
|
||||
hidden "$A" 0
|
||||
hidden "$X" 0
|
||||
|
||||
# Activating a tiled pane that is covered by zoomed panes hides them, as the
|
||||
# desktop does: they stay zoomed, the tiles are shown and the pane is active.
|
||||
reset
|
||||
C=$(run split-window -dPF '#{pane_id}') || exit 1
|
||||
run resize-pane -Z -t "$A"
|
||||
run resize-pane -Z -t "$B"
|
||||
run select-pane -t "$C"
|
||||
check "$C" '#{pane_active}' 1
|
||||
for p in "$A" "$B"; do
|
||||
hidden "$p" 1
|
||||
check "$p" '#{pane_zoomed_flag}' 1
|
||||
done
|
||||
hidden "$C" 0
|
||||
check "$C" '#{window_zoomed_flag}' 0
|
||||
# The last pane brings back the one that was zoomed.
|
||||
run select-pane -l
|
||||
check "$B" '#{pane_active}:#{pane_hidden_flag}:#{window_zoomed_flag}' '1:0:1'
|
||||
# The desktop shows the others, and the active pane is not left covered.
|
||||
run select-pane -t "$C"
|
||||
run resize-pane -a -H -t "$A"
|
||||
for p in "$A" "$B"; do
|
||||
hidden "$p" 0
|
||||
done
|
||||
check "$A" '#{window_zoomed_flag}' 1
|
||||
visible=$(run list-panes -F '#{pane_active}#{pane_zoomed_flag}' | grep -c '^11$')
|
||||
[ "$visible" = 1 ] || fail "active pane is covered after the desktop"
|
||||
|
||||
# select-pane -Z moves the zoom to a covered tiled pane without hiding the old
|
||||
# one, and so do last-pane -Z and rotate-window -Z.
|
||||
reset
|
||||
run resize-pane -Z -t "$A"
|
||||
run select-pane -Z -t "$B"
|
||||
check "$B" '#{pane_zoomed_flag}:#{pane_active}' '1:1'
|
||||
check "$A" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '0:0'
|
||||
run select-pane -Z -t "$A"
|
||||
run select-pane -Z -l
|
||||
check "$B" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:0'
|
||||
check "$A" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '0:0'
|
||||
run rotate-window -Z
|
||||
check "$A" '#{pane_hidden_flag}' 0
|
||||
check "$B" '#{pane_hidden_flag}' 0
|
||||
|
||||
# Floating and tiling a hidden pane keeps it hidden.
|
||||
reset
|
||||
run resize-pane -H -t "$B"
|
||||
|
||||
@@ -320,7 +320,7 @@ check_ok resize-pane -Z -t "$p0"
|
||||
check_fmt "$p0" '#{window_zoomed_flag}' '0'
|
||||
|
||||
# Splitting while zoomed with -d leaves the zoom alone; without -d the new
|
||||
# pane is active and covered, so selecting it unzooms.
|
||||
# pane is active and covered, so selecting it hides the zoomed pane.
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
|
||||
check_ok split-window -d -v -t "$p0"
|
||||
@@ -334,16 +334,25 @@ check_fmt 'P:0' '#{window_zoomed_flag}' '0'
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
check_ok split-window -v -t "$p0"
|
||||
check_fmt 'P:0' '#{window_zoomed_flag}' '0'
|
||||
check_fmt "$p0" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:1'
|
||||
p6=$($TMUX display-message -p -t P:0 '#{pane_id}')
|
||||
check_ok kill-pane -t "$p6"
|
||||
check_ok resize-pane -a -H -t "$p0"
|
||||
check_ok resize-pane -a -Z -t "$p0"
|
||||
|
||||
# Zoom and unzoom preserve the exact tiled layout. Selecting another pane
|
||||
# without -Z unzooms, while -Z transfers zoom to the selected pane.
|
||||
# without -Z hides the zoomed pane until the desktop shows it, while -Z
|
||||
# transfers zoom to the selected pane.
|
||||
layout=$(pane_layout P:0)
|
||||
check_ok select-pane -t "$p0"
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
check_ok select-pane -t "$p2"
|
||||
check_fmt "$p2" '#{window_zoomed_flag}:#{pane_active}' '0:1'
|
||||
check_fmt "$p0" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:1'
|
||||
check_ok resize-pane -a -H -t "$p0"
|
||||
check_fmt "$p0" '#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_active}' \
|
||||
'1:1:1'
|
||||
check_ok resize-pane -a -Z -t "$p0"
|
||||
check_layout P:0 "$layout"
|
||||
|
||||
check_ok select-pane -t "$p0"
|
||||
@@ -355,7 +364,7 @@ check_ok resize-pane -Z -t "$p2"
|
||||
check_layout P:0 "$layout"
|
||||
|
||||
# Directional selection temporarily restores the full layout to find its
|
||||
# neighbour, then follows the same unzoom or -Z transfer rules.
|
||||
# neighbour, then follows the same hide or -Z transfer rules.
|
||||
check_ok select-pane -t "$p0"
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
check_ok select-pane -t "$p0"
|
||||
@@ -363,6 +372,9 @@ check_fmt "$p0" '#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_active}' \
|
||||
'1:1:1'
|
||||
check_ok select-pane -D -t "$p0"
|
||||
check_fmt "$p2" '#{window_zoomed_flag}:#{pane_active}' '0:1'
|
||||
check_fmt "$p0" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:1'
|
||||
check_ok resize-pane -a -H -t "$p0"
|
||||
check_ok resize-pane -a -Z -t "$p0"
|
||||
|
||||
check_ok select-pane -t "$p0"
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
@@ -379,6 +391,9 @@ check_ok resize-pane -Z -t "$p2"
|
||||
check_ok select-pane -l -t P:0
|
||||
check_fmt "$p0" '#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_active}' \
|
||||
'0:0:1'
|
||||
check_fmt "$p2" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:1'
|
||||
check_ok resize-pane -a -H -t "$p0"
|
||||
check_ok resize-pane -a -Z -t "$p0"
|
||||
|
||||
check_ok select-pane -t "$p0"
|
||||
check_ok select-pane -t "$p2"
|
||||
|
||||
@@ -93,6 +93,21 @@ function noZoom( i)
|
||||
fail("pane " aid[i] " is still zoomed")
|
||||
}
|
||||
}
|
||||
function hideZoomed(t, i, id, want)
|
||||
{
|
||||
sameZ("")
|
||||
for (i = 1; i <= nb; i++) {
|
||||
id = bid[i]
|
||||
if (id == t || !(id in ina))
|
||||
continue
|
||||
want = (bH[id] || bZ[id]) ? 1 : 0
|
||||
if (aH[id] != want)
|
||||
fail("pane " id " zoomed " bZ[id] " hidden " bH[id] \
|
||||
" became hidden " aH[id])
|
||||
}
|
||||
if (aH[t])
|
||||
fail("pane " t " is still hidden")
|
||||
}
|
||||
function covered(t, i, q)
|
||||
{
|
||||
if (bF[t] || bZ[t])
|
||||
@@ -177,8 +192,9 @@ END {
|
||||
if (op == "select") {
|
||||
if (aA[T] != 1) fail("not active")
|
||||
if (aH[T]) fail("still hidden")
|
||||
if (covered(T)) noZoom(); else sameZ("")
|
||||
sameF(""); sameH(T)
|
||||
if (covered(T)) hideZoomed(T)
|
||||
else { sameZ(""); sameH(T) }
|
||||
sameF("")
|
||||
} else if (op == "zoom") {
|
||||
sameF("")
|
||||
if (bZ[T]) {
|
||||
@@ -195,12 +211,12 @@ END {
|
||||
if (bH[T]) {
|
||||
if (aH[T]) fail("not shown")
|
||||
if (aA[T] != 1) fail("not active when shown")
|
||||
if (covered(T)) noZoom(); else sameZ("")
|
||||
if (covered(T)) hideZoomed(T)
|
||||
else { sameZ(""); sameH(T) }
|
||||
} else {
|
||||
if (!aH[T]) fail("not hidden")
|
||||
sameZ("")
|
||||
sameZ(""); sameH(T)
|
||||
}
|
||||
sameH(T)
|
||||
} else if (op == "desktop") {
|
||||
sameF(""); sameZ("")
|
||||
for (i = 1; i <= nb; i++) {
|
||||
@@ -267,11 +283,12 @@ END {
|
||||
sameF(""); sameH(""); noZoom()
|
||||
} else {
|
||||
# Moving around or changing layout: floating panes stay floating
|
||||
# and nothing is hidden.
|
||||
# and only a zoomed pane is hidden, when a covered pane is made
|
||||
# active.
|
||||
sameF("")
|
||||
for (i = 1; i <= nb; i++) {
|
||||
id = bid[i]
|
||||
if (id in ina && aH[id] > bH[id])
|
||||
if (id in ina && aH[id] > bH[id] && !bZ[id])
|
||||
fail("pane " id " was hidden by this")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,14 +337,20 @@ check_fmt 'R:0' '#{pane_index}:#{pane_id}' "0:$p1"
|
||||
check_ok rotate-window -D -t R:0
|
||||
check_fmt 'R:0' '#{pane_index}:#{pane_id}' "0:$p0"
|
||||
|
||||
# Rotation without -Z unzooms. With -Z it preserves zoom and transfers it to
|
||||
# the pane which arrives at the active position.
|
||||
# Rotation without -Z hides the zoomed pane until the desktop shows it. With -Z
|
||||
# it preserves zoom and transfers it to the pane which arrives at the active
|
||||
# position.
|
||||
layout=$($TMUX display-message -p -t R:0 '#{window_layout}')
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
check_ok rotate-window -U -t R:0
|
||||
check_fmt "$p1" '#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_active}' \
|
||||
'0:0:1'
|
||||
check_fmt "$p0" '#{pane_zoomed_flag}:#{pane_hidden_flag}' '1:1'
|
||||
check_ok resize-pane -a -H -t "$p0"
|
||||
check_ok resize-pane -a -Z -t "$p0"
|
||||
check_ok rotate-window -D -t R:0
|
||||
check_ok select-pane -t "$p1"
|
||||
check_ok select-pane -t "$p0"
|
||||
check_fmt 'R:0' '#{window_layout}' "$layout"
|
||||
|
||||
check_ok resize-pane -Z -t "$p0"
|
||||
|
||||
36
window.c
36
window.c
@@ -75,6 +75,8 @@ static void window_pane_free(struct window_pane *);
|
||||
static void window_pane_scrollbar_timer(int, short, void *);
|
||||
static int window_activate_pane(struct window *, struct window_pane *, int,
|
||||
int);
|
||||
static void window_hide_one(struct window_pane *, int);
|
||||
static void window_hide_zoomed(struct window *);
|
||||
static void window_pane_full_size_offset(struct window_pane *, int *, int *,
|
||||
u_int *, u_int *);
|
||||
|
||||
@@ -775,14 +777,14 @@ window_activate_pane(struct window *w, struct window_pane *wp, int notify,
|
||||
return (0);
|
||||
if (!window_pane_is_visible(wp)) {
|
||||
/*
|
||||
* The pane is covered by a zoomed pane. A tiled pane that is
|
||||
* not zoomed can only be reached by unzooming (any floats
|
||||
* stay); anything else can be raised above the zoom.
|
||||
* The pane is covered by a zoomed pane. Raise it above the zoom
|
||||
* if it can be, otherwise (a tiled pane that is not zoomed) hide
|
||||
* the zoomed panes, as the desktop does, to show the tiles.
|
||||
*/
|
||||
if (window_pane_is_raised(wp))
|
||||
window_raise_pane(wp);
|
||||
else
|
||||
window_unzoom(w, 1);
|
||||
window_hide_zoomed(w);
|
||||
} else if (raise) {
|
||||
/* Raise the pane if the option says to. */
|
||||
switch (options_get_number(w->options, "pane-raise-on-focus")) {
|
||||
@@ -1041,6 +1043,30 @@ window_count_tiled_siblings(struct layout_cell *lc)
|
||||
*/
|
||||
void
|
||||
window_hide_pane(struct window_pane *wp)
|
||||
{
|
||||
window_hide_one(wp, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hide every zoomed pane that is not hidden, marking them as the desktop does so
|
||||
* that it shows them again. The focus is left for the caller to move.
|
||||
*/
|
||||
static void
|
||||
window_hide_zoomed(struct window *w)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if ((wp->flags & PANE_ZOOMED) && (~wp->flags & PANE_HIDDEN)) {
|
||||
window_hide_one(wp, 0);
|
||||
wp->flags |= PANE_HIDDENALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide a pane, moving the focus away from it if it is active and asked to. */
|
||||
static void
|
||||
window_hide_one(struct window_pane *wp, int refocus)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct layout_cell *lc = wp->layout_cell;
|
||||
@@ -1068,7 +1094,7 @@ window_hide_pane(struct window_pane *wp)
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
/* Move the focus to the last used pane or the top one that is seen. */
|
||||
if (wp == w->active) {
|
||||
if (refocus && wp == w->active) {
|
||||
TAILQ_FOREACH(wp1, &w->last_panes, sentry) {
|
||||
if (wp1 != wp && window_pane_is_visible(wp1))
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user