# LiosBar
LiosBar is a native terminal workspace created by Trevor Knott through Knott
Dynamics. It keeps several real GTK4/VTE terminal sessions alive in one
window and turns a compact sidebar into navigation between them. It also
provides an embeddable Rust/GTK4 session workspace: a host supplies its own
terminal widgets, so embedding does not require a wrapper process.
The sidebar starts on the left. Move it to the right from the header, with
`Ctrl+Shift+B`, with `--sidebar right`, or by setting
`sidebar = "right"` in `~/.config/lios/bar.toml`.
## What it does
- Keeps up to 32 terminal sessions alive while LiosBar is running.
- Switches sessions without restarting shells or losing scrollback.
- Reorders sidebar rows by dragging or with Ctrl+Shift+Page Up/Down.
- Filters sessions by name or shell title without changing the active terminal.
- Previews matching sessions with Up/Down; Enter switches and Escape cancels.
- Scrolls the selected row into view and shows visible/total session counts.
- Inherits the active terminal's working directory for each new session.
- Shows running/exited state and the shell-provided terminal title.
- Renames sessions locally without changing shell state.
- Keeps exited sessions visible so their output can still be inspected.
- Places the session bar on the left by default or persistently on the right.
- Provides a Sidebar Layout menu with saved density, title, and hint choices.
- Uses opaque, non-reused session identifiers within each workspace.
- Confirms multiline, control-character, and unusually large clipboard pastes.
- Installs and removes a desktop launcher with `lios-bar --install` and
`lios-bar --uninstall`.
LiosBar owns only the sessions it launches. It does not discover unrelated
terminal windows, expose terminal byte streams, run a network service, store
credentials, or restore shells after the LiosBar process exits. Use `tmux`,
`screen`, or another multiplexer inside a session when persistence across app
restarts is required.
## Install
LiosBar needs the same GTK4 and VTE GTK4 development libraries as native Lios.
The simplest supported path is:
```sh
cargo install lios
lios install
cargo install --locked lios-bar
lios-bar --install
lios-bar
```
### Linux toolkit compatibility
The standalone terminal uses GTK/GDK 4.0.1+, VTE **GTK4** 0.70+, GLib 2.66+,
and Pango 1.46+, on a working Wayland or X11 display. Newer GTK 4.x runtimes
use the same API family; GTK3 is a different ABI, not a runtime fallback.
The earlier 0.68 VTE requirement was misleading: upstream's 0.68 branch
explicitly disables GTK4 builds. Ubuntu 22.04's stock GTK3 VTE cannot satisfy
the standalone requirement. Use distribution-maintained GTK4 VTE packages;
do not replace system libraries with unmaintained private builds.
Use a coherent distribution library set: newer VTE releases can themselves
require newer GTK, independently of LiosBar's API floor.
`lios-bar --check` (also `--diagnostics`) reports the actual toolkits, display
availability, renderer environment, and VTE security-update advice without
loading settings or starting a shell. Its result covers the native libraries;
a missing display is reported separately. For GPU-driver problems, try
`lios-bar --no-gpu`: this selects Cairo for that launch only and leaves saved
preferences and the cyan/black appearance unchanged. `GDK_BACKEND=x11` or
`GDK_BACKEND=wayland` can select an available display backend explicitly.
The reusable `widget` feature needs GTK 4.0+, not VTE, and remains usable on
Ubuntu 22.04's GTK 4.6. CI defines widget coverage there, plus full terminal
tests on Debian 12 (GTK 4.8/VTE 0.70) and Ubuntu 24.04. The native Cargo graph
guard rejects accidental increases in toolkit API floors. Build probes honor
target-specific pkg-config wrappers and sysroots when cross-compiling; the
appropriate target libraries and compiler are still required.
Lios 0.1.69 and newer can manage the reviewed LiosBar release from
`Preferences → Plugins`. The Lios card installs only its version-pinned
crates.io artifact, records enablement separately from installation, and
launches LiosBar as an independent process. Disabling the card preserves the
binary and does not terminate a workspace that is already running.
From source:
```sh
cargo run
cargo run -- --sidebar right
cargo run -- --working-directory /path/to/project
```
## Keyboard navigation
- `Ctrl+Shift+T`: create a session.
- `Ctrl+PageDown`: select the next session.
- `Ctrl+PageUp`: select the previous session.
- `Ctrl+Shift+PageUp` / `Ctrl+Shift+PageDown`: move the active session up/down without switching terminals; stop at the ends.
- `Ctrl+Shift+W`: close the selected session, with confirmation while running.
- `Ctrl+Shift+R`: rename the selected session.
- `Ctrl+Shift+B`: move the sidebar between left and right and save the choice.
- `Ctrl+Shift+L`: focus the session filter; Up/Down choose a match, Enter switches to it, and Escape clears the filter and returns to the current terminal.
- `Ctrl+Shift+F`: find text inside the selected terminal.
- `Enter` / `Shift+Enter` in Find, or `F3` / `Shift+F3` while Find owns focus or the terminal is focused: next/previous match, wrapping at the ends.
- `Escape` in Find: close it and return focus to the terminal.
- `Ctrl+Shift+C`: copy selected terminal text.
- `Ctrl+Shift+V`: guarded clipboard paste.
- `Shift+Insert`: the same guard while a terminal owns focus; text fields keep their normal paste behavior.
Filtering is literal and case-insensitive, limited to 128 characters. It never
switches or closes your current shell. The cyan outline is a preview, not an
active session: Enter or a row click commits the choice. Close is disabled when
the preview and active terminal differ. Modified arrows and Home/End retain
their normal text-field behavior. Explicit next/previous navigation clears
a filter if necessary to reveal its target. Click the current row to return
keyboard focus to its terminal. Closing the final session closes the workspace;
it does not silently start a replacement shell.
Drag a session row above or below another row to reorder it; cyan insertion
lines show the drop position. Only rows from that same workspace are accepted.
Navigation follows the new order. Ordering is local to the running workspace,
including when filtering; it is not a saved shell-restoration feature.
## Sidebar layout
Use the gear beside **SESSIONS** to switch to compact rows, hide running-session
titles, or hide the keyboard hints. Exit details stay visible, and hidden titles
remain searchable. Reset layout restores only those three choices, not sessions,
sidebar position, terminal colors, or the divider width.
The standalone app remembers these choices in `bar.toml`. Lios stores its own
integrated layout in its `[workspace]` configuration; the files stay separate.
Resized divider widths and session names remain local to each running workspace.
## Find in terminal
Use **Find** in the header or **Ctrl+Shift+F** to search the selected terminal's
scrollback. Queries are literal text, with **Match case** enabled by default and
an optional **Whole words** mode that respects Unicode letters and combining
marks. Press Enter or the arrow buttons to scan; typing does not repeatedly
scan the buffer. Queries are limited to 1,024 characters.
Each session keeps its own query and options until it closes. Switching sessions
dismisses Find and cancels queued scans. Reopen Find to reuse that session's query;
the terminal's grid and running shell stay in place. Exited sessions remain
searchable. This searches terminal text; Ctrl+Shift+L still filters session names.
## Embed as a Rust component
The `widget` feature exposes `SessionWorkspace`, `SessionId`, `SidebarSide`,
`SidebarPreferences`, and `AddError` without pulling in VTE, a shell launcher,
or configuration I/O:
```toml
[dependencies]
lios-bar = { version = "0.1.9", default-features = false, features = ["widget"] }
```
```rust,ignore
use lios_bar::{SessionWorkspace, SidebarSide};
// Run after GTK initialization, on its main thread.
let sessions = SessionWorkspace::new(SidebarSide::Left);
window.set_child(Some(sessions.widget()));
let first = sessions.add(&terminal_widget, "Build")?;
sessions.select(first);
```
Keep the `SessionWorkspace` handle alive while its widget is mounted. Connect
`connect_new_requested` to the host's terminal factory; connect
`connect_close_requested` to the host's confirmation flow and only then call
`remove`. `connect_selected` lets the host route focus, actions, and titles to
the active session. The component retains up to 32 host-provided GTK widgets
without recreating them when switching. It does not install global shortcuts,
change host styling, read terminal contents, or launch processes.
Hosts can call `focus_search` and connect `connect_activated` to their terminal's
focus method. Activation is distinct from selection: clicking an already-selected
row or pressing Escape from the filter can return focus without switching IDs.
Style `.liosbar-session-preview` separately from `:selected`: preview navigation
does not emit selection callbacks or change the visible content widget. The
filter exposes its candidate through GTK's active-descendant relationship.
`SidebarPreferences` controls compact rows, title visibility, and keyboard hints.
Call `set_preferences` before connecting `connect_preferences_changed` to the
host's save flow. Identical values are silent; reset emits one edit and callbacks
may safely re-enter the component. The widget itself never reads or writes config.
`session_ids` returns sidebar order. `reorder(id, index)` moves a retained row;
`move_active(offset)` provides bounded keyboard moves. Invalid or unchanged moves
return false. Neither operation emits selection or activation notifications or
reparents terminal content. The host's session storage can remain keyed by ID.
The standalone app and the integrated workspace in Lios 0.1.85 and newer use this same component.
In Lios, press **Ctrl+Shift+T** to open a workspace with full Lios backgrounds,
prompts, search, Preferences, and session-aware close protection. No separate
install is needed: Lios includes an exact reviewed source snapshot. The 0.1.9
component preserves the 0.1.6 runtime/API and improves its older-GTK GUI test.
The **Lios Preferences standalone plugin card still launches the independent
executable**. It does not silently change to in-process loading. See
[the integration contract](INTEGRATION.md) for both modes and their boundaries.
Lios 0.1.86 pins that card to LiosBar 0.1.7; installation and launch remain explicit.
Lios 0.1.88 pins it to 0.1.8, adding the standalone terminal Find bar.
Lios 0.1.89 pins it to 0.1.9, adding compatibility diagnostics and a software-rendering override.
## Configuration
LiosBar reads `~/.config/lios/bar.toml`, or
`$XDG_CONFIG_HOME/lios/bar.toml` when `XDG_CONFIG_HOME` is set:
```toml
sidebar = "left"
compact = false
show_titles = true
show_hints = true
```
Malformed configuration fails closed with a clear error instead of silently
overwriting the file. Sidebar changes are saved atomically with user-only file
permissions. Relative/absolute config symlinks stay intact and writes update
their target, including a missing target reached through a valid link chain.
Comments and untouched fields stay intact; saving does not insert unrelated
default values. Config files must be regular UTF-8 TOML files of at most 64 KiB.
Saves reload current settings and merge only this window's edited fields;
independent sequential edits are preserved. Standalone processes do not
share a transaction lock, so simultaneous writes can still race.
## Scope and safety
Each sidebar entry is a local VTE child shell. LiosBar passes arguments as
argv, does not invoke a command string, and does not provide arbitrary remote
execution. Closing a live entry warns before the terminal widget and PTY are
removed. Closing the window warns when any owned shell is still running.
Clipboard text pastes directly only when it is a reasonably sized single line
without unsafe control characters. Risky paste confirmation displays counts,
never clipboard contents.
Reads are streamed with a 64 MiB cap and 15-second deadline. Large assessments
run off the GTK thread. Pending reads/assessments are canceled when focus leaves
the terminal or window; the confirmation may take focus, but switching/hiding
its terminal dismisses it. Duplicate paste requests cannot stack dialogs.
For vulnerabilities and the threat boundary, see [SECURITY.md](SECURITY.md).
For ownership and callback boundaries, see
[ARCHITECTURE.md](ARCHITECTURE.md). Maintainers can use the repeatable
[RELEASING.md](RELEASING.md) checklist. The exact boundary between Lios and
this standalone application is documented in [INTEGRATION.md](INTEGRATION.md).
## Author and license
LiosBar is created and maintained by Trevor Knott through Knott Dynamics.
It is distributed under your choice of the MIT License or Apache License 2.0.
See `NOTICE`, `LICENSE-MIT`, and `LICENSE-APACHE`.