Layout Modes

Floating, BSP, master-stack, scrolling columns and zoom, and how to switch between them.

Tiling is a switch: on or off. When it is on, the panes follow one of three layouts. When it is off, the panes float and you place them yourself. Zoom sits on top of all of them and shows one pane large for a moment.

Try it live: the Layouts track lets you switch between them in your browser.

ModeWhat it does
BSPA tree of splits. Any number of panes, each resizable on its own. The default. See BSP Tiling.
Master-stackOne or more master panes on one side, and the other panes in a stack beside them.
ScrollingNiri-style columns on a strip wider than the screen. The screen scrolls instead of every pane shrinking.
FloatingTiling off. Panes can overlap, and you move, snap and resize them.

Open, close and focus panes below to see how each layout places them:

Layout
3 / 9 panes
Preselect where the next pane goespreselect

3 panes. The next pane opens side by side with pane 3.

A new pane splits the focused one. With the default spiral scheme the split turns from side by side to stacked as the tree gets deeper. Preselect a side to choose it yourself. Click a pane to focus it.

Switching modes

Turn tiling on or off:

KeyWhere
tWindow management mode
Ctrl+B SpaceAny mode

Pick the layout from the command palette (Ctrl+P):

  • Layout: BSP tiling
  • Layout: master-stack
  • Layout: scrolling (niri-style)
  • Layout: disable tiling

Picking a layout also turns tiling on. There is no default key for a layout. Bind one yourself if you switch often.

The layout mode belongs to the session. It is kept in the daemon's session state, so a scrolling session is still scrolling after you detach and reattach, and turning tiling off does not forget which layout you had. The layout itself (the BSP tree, the scrolling columns) is kept per workspace, so each of the nine workspaces has its own.

startup.layout sets the mode a new session starts in: bsp, master-stack or scrolling. startup.tiled (default true) decides whether a new session starts tiled at all. A session that already exists keeps its own mode.

[startup]
layout = "scrolling"
tiled = true

From a script, tuios set-layout turns tiling on or off and tidies the splits:

tuios set-layout --tiling true
tuios set-layout --equalize
tuios set-layout --rotate

It needs an attached client.

Master-stack

The master-stack layout puts the first panes of a workspace in a master area and the other panes in a stack beside it. The master area is for the pane you work in most, such as an editor. The layout is close to dwm's tile layout and Hyprland's master layout.

OptionDefaultMeaning
appearance.master_positionleftThe side the masters take: left, right, top, bottom or center
appearance.master_count1How many panes are masters (1 to 9). The masters share the master area in equal parts
appearance.master_ratio50The share of the screen the master area takes, as a percent (10 to 90)
appearance.master_gridtrueWith one master on the left, show four or more panes as an equal grid. false keeps the master and the stack at every pane count

With center, the first stack pane goes to the right, the next to the left, and so on. With only one stack pane, the master goes to the left. Two panes on a screen that is taller than it is wide stack one above the other.

Each workspace starts with these options. The keys below change the workspace on screen, and the workspace keeps the change. In a daemon session every attached client shows the same layout.

KeyActionWhat it does
Ctrl+B L ocycle_master_positionMove the masters to the next side
Ctrl+B L Enterswap_with_masterSwap the focused pane with the master. On the master, swap with the first stack pane
Ctrl+B L mfocus_masterFocus the master
Ctrl+B L iadd_masterMake one more pane a master
Ctrl+B L dremove_masterMake one pane fewer a master
< / > (window mode)resize_master_shrink, resize_master_growNarrow or widen the master area
= (window mode), Ctrl+B =equalize_splits, prefix_equalize_splitsPut the master back at master_ratio and give every other pane an equal share
tuios set-layout --master-position center
tuios set-layout --masters 2

How a resize is kept

A resize goes into the workspace's splits: the master ratio, and the share of every other pane. That covers each master, each stack pane, and each row and pane of the grid. The keyboard resizes, the percentage resizes and a mouse drag on a divider all do this, so the resize survives a retile. A terminal resize is a retile too. When a pane opens or closes, the part of the layout it changes goes back to equal shares.

