Default to native border for Zellij floating pane (#4854)

The native border is the handle for moving and resizing the pane with
the mouse, so use it by default, consistent with tmux. fzf draws its
own border only when a border style is explicitly specified with
--border. Extract the shared native-border decision into a helper.
This commit is contained in:
Junegunn Choi
2026-07-06 21:04:35 +09:00
committed by GitHub
parent f7392a8b63
commit e54f11c64e
4 changed files with 55 additions and 20 deletions
+15 -8
View File
@@ -183,17 +183,24 @@ exit "$code"`, newPane, code, signal, signal, code, code, code)
}, opts, true)
}
// Whether to use the multiplexer's native border for the floating pane. Its
// native border is the handle that makes the pane movable and resizable with
// the mouse, so it is the default; 'border-native' forces it. It is not used
// when a border style is explicitly specified with --border, so that the
// fzf-drawn border is the only one shown. 'none' and 'line' are treated as no
// border; fzf draws no box for either, and 'line' only makes sense with
// --height.
func nativeBorder(opts *Options) bool {
return opts.Tmux.border || opts.BorderShape == tui.BorderUndefined ||
opts.BorderShape == tui.BorderLine || opts.BorderShape == tui.BorderNone
}
func runTmux(args []string, opts *Options) (int, error) {
// On tmux 3.7 or above, fzf runs in a floating pane instead of a popup.
// A floating pane always has a native border, so 'border-native' is
// implied. When a border style is explicitly specified with --border, a
// When the native border is not used (an explicit --border style), a
// popup is used instead so that the fzf-drawn border is the only border
// shown; the native border of a floating pane cannot be removed. 'none'
// and 'line' are treated as no border; fzf draws no box for either, and
// 'line' only makes sense with --height. Give 'border-native' to force
// a floating pane nonetheless.
if opts.Tmux.border || opts.BorderShape == tui.BorderUndefined ||
opts.BorderShape == tui.BorderLine || opts.BorderShape == tui.BorderNone {
// shown; the native border of a tmux floating pane cannot be removed.
if nativeBorder(opts) {
if windowWidth, windowHeight, ok := tmuxFloatingPaneInfo(); ok {
opts.Tmux.border = true
argStr, dir := popupArgStr(args, opts)
+25
View File
@@ -2,9 +2,18 @@ package fzf
import (
"os/exec"
"github.com/junegunn/fzf/src/tui"
)
func runZellij(args []string, opts *Options) (int, error) {
// Use the native Zellij border by default, consistent with tmux, so that
// the pane can be moved and resized with the mouse. Set before
// popupArgStr so that it does not inject an fzf border. fzf draws its own
// border instead when a border style is explicitly specified.
if nativeBorder(opts) {
opts.Tmux.border = true
}
argStr, dir := popupArgStr(args, opts)
zellijArgs := []string{
@@ -13,6 +22,22 @@ func runZellij(args []string, opts *Options) (int, error) {
}
if !opts.Tmux.border {
zellijArgs = append(zellijArgs, "--borderless", "true")
} else {
// Set --border-label as the name of the pane, displayed on the
// native border. The label is left to fzf when it draws its own
// border with the label on it (border-native with an explicit
// --border style). Empty otherwise, to override the default name
// (the running command). Passed as a single argument in the
// --name=label form; the detached form fails to parse when the
// label starts with a hyphen. No escaping is needed beyond
// stripping ANSI sequences fzf would otherwise render itself.
// --border-label-pos is ignored.
label := ""
if opts.BorderShape == tui.BorderUndefined || opts.BorderShape == tui.BorderLine ||
opts.BorderShape == tui.BorderNone {
label, _, _ = extractColor(opts.BorderLabel.label, nil, nil)
}
zellijArgs = append(zellijArgs, "--name="+label)
}
switch opts.Tmux.position {
case posUp: