Skip to content

Add per-pane-border option - #5433

Open
redesigndavid wants to merge 28 commits into
tmux:masterfrom
redesigndavid:feat/per-window-border
Open

Add per-pane-border option#5433
redesigndavid wants to merge 28 commits into
tmux:masterfrom
redesigndavid:feat/per-window-border

Conversation

@redesigndavid

@redesigndavid redesigndavid commented Jul 26, 2026

Copy link
Copy Markdown

Summary

  • Add a window option per-pane-border that draws a full border around each tiled pane (inset geometry + redraw).
  • Keep display-panes aligned with that layout: draw indexes using per-pane borders, fill the window while active, and hide scrollbars so the overlay is not shifted.
  • Update the display-panes regress coverage for the no-scrollbar overlay sizes.

Test plan

  • set -w per-pane-border on with multiple tiled panes and confirm each pane gets a full border
  • Toggle pane-border-status (top/bottom/off) with per-pane-border and confirm no blank/grey opposite edge
  • display-panes / prefix-q with and without scrollbars; indexes should not shift when scrollbars are enabled
  • cd regress && gmake (or run display-panes.sh at minimum), though a few of the tests are broken even in master.

asciicast

@github-project-automation github-project-automation Bot moved this to Not Started in Open Issues & PRs Jul 26, 2026
@redesigndavid
redesigndavid marked this pull request as ready for review July 26, 2026 03:29
@nicm

nicm commented Jul 26, 2026

Copy link
Copy Markdown
Member

Looks OK but I don't like the option name, it should be something starting with pane-border- to match the others.

I'm not sure about having WINDOW_PANESMODE rather than generic flags and if we do have it those fixes seem like they are separate?

In window_panes_mark_per_pane_borders, you need {} around the if bodies where they cross multiple lines.

In screen-redraw.c, we do not want to call options_get_number for every pane, this is a window option and can be cached.

@nicm nicm moved this from Not Started to Waiting in Open Issues & PRs Jul 26, 2026
@redesigndavid

redesigndavid commented Jul 26, 2026 via email

Copy link
Copy Markdown
Author

@nicm

nicm commented Jul 26, 2026

Copy link
Copy Markdown
Member

I don't like pane-border-surround. Feels like this should be part of pane-border-lines but not sure I want to double the number of choices. Leave it as it is for the moment and I'll think about it.

@nicm

nicm commented Jul 26, 2026

Copy link
Copy Markdown
Member

Maybe pane-border-type (or -model or something?) and choices are joined or separate?

@redesigndavid

Copy link
Copy Markdown
Author

Yeah, pane-border-type with joined or separate sounds as good as any? Let me make that update.

@nicm

nicm commented Jul 26, 2026

Copy link
Copy Markdown
Member

New option needs to go in tmux.1 also.

@nicm

nicm commented Jul 27, 2026

Copy link
Copy Markdown
Member

OK a few minor issues:

  • When I have two panes side by side or one above the other, only one of the borders works to resize when dragged with the mouse, the other border does not (behaves as if inside pane).

  • selectp -U, -L etc do not work.

  • {left}, {top} targets are also broken, probably for the same reason (selectp -t '{top}').

  • main-vertical seem to place the right hand border of the right pane outside the window in some circumstances (seems to depend on what the width and height is). Same for main-horizontal with the bottom border.

  • There are similar problems with placement of cells after resize, for example try this, the right pane is now outside the window:

tmux new \; set -g pane-border-type separate \; splitw -h \; resize-pane -x 1

I also think we could do with adding test coverage for this feature.

@redesigndavid

Copy link
Copy Markdown
Author

I did find another bug. When you have pane-border-status enabled, and click on x, it seems impossible to click on yes. But the bug seems to exist in master too so I didn't bring it up. Shall we include a fix for that too?

@nicm

nicm commented Jul 28, 2026

Copy link
Copy Markdown
Member

I do not see this problem in master, the menu works fine. How do you reproduce?

@redesigndavid

Copy link
Copy Markdown
Author

On master, set status-position to 'top' and pane-border-status to 'top' or 'bottom'.

Screen.Recording.2026-07-28.at.20.18.20.mov

@nicm

nicm commented Jul 28, 2026

Copy link
Copy Markdown
Member

It works OK for me but the mouse position is one line off, I'll fix it.

@nicm

nicm commented Jul 29, 2026

Copy link
Copy Markdown
Member

OK this seems to work well for me. A few comments:

I think all these:

PANE_BORDER_TYPE_IS_SEPARATE(options_get_number(w->options,
+           "pane-border-type")

Would be neater if you just dropped PANE_BORDER_TYPE_IS_SEPARATE and added a helper int window_border_type_is_separate(struct window *). This would get rid of a lot of wrapped lines.

Any if body that crosses more than one line needs {}, even if it is only one statement, so here:

+               if (!fill)
+                       layout_apply_pane_border_type(w, root, lc, &wp->xoff,
+                           &wp->yoff, &sx, &sy);

There are a couple of others too I think.

Maybe rename layout_pane_minimum to layout_pane_minimum_size?

I think some or all the new comments are probably either unnecessary or too big...

The !blank checks in redraw_draw_border_span could probably be tidied up into nested ifs.

Can WINDOW_MODE_HIDE_SCROLLBARS be done as a separate PR to get it out of the way? Could add WINDOW_MODE_FILL_WINDOW also even if it doesn't do anything yet.

@lollipopman

Copy link
Copy Markdown

I have always wanted this feature, thanks for implementing it! I just tested it out on a local build and it seems to work great, <3

@redesigndavid

Copy link
Copy Markdown
Author

Thank you, very encouraging!

@redesigndavid

Copy link
Copy Markdown
Author

@nicm, I believe we've hit all points, yes?

@nicm

nicm commented Jul 30, 2026

Copy link
Copy Markdown
Member

I'm away but I'll look when I'm back on Monday, thanks.

@nicm

nicm commented Aug 3, 2026

Copy link
Copy Markdown
Member

Looks pretty good. Two other minor issues:

  • splitw can still create panes that are too small, for example splitw -fh -l 1. These can end up with the border overwriting other pane borders instead of resizing them, for example:
image
  • The same thing can happen with selectl -E, for example:
./tmux -vvLx new \; set -g pane-border-type separate \; splitw -h \; splitw -h \; splitw -h \; resizew -x10 \; selectl -E
image

@redesigndavid

Copy link
Copy Markdown
Author

Thanks! Pushed fixes and tests to address both.

@nicm

nicm commented Aug 4, 2026

Copy link
Copy Markdown
Member

If you do this:

./tmux -Lx new \; splitw -fhl1 \; set -g pane-border-type separate

You end up with the right pane wrong. Not sure if this is worth fixing if it isn't easy.

This does not work properly (the selectp -D does not change the pane):

./tmux -Lx new \; set pane-border-type separate \; set pane-border-status bottom \; splitw -v \; selectp -D

I think redraw_draw_ctx could do with a cached border_type as well for redraw_draw_border_span.

This may be an existing problem - this is an error:

./tmux -Lx new \; resizew -x 5 -y 8 \; set pane-scrollbars on \; set -g pane-border-type separate \; set pane-scrollbars-style 'width=2,pad=1' \; splitw -h

But this gets in a muddle instead:

./tmux -Lx new \; resizew -x 5 -y 8 \; set pane-scrollbars on \; set -g pane-border-type joined \; set pane-scrollbars-style 'width=2,pad=1' \; splitw -h

I think both cases should be an error.

@redesigndavid

Copy link
Copy Markdown
Author

Interesting, let me have a look.

@redesigndavid

Copy link
Copy Markdown
Author

Okay pushing updates:

For item 1: on options_push_changes for pane-border-type, reflow so cells under the new minimums grow.

For 2–4: fix select-pane wrap with separate + bottom status; cache border_type on the draw context; for always-on scrollbars, LEFTRIGHT space counts both bars so tiny splits fail cleanly instead of leaving broken pane sizes.

@nicm

nicm commented Aug 4, 2026

Copy link
Copy Markdown
Member

OK there are still some minor things with small windows, but TBH I am not wild about layout_rebalance_mins and friends, they seem like overkill. I wonder if we should access some weirdness to get away from having to do this, so long as tmux does not do anything really crazy or crash.

@redesigndavid

Copy link
Copy Markdown
Author

Let me spend a few more hours later to see if I can think of a cleaner fix?

@nicm

nicm commented Aug 5, 2026

Copy link
Copy Markdown
Member

OK thanks. TBH I think we could probably live with the borders overlapping at small sizes so long as tmux does not crash or behave incorrectly. Anyone with a window that is just too small for the panes can't really expect it to work usefully, so long as it goes back to normal when the window is big enough again.

When the window is big enough it should probably do the right thing with small panes though.

This reverts commit 8f87186, deemed a fix not worth a fix for such an edge case.
@redesigndavid

Copy link
Copy Markdown
Author

Just pushed updates that revert the layout rebalance helpers. Yeah, it is definitely an edge case (didn't want to miss the chance to use that pun).

The broken case seems to occur specifically when you do the split while in joined border type and then switch to separate. No odd borders when you do the split while already in pane-border-type separate:

  ./tmux -Lx new \; set -g pane-border-type separate \; splitw -fhl1

Chances are most users won't switch between joined and separate that often, or have enough splits in a tiny window to hit this. Happy to leave it as accepted weirdness for such edge cases.

@nicm

nicm commented Aug 6, 2026

Copy link
Copy Markdown
Member

I think this is OK but I am away next week so I will probably not look at it until I am home again. This will be a 3.9 feature in any case.

@nicm nicm moved this from Waiting to For Review in Open Issues & PRs Aug 6, 2026
@nicm nicm mentioned this pull request Aug 6, 2026
17 tasks
@redesigndavid

Copy link
Copy Markdown
Author

Thank you for taking care of this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: For Review

Development

Successfully merging this pull request may close these issues.

4 participants