With the master in the center, a resize moves one divider, and the next retile puts the master back in the middle at its new width. The splits are session state, so every client attached to the session lays the workspace out the same way.

In every layout, a workspace keeps its splits when the session's size changes while the workspace is off screen. When you switch back, the panes fit the new size.

Scrolling

The scrolling layout is modeled on the niri window manager. Each pane is a column on a horizontal strip, and the screen is a window onto that strip. A new pane gets a new column right after the focused one, and the strip scrolls to show it. The other columns keep their width.

A column holds one pane by default. It can hold several stacked vertically, which split its height evenly. Closing the last pane in a column removes the column and moves focus to the column on its left.

Moving around

InputAction
Alt+Left / Alt+Right (terminal mode)Focus the column to the left or right
h / l (window mode)Focus the column to the left or right
j / k (window mode), Alt+Down / Alt+Up (terminal mode)Focus the pane below or above in a column of stacked panes
Alt+P / Alt+NFocus the column to the left or right
H / L, or Ctrl+Left / Ctrl+Right (window mode)Move the focused column left or right along the strip
< / > (window mode)Shrink or grow the focused column by four cells
Alt or Shift + mouse wheelScroll the strip sideways

Moving focus with the keyboard scrolls the strip by the least amount that shows the whole focused column, with four cells of its neighbour peeking in beside it. It does not center the column: when all of it and that margin are already on screen, the strip stays put. Clicking a column that is partly off screen brings all of it on screen (appearance.niri_click_reveals). With focus_follows_mouse on, hovering does the same (appearance.niri_hover_reveals).

The plain mouse wheel belongs to the pane under the pointer. The strip only scrolls while Alt or Shift is held. This stops a trackpad's sideways drift from sliding the strip while you scroll a pane's history.

Column commands

These have palette entries and no default key. The action names can be bound in [keybindings].

Palette entryActionWhat it does
Scroll: cycle column widthscroll_cycle_widthCycle the focused column through 33%, 50%, 55%, 67% and 90% of the screen, and 100% when scroll_column_max is 100
Scroll: maximize column widthscroll_maximizeWiden the focused column to scroll_column_max, the widest the strip gives it
Scroll: move window into the column belowscroll_consumePull the pane from the next column into the focused one, stacked below
Scroll: move window out to its own columnscroll_expelMove the focused pane out of its column into a new column to the right. Focus follows it, so expel undoes a consume
nonescroll_focus_left, scroll_focus_rightFocus the column to the left or right
nonescroll_move_left, scroll_move_rightMove the focused column left or right

A column's width is a share of the screen until you resize it with < or >, which pins it to a cell count. Each press changes the width by four cells, from 20 cells up to scroll_column_max. Cycling the width unpins it again.

Settings

KeyDefaultMeaning
appearance.scroll_column_width55Width of a new column, as a percent of the screen (20 to 100)
appearance.scroll_column_max90The widest a column may be set, as a percent. 100 lets a column fill the screen, and the next column no longer peeks in
appearance.niri_scroll_cells8Cells the strip moves per wheel event (1 to 200)
appearance.niri_reverse_scrollfalseReverse the wheel direction on the strip
appearance.niri_click_revealstrueClicking a partly hidden column scrolls it fully into view
appearance.niri_hover_revealstrueWith focus-follows-mouse, hovering does the same

The default column width of 55% is over half on purpose: two columns never quite fit, so the strip reads as something you scroll.

The scroll offset and the columns are part of the session. Every client attached to the session sees the same columns at the same offset, and the columns come back after a session switch or a reattach. A session switch forgot my column widths tells how the columns became session state.

Shared borders: with shared_borders on, columns draw no border of their own. One divider stands between two columns. Drag it to set the width of the column on its left. Windows stacked in one column have a divider between them too, but they always share the column's height evenly.

Limits: the strip always animates when it slides, even with animations off, because a jump is hard to follow.

Floating

With tiling off, panes float. Drag a pane by its title bar to move it, or Alt+drag anywhere on it. Right-drag resizes it from the nearest corner. In window management mode:

KeyAction
h / lSnap to the left or right half
fSnap to full screen
uUnsnap
Ctrl+B L 1-4Snap to a corner

Dragging a pane to a screen edge or corner snaps it there too. See Keybindings.

The palette entry Toggle floating lifts only the focused pane out of the tiling and lets it float over the others. Run it again to put the pane back.

For a short-lived floating pane that closes when its program exits, use a popup:

tuios popup --width 90% --height 80% -- htop

Zoom

Zoom shows the focused pane over the layout. By default it takes 95% of the screen, so the edges of the layout stay visible around it. The layout underneath is not changed.

KeyWhere
zWindow management mode
Ctrl+B zAny mode

On a tiled pane, the third title bar control toggles zoom too (appearance.window_button_zoom).

KeyDefaultMeaning
appearance.zoom_size95Share of the screen a zoomed pane takes, as a percent (50 to 100). 100 is fullscreen
appearance.zoom_max_width0Width cap in cells. 0 means no cap. Useful on an ultrawide display
appearance.zoom_borderlessfalseShow the zoomed pane on the whole pane region, with no border and no title bar. The program in the pane gets the full size. The dock and the rail stay on the screen. With it on, zoom_size and zoom_max_width have no effect
appearance.zoom_follows_focustrueMoving focus while zoomed zooms the pane you moved to
appearance.zoom_animationtrueSlide between the tile and the zoomed box instead of switching in one frame

Gaps and sizing

appearance.gap keeps empty cells between neighbouring panes, in every tiling mode (0 to 8, default 0). It is an inner gap only: there is no margin at the screen edge.

The layout prefix sizes the focused pane to a percentage:

KeyAction
Ctrl+B L 5-9Width to 50%, 60%, 70%, 80% or 90% of the content area
Ctrl+B L Shift+5-9Height to 50% through 90%

Each percentage is its own action (resize_width_50 to resize_width_90, resize_height_50 to resize_height_90), so any of them can be rebound in [keybindings.layout_prefix]. The layout still applies its minimum pane size and gaps. In the scrolling layout only the width actions do anything.

gap, master_ratio, scroll_column_width and shared_borders decide how many cells each pane gets, so they are shared across the session: change one on any client and every attached client follows. Purely visual settings such as the theme, border style and glyphs stay per client.

Finding a pane

The palette entry All windows opens a searchable list of every pane on every workspace, with a short preview of each. It has no default key.

KeyAction
TypeFilter by title, workspace number, preview text or directory
Up / Down, Ctrl+P / Ctrl+NMove the selection
EnterGo to the pane: switch workspace, restore it if minimized, focus it
Ctrl+UClear the query
EscClose

The preview is the first three non-empty lines of the pane, taken when the list opens. The directory is only read on Linux.

Typing into several panes

Multifocus sends your typing to several panes at once, like tmux's synchronize-panes. Use it to run the same command on several hosts.

InputAction
Ctrl+Shift+click on a paneAdd or remove it from the set
Palette: Toggle multifocus, or action toggle_multifocus_activeAdd or remove the focused pane
Palette: Toggle multifocus on all panes, or action toggle_multifocus_allAdd every visible pane on the workspace. When all of them are in the set, remove them. Panes on other workspaces stay in the set
Palette: Clear multifocusEmpty the set

The two actions have no default key. This example binds them to Ctrl+B y and Ctrl+B Y:

[keybindings.prefix_mode]
toggle_multifocus_active = ["y"]
toggle_multifocus_all = ["Y"]

To open many panes with multifocus on in one step, use tuios xpanes. It opens one pane per item on a new workspace, tiled, and puts all of them in the set:

tuios xpanes --ssh web1 web2 web3

From a script, tuios run-command SetMultifocus <window>... sets the set to exactly these windows. With no window, it empties the set.

Panes in the set get a distinct border colour. A notification shows the size of the set when you change it. With appearance.dim_unfocused on, the panes in the set are not dimmed. Set appearance.dim_multifocus = true to dim them like the other panes.

While the set is not empty and you are in terminal mode, every key that goes to the focused pane also goes to each pane in the set. A paste goes to each pane in the set too. A pane gets a bracketed paste only when its program turned bracketed paste on. A paste into a scrolled pane first returns it to live output, as a typed key does. In copy mode, TUIOS drops the paste. Keys that TUIOS handles itself, such as the leader key, are not copied.

Limits:

  • Nothing is copied in window mode.
  • A key goes only to the panes of the set that are on the current workspace and are not minimized. The other panes stay in the set and get keys again when they are on screen.
  • The set belongs to your client. Other clients do not share it. It does not survive a detach, and a session switch clears it.
  • The set follows panes, not positions. A swap keeps the same panes in the set. A pane that closes leaves the set.
  • A popup cannot join the set.

Multi copy mode

Multi copy mode is copy mode on every pane of the multifocus set at the same time. Use it to search the output of many panes at once and copy the same part from each pane. Each pane has its own cursor and its own selection. Each key moves all of them together.

To start it, add two or more panes to the multifocus set and focus one of them. Then press Ctrl+B [, the copy mode key. When the focused pane is not in the set, the key starts copy mode on one pane. When multifocus is on, the palette entry Multi copy mode also starts it, and the prefix menu shows Multi copy (N) on the [ line.

The dock shows MULTI 3, where 3 is the number of panes. After a search, it shows MULTI 2/3: the search found text in 2 of the 3 panes.

KeyAction
h j k l, w b e, g G and the other copy mode motionsMove the cursor in every pane
/ or ?, then text, then EnterSearch every pane. Each pane goes to its own match
n / NGo to the next or previous match in each pane
v / VStart a character or line selection in every pane that has a match
EscEnd the selection. A second Esc, or q, leaves copy mode in every pane
yCopy the selection of each pane to the clipboard, as one block
YSave the selection of each pane to a file
TabChange the format: plain, markdown, json
Shift+Up / Shift+DownScroll every pane one line

A pane where the search finds no text loses the multifocus border colour. With a theme, the pane is also dimmed. It keeps its cursor. It takes no motions or selections until a later search finds text in it. Ctrl+L clears the search.

y copies only the selected text of each pane. A pane without a selection adds nothing. The panes are in window order.

FormatWhat it writes
plainThe selected lines of each pane, one pane after the other. Each pane ends with a newline. Nothing is added. Use it when each line already names its host
markdownFor each pane, a ## Pane N: title heading and the lines in a fenced code block
jsonAn array with one object for each pane: {"pane": N, "window_id": "...", "title": "...", "lines": ["..."]}. The pane number is the index that tuios list-windows --json shows

The format starts as appearance.selection.multi_format (default plain). Tab changes it until you leave multi copy mode.

appearance.selection.copy_command and a [[keybindings.copy_pipe]] key also work in multi copy mode. The command gets the text that y copies, in the current format, one time for all panes. See Pipe a yank through a command.

Y opens a prompt at the bottom of the focused pane. The default path is ~/tuios-copy-<date>-<time>.<ext>, with txt, md or json for the format. Type or paste a path. Press Enter to save, or Esc to cancel.

  • A relative path starts in the directory of the focused pane, when its shell reports one. Otherwise it starts in your home directory. The line above the prompt shows the full path.
  • TUIOS does not write over a file that exists. It tells you when the folder does not exist or when the path is a folder.
  • The dock shows the path of the file it wrote. In the web client and over SSH, the file is on the machine that runs TUIOS, and the dock names that machine.

A pane title can come from a remote shell. In the markdown and json formats, TUIOS removes control, bidirectional and zero-width characters from the title and cuts it to 200 characters.

Limits:

  • Soft-wrapped lines are joined by a width estimate, as in copy mode on one pane.
  • Multi copy mode ends when focus moves to a pane that is not in it.
  • A pane that you minimize or move to another workspace leaves multi copy mode.
  • The clipboard gets the copy through OSC 52. Some terminals cut a long OSC 52 copy. Above 100 KB, the dock tells you. Use Y to save a large copy to a file.

On this page