Zoomed panes are now like full screen floating panes.

This commit is contained in:
Michael Grant
2026-09-30 23:10:40 +01:00
parent 5a820e63b7
commit 7810f8abf3
29 changed files with 752 additions and 621 deletions

View File

@@ -56,6 +56,7 @@ for mode in before after detached modal; do
-x 20 -y 8 -X 8 -Y 3 '') || exit 1
if [ "$mode" = before ]; then
run resize-pane -Z -t "$base"
run select-pane -t "$float"
fi
run set -gu @unzoomed
check_zoom
@@ -131,28 +132,29 @@ for z in 1 0 99; do
check_zoom
done
run resize-pane -Z -t "$base"
check "$float" '#{pane_z}' 2
check "$float" '#{pane_z}' 1
check "$hidden" '#{pane_z}' 2
check "$base" '#{pane_z}' 4
run kill-pane -t "$hidden"
run kill-pane -t "$back"
# Explicit zoom toggling and operations on tiled panes retain their
# existing behaviour. The over-zoom flag alone does not make a pane a float:
# zooming the float itself gives it a tiled cell until unzoom.
# Zooming a float keeps it floating. Resizing a zoomed float unzooms just that
# pane, but operations on other panes leave a zoom alone.
run resize-pane -Z -t "$float"
check "$float" '#{pane_zoomed_flag}:#{pane_floating_flag}' '1:0'
check "$float" '#{pane_zoomed_flag}:#{pane_floating_flag}' '1:1'
run resize-pane -t "$float" -x 25
check "$float" '#{window_zoomed_flag}:#{pane_floating_flag}:#{pane_width}' \
'0:1:23'
run resize-pane -Z -t "$base"
run resize-pane -t "$other" -D 1
check "$base" '#{window_zoomed_flag}' 0
check "$base" '#{window_zoomed_flag}' 1
run resize-pane -Z -t "$base"
# A hidden ordinary float must still be unzoomed before resizing it.
# A float covered by a zoom can be resized without unzooming.
hidden=$(run new-pane -dPF '#{pane_id}' -t "$base" '') || exit 1
run resize-pane -Z -t "$base"
run resize-pane -t "$hidden" -x 25
check "$hidden" '#{window_zoomed_flag}:#{pane_floating_flag}:#{pane_width}' \
'0:1:23'
'1:1:23'
exit 0

View File

@@ -537,8 +537,8 @@ case "$(fmt "$ignored" '#{pane_flags}')" in
*) ;;
esac
# Existing floating panes are filtered when zoom begins: -A panes remain in the
# visible layout and ordinary floating panes do not.
# Existing floating panes stay floating when zoom begins: -A panes remain above
# the zoom and ordinary floating panes are covered by it.
check_ok new-window -d -t modal: -n existing-over-zoom 'cat'
base=$(fmt modal:existing-over-zoom '#{pane_id}')
check_ok split-window -dh -t "$base" 'cat'
@@ -552,10 +552,10 @@ check_ok select-window -t modal:existing-over-zoom
check_ok select-pane -t "$base"
check_ok resize-pane -Z -t "$base"
must_equal "$(fmt "$over" '#{pane_floating_flag}')" 1
must_equal "$(fmt "$under" '#{pane_floating_flag}')" 0
must_equal "$(fmt "$under" '#{pane_floating_flag}')" 1
must_equal "$(fmt "$base" '#{window_zoomed_flag}:#{pane_zoomed_flag}')" 1:1
# Geometry changed in the visible zoom layout is copied back when unzooming.
# Geometry changed while zoomed is kept when unzooming.
check_ok select-pane -t "$over"
left=$(fmt "$over" '#{pane_left}')
top=$(fmt "$over" '#{pane_top}')
@@ -593,8 +593,8 @@ done
must_equal "$(fmt "$base" '#{window_zoomed_flag}:#{pane_zoomed_flag}')" 1:1
# A pane with -A is also above a zoom target which was itself floating. The
# temporary tiled target must sit behind retained floating panes, then return
# to the normal floating z order when unzoomed.
# target must sit behind the -A pane, then return to the normal floating z
# order when unzoomed.
check_ok new-window -d -t modal: -n floating-zoom-target 'cat'
base=$(fmt modal:floating-zoom-target '#{pane_id}')
check_ok split-window -dh -t "$base" 'cat'
@@ -606,13 +606,13 @@ over=$($TMUX new-pane -AdPF '#{pane_id}' -t "$base" \
fail "float-over-zoom pane creation failed"
check_ok select-window -t modal:floating-zoom-target
check_ok select-pane -t "$target"
must_equal "$(fmt "$target" '#{pane_z}')" 0
must_equal "$(fmt "$over" '#{pane_z}')" 1
must_equal "$(fmt "$target" '#{pane_z}')" 1
must_equal "$(fmt "$over" '#{pane_z}')" 0
check_ok resize-pane -Z -t "$target"
must_equal "$(fmt "$target" \
'#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_floating_flag}:#{pane_z}')" \
1:1:0:2
1:1:1:1
must_equal "$(fmt "$over" '#{pane_floating_flag}:#{pane_z}')" 1:0
check_ok select-pane -t "$over"
must_equal "$(fmt "$over" '#{window_zoomed_flag}:#{pane_active}')" 1:1
@@ -620,13 +620,14 @@ check_ok resize-pane -Z -t "$target"
must_equal "$(fmt "$over" '#{pane_active}:#{pane_z}')" 1:0
must_equal "$(fmt "$target" '#{pane_floating_flag}:#{pane_z}')" 1:1
# If the target remains active, it returns to the front on unzoom.
# A pane with -A stays in front of the target, even when the target is active
# and is zoomed and unzoomed again.
check_ok select-pane -t "$target"
check_ok resize-pane -Z -t "$target"
must_equal "$(fmt "$over" '#{pane_floating_flag}:#{pane_z}')" 1:0
check_ok resize-pane -Z -t "$target"
must_equal "$(fmt "$target" '#{pane_active}:#{pane_z}')" 1:0
must_equal "$(fmt "$over" '#{pane_z}')" 1
must_equal "$(fmt "$target" '#{pane_active}:#{pane_z}')" 1:1
must_equal "$(fmt "$over" '#{pane_z}')" 0
cleanup
exit 0

View File

@@ -166,7 +166,8 @@ check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# break-pane and join-pane.
# break-pane moves a pane to a new window; -P -F prints where it went and -n
# names the new window. Moving a pane out of a zoomed window unzooms it first.
# names the new window. Moving another pane out of a zoomed window leaves the
# zoom alone.
check_ok resize-pane -Z -t "$p0"
out=$($TMUX break-pane -d -P -F '#{window_index}:#{pane_id}' -n broken \
-s "$p1" -t P:)
@@ -176,13 +177,14 @@ if [ "$out" != "1:$p1" ]; then
fi
check_fmt 'P:1' '#{window_name}:#{window_panes}' 'broken:1'
check_fmt 'P:0' '#{window_panes}' '3'
check_fmt 'P:0' '#{window_zoomed_flag}' '0'
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
# join-pane -v moves it back (the source window, left empty, is destroyed) and
# also unzooms the destination before changing its layout.
check_ok resize-pane -Z -t "$p0"
# also leaves the destination zoomed while changing its layout.
check_ok join-pane -d -v -s P:broken.0 -t "$p2"
check_fmt 'P:0' '#{window_panes}' '4'
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
check_ok resize-pane -Z -t "$p0"
check_fmt 'P:0' '#{window_zoomed_flag}' '0'
if $TMUX has-session -t P:broken 2>/dev/null; then
echo "Window 'broken' still exists after join-pane."
@@ -317,14 +319,23 @@ check_fmt "$p0" '#{window_zoomed_flag}:#{pane_width}x#{pane_height}' \
check_ok resize-pane -Z -t "$p0"
check_fmt "$p0" '#{window_zoomed_flag}' '0'
# Splitting while zoomed unzooms first.
# Splitting while zoomed with -d leaves the zoom alone; without -d the new
# pane is active and covered, so selecting it unzooms.
check_ok resize-pane -Z -t "$p0"
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
check_ok split-window -d -v -t "$p0"
check_fmt 'P:0' '#{window_zoomed_flag}' '0'
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
check_fmt 'P:0' '#{window_panes}' '5'
p6=$($TMUX display-message -p -t P:0.2 '#{pane_id}')
check_ok kill-pane -t "$p6"
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
check_ok resize-pane -Z -t "$p0"
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'
p6=$($TMUX display-message -p -t P:0 '#{pane_id}')
check_ok kill-pane -t "$p6"
# Zoom and unzoom preserve the exact tiled layout. Selecting another pane
# without -Z unzooms, while -Z transfers zoom to the selected pane.
@@ -378,7 +389,8 @@ check_fmt "$p0" '#{window_zoomed_flag}:#{pane_zoomed_flag}:#{pane_active}' \
check_ok resize-pane -Z -t "$p0"
check_layout P:0 "$layout"
# Killing either a hidden ordinary pane or the zoom target unzooms.
# Killing a hidden ordinary pane leaves the zoom, and killing the zoom target
# shows what was underneath.
check_ok new-window -d -t P:12 -n zoom-kill 'cat'
zk0=$($TMUX display-message -p -t P:12.0 '#{pane_id}')
zk1=$($TMUX split-window -d -P -F '#{pane_id}' -t P:12.0 'cat')
@@ -386,8 +398,7 @@ zk2=$($TMUX split-window -d -P -F '#{pane_id}' -t P:12.0 'cat')
check_ok resize-pane -Z -t "$zk0"
check_ok kill-pane -t "$zk1"
check_fmt "$zk0" '#{window_panes}:#{window_zoomed_flag}:#{pane_zoomed_flag}' \
'2:0:0'
check_ok resize-pane -Z -t "$zk0"
'2:1:1'
check_ok kill-pane -t "$zk0"
check_fmt "$zk2" '#{window_panes}:#{window_zoomed_flag}:#{pane_zoomed_flag}' \
'1:0:0'
@@ -406,7 +417,7 @@ while [ "$($TMUX display-message -p -t P:13 '#{window_panes}')" != 2 ]; do
[ $i -gt 50 ] && { echo "Hidden pane did not exit."; exit 1; }
sleep 0.1
done
check_fmt "$ze0" '#{window_zoomed_flag}:#{pane_zoomed_flag}' '0:0'
check_fmt "$ze0" '#{window_zoomed_flag}:#{pane_zoomed_flag}' '1:1'
check_ok resize-pane -Z -t "$ze2"
check_ok send-keys -t "$ze2" C-d
i=0

View File

@@ -355,6 +355,24 @@ check_ok resize-pane -Z -t "$p1"
check_ok rotate-window -D -t R:0
check_fmt 'R:0' '#{window_layout}' "$layout"
# Floating panes are not rotated: they keep their geometry and stay floating
# while the tiled panes rotate around them.
fp=$($TMUX new-pane -dPF '#{pane_id}' -t R:0 -x 20 -y 8 -X 8 -Y 3 '')
fgeom=$($TMUX display-message -p -t "$fp" \
'#{pane_floating_flag}:#{pane_left}:#{pane_top}:#{pane_width}:#{pane_height}')
check_ok select-pane -t "$p0"
check_ok rotate-window -U -t R:0
check_fmt "$fp" \
'#{pane_floating_flag}:#{pane_left}:#{pane_top}:#{pane_width}:#{pane_height}' \
"$fgeom"
check_fmt "$p1" '#{pane_floating_flag}:#{pane_top}:#{pane_active}' '0:0:1'
check_ok rotate-window -D -t R:0
check_fmt "$fp" \
'#{pane_floating_flag}:#{pane_left}:#{pane_top}:#{pane_width}:#{pane_height}' \
"$fgeom"
check_fmt "$p0" '#{pane_floating_flag}:#{pane_top}:#{pane_active}' '0:0:1'
check_ok kill-pane -t "$fp"
# ---------------------------------------------------------------------------
# kill-window.