Skip to content

desktop-tui

desktop-tui is a tiny desktop environment that lives in a terminal: overlapping, movable, resizable windows; a taskbar; window chrome with a title bar and an optional close button; and a launcher that starts real programs (e.g. helix) from .toml shortcut files. Windows can float (default) or be fixed-position; “tilling” (tiling) options can be toggled. Each launched app runs inside a window of the TUI desktop. It’s a small project, but it’s a clean, current worked example of multi-window management inside a character grid.

For KN-86 the value is the window-management model and, specifically, how window chrome reads in a constrained terminal — title bars, borders, close affordances, focus, and stacking, all in text. KN-86’s primary surface is a single 80×25 amber grid; if any KN-86 surface ever needs overlapping panels or a “windowed” multi-app feel (a SYS multitasking view, a layered modal stack, an authoring environment), this is the reference for doing it in characters. (Reference “CLAUDE.md Canonical Hardware Specification” for the grid; not restated here.)

  • Overlapping movable/resizable windows — the core feature (“Move and resize windows”). Windows stack with a z-order; the focused window comes forward.
  • Window chrome — each window has a title bar (“Window name”) and a configurable close button (close_button = true). Inner spacing is set by padding; windows can be marked resizable.
  • Floating vs fixed — windows float by default (fixed_position = false) or can be pinned to a fixed position. Tiling is an alternate mode toggled in options.
  • Taskbar — launched apps appear on a taskbar; taskbar.position orders them and taskbar.additional_commands adds contextual launcher entries.
  • App launcher from TOML — each shortcut file declares command, args (with special <FILE_PATH> / <FOLDER_PATH> tokens that pop a file/folder selection dialog before launch), and taskbar placement. Adding an app = dropping a .toml. This config-as-data launcher is a clean pattern: the app roster is declarative, not compiled in.

Rendering is via AppCUI-rs over a crossterm backend, with TRUE_COLORS enabled — so the upstream project is full-color (window backgrounds are RGB, e.g. background_color = { r = 30, g = 30, b = 30 }). But the window-management vocabulary it draws — borders, title bars, a close glyph, a focused-vs-unfocused frame, a taskbar strip — is entirely expressible in box-drawing glyphs + inversion, which is exactly KN-86’s available toolkit. The full-color version is incidental; the chrome geometry is the portable part.

AppCUI-rs is worth noting for the library shortlist in its own right: it’s a Turbo-Vision-descended Rust TUI framework (windows, menus, dialogs, controls as first-class objects), which ties this entry to tvterm.md’s Turbo Vision lineage from the Rust side.

Window chrome in single-color terminals (the focus)

Section titled “Window chrome in single-color terminals (the focus)”

The brief’s specific ask — window chrome in single-color terminals — answered as a recommendation set for KN-86:

  • Borders = box-drawing glyphs. A window is a box: ┌─┐ │ │ └─┘ (single-line) for unfocused, ╔═╗ ║ ║ ╚═╝ (double-line) for the focused window. Using line weight (single vs double) to mark focus is a color-free, instantly-legible convention — the monochrome substitute for “the active window is brighter/tinted.”
  • Title bar = inverted strip. The title bar renders as an inverted run (black-on-amber) across the window’s top edge, with the title text and a close glyph ([x] or ×). Inversion makes the bar pop without color and doubles as a drag-handle affordance.
  • Focus, again, via inversion + border weight. Only one window is focused; it gets the double border and a brighter (inverted) title bar. Unfocused windows get single borders and a non-inverted title. Two cheap channels (border weight + title inversion) fully encode focus state with zero color.
  • Z-order via occlusion. Overlap is its own depth cue — the front window’s box simply overwrites the cells of the windows behind it. No color needed; the geometry carries it.
  • Taskbar = a Row-of-labels strip. A bottom or top strip of window names, the active one inverted. This is the same primitive as mc’s F-key bar and KN-86’s Row 24 — a labeled strip with the active item inverted.
  • Shadows (optional) — a one-cell offset shadow drawn with a dim shade glyph () on the right/bottom edges fakes depth, the classic Turbo Vision look, achievable on the amber grid with the CP437 shading ramp.

The README does not enumerate keybindings; from the feature set the model is move/resize/focus windows, switch via the taskbar, and launch from shortcuts. The transferable point isn’t the specific keys but the interaction model: a focusable stack of windows + a launcher + a taskbar. (KN-86’s own input layer — the 31-key model with hold detection — would supply the actual bindings.)

  • Config-as-data app roster — apps are TOML shortcut files, not compiled-in code. The desktop reads the shortcut directory and populates the launcher/taskbar. This is a clean, KN-86-friendly pattern: a declarative roster the runtime reads at startup (echoes KN-86’s nosh-config.toml and the aesthetic-mode TOML approach noted in 4trk.md).
  • AppCUI-rs object model — windows, controls, and dialogs are framework objects; desktop-tui composes them rather than drawing cells by hand. The lesson for KN-86 isn’t to adopt AppCUI (KN-86 is C/SDL3), but that a window = a first-class object with chrome + focus + content, and the desktop is a manager of a window stack. If KN-86 ever needs a windowed surface, model it as a stack of window objects, not as ad-hoc cell drawing.
  • External-process hosting — desktop-tui launches real terminal programs into windows. KN-86 has no analog (carts are KEC Lisp, not external processes), so this part doesn’t port — but the windowing shell around content does.
  • Windowed/layered surface design — if a KN-86 surface ever needs overlapping panels (a SYS multitasking view, a layered modal/dialog stack over a cart, an authoring IDE), this is the model: a focusable window stack with box-glyph chrome and inversion-marked focus.
  • Declarative launcher roster — a TOML/data-driven app or cart launcher (the bare-deck “what can I run” view) fits KN-86’s existing config-as-data approach; cross-link the bare-deck terminal content brief.
  • Window-chrome convention set (border-weight = focus, inverted title bar, occlusion = depth, shade-glyph shadow) — adopt as the KN-86 house style for any windowed/modal element; reusable UI pattern for the authoring docs.
  • Batch 8. Brief focus was window management + window chrome in single-color terminals — captured above as a concrete convention set.
  • Library shortlist: AppCUI-rs (Turbo-Vision-lineage Rust TUI framework, crossterm backend). Pairs with the Turbo Vision (tvision) note in tvterm.md.
  • Cross-link tvterm.md (Turbo Vision — the C++ ancestor of this windowing style), mc.md (a hand-rolled terminal widget kit doing dialogs/panels), and opentui.md (modern TUI framework). Together these four (mc, desktop-tui, tvterm, opentui) are the windowing/TUI-framework spine of the corpus.
  • The border-weight-for-focus + inverted-title + occlusion-depth triad is the windowing-side instance of the cluster’s convergent monochrome finding (Brogue: glyph=identity; mc: inversion=focus; here: chrome geometry over color).