greymd / tmux-xpanes

Awesome tmux-based terminal divider
MIT License
1.96k stars 61 forks source link

Number of columns incorrectly set in speedy mode #157

Open frafra opened 3 years ago

frafra commented 3 years ago

If there are 3 arguments, and the total number of available columns in C, the third pane has C/2 columns (half the size), the second pane has (2/3)*(C/2) columns (two-sixth), and the first one has (1/3)*(C/2) columns (a sixth).

This seems to happen only in speedy mode -s or -ss, independently of the layout chosen (but it is easier to view in ev mode).

Screenshot from 2020-10-31 12-51-28

$ tmux -V
tmux 2.9a
$ xpanes -V
xpanes 4.1.1
$ lsb_release -sd
"Fedora release 31 (Thirty One)"
greymd commented 3 years ago

Thanks a lot. I could also reproduce this issue on macOS. I will working on it soon.

$ xpanes -l ev -c 'stty size' 1 2 3

Screenshot 2020-11-07 at 22 47 44

greymd commented 3 years ago

@frafra Try this workaround for a while, as it may take some time to fix this bug. Adding the alias to ~/.bashrc might mitigate this issue (if you use Bash).

_cmd='stty `tmux display-message -p "rows #{pane_height} cols #{pane_width}"`'
alias xpanes="xpanes -B '${_cmd}'"
greymd commented 1 year ago

I could repro the issue without xpanes.

#!/bin/bash

## Create new session of tmux
tmux new-session -d -s "my_session" -d "/bin/sh"
## Split window vertically
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
## Set layout to vertically lined up
tmux select-layout -t "my_session" even-vertical
## Show all pane id
tmux list-panes -t "my_session" -F "#{pane_id}" | while read -r pane_id; do
    ## Send command to each pane
    tmux send-keys -t "my_session.$pane_id" "stty size" C-m
done

## Attach to session
tmux attach-session -t "my_session"

Screenshot 2023-02-02 at 21 46 01

greymd commented 1 year ago

Open an interactive shell such as /bin/sh, wait a few moments, and the column count will return to normal. Here is the code for reproduction.

#!/bin/bash

## Create new session of tmux
tmux new-session -d -s "my_session" -d "/bin/sh"
## Split window vertically
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
## Set layout to vertically lined up
tmux select-layout -t "my_session" even-vertical

cmd='printf "%$(tput cols)s\\n" "" | tr " " @'
## Show all pane id
tmux list-panes -t "my_session" -F "#{pane_id}" | while read -r pane_id; do
    ## Send command to each pane
    tmux send-keys -t "my_session.$pane_id" "stty size" C-m
    tmux send-keys -t "my_session.$pane_id" "$cmd" C-m
    tmux send-keys -t "my_session.$pane_id" "sleep 1" C-m
    tmux send-keys -t "my_session.$pane_id" "stty size" C-m
    tmux send-keys -t "my_session.$pane_id" "$cmd" C-m
done

## Attach to session
tmux attach-session -d -t "my_session"

Screenshot 2023-02-02 at 21 58 24

greymd commented 1 year ago

I've tried below workaround, but does not work. It seems terminal size is adjusted after attaching session. Therefore, It is not possible to estimate the actual window size before attaching.

#!/bin/bash

## Create new session of tmux
tmux new-session -d -s "my_session" -d "/bin/sh"
## Split window vertically
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
tmux split-window -v -t "my_session:0" -h -d "/bin/sh"
## Set layout to vertically lined up
tmux select-layout -t "my_session" even-vertical

cmd='printf "%$(tput cols)s\\n" "" | tr " " @'
tmux list-panes -t "my_session" -F "#{pane_id}" | while read -r pane_id; do

    ##### Adjust new pane size before sending commands
    a="$(tmux display-message -t "my_session:0.$pane_id" -p "rows #{pane_height} cols #{pane_width}")"
    tmux send-keys -t "my_session.$pane_id" "stty $a" C-m

    ## Send command to each pane
    tmux send-keys -t "my_session.$pane_id" "stty size" C-m
    tmux send-keys -t "my_session.$pane_id" "$cmd" C-m
    tmux send-keys -t "my_session.$pane_id" "sleep 1" C-m
    tmux send-keys -t "my_session.$pane_id" "stty size" C-m
    tmux send-keys -t "my_session.$pane_id" "$cmd" C-m
done

## Attach to session
tmux attach-session -d -t "my_session"

Screenshot 2023-02-02 at 22 25 33

greymd commented 1 year ago

I have no idea if this behavior is a bug in tmux or not.

But the fact is that many minor versions of tmux follow this behavior. Therefore, it is worth putting in some mitigation on the xpanes side. A sure way appears to be to force the following command to be executed when the -s option is executed.

stty `tmux display-message -p "rows #{pane_height} cols #{pane_width}"`
greymd commented 1 year ago

More insuitive way to reproduce

$ xpanes -s -lev -c 'printf "%$(tput cols)s\\n" "" | tr " " @' 1 2 3
greymd commented 1 year ago

I noticed that just adding -B 'sleep 1' resolves the issue. Just give tmux time to update the terminal cols and rows.

$ xpanes -s -l ev -c 'printf "%`tput cols`s\\n" "" | tr " " @' 1 2 3 4 5

=> Broken layout

Screenshot 2023-02-02 at 22 55 52
$ xpanes -s -l ev -B 'sleep 1' -c 'printf "%`tput cols`s\\n" "" | tr " " @' 1 2 3 4 5

=> Resolved!

Screenshot 2023-02-02 at 22 56 04