Desktop edition
Development reference · View source
Build the desktop edition with cargo build -p runyte-desktop.
Launch target/debug/runyte-desktop --window in a workspace, or add --editor to work
outside one. All existing editor keys and configured keymaps are dispatched by
the same registry. The interface remains the editor’s cell grid, without menus
or toolbars. Window resizing changes the pane geometry and PTY dimensions.
In standalone mode the window close button requests :qa, preserving
unsaved-buffer and running-terminal refusal. In --window --mux it detaches,
leaving all editor state and terminal sessions in the host.
If the host cannot keep up and the bounded input queue fills, the window shows “Some input was lost. Click to dismiss.” The notice remains until clicked. Consecutive queued drags coalesce to their latest position; keys, clicks and paste keep their order.
For the Runyte application icon on Wayland, register the desktop entry with
python3 contrib/packaging/package.py linux --binary target/debug/runyte-desktop before
opening a new window. X11 also receives an icon directly. A macOS .app
packaging helper and the platform limitations are described in the
native desktop integration guide
.
PNG, JPEG, GIF, WebP, BMP, and PDF paths open as read-only media projections in
the destination pane, including from :open, the explorer, the directory tree,
and startup filenames. Other binary types retain the external-program prompt.
Media never becomes an editable source file or a save target. Ordinary pane,
buffer, jump, and close commands remain available. Titles identify PDFs with
[pdf] and images with [image]. Images initially fit the pane while preserving
aspect ratio. Zoom, pan, and selection belong to each pane, so split views of
the same file can differ.
Animated GIF and WebP images play automatically while visible, using their frame
delays and loop counts. A finite animation stops on its last frame. Selecting a
region pauses that pane on the displayed frame; y / Ctrl-c copies from that
frame. Clearing the selection resumes playback. Split panes have independent
playback and selection state. Hidden previews and minimized windows do not keep
an animation timer running; restoring a preview resumes without replaying missed
frames. There are no separate pause, step, or restart bindings.
Frame delays below 20 ms use 100 ms to prevent continuous redraws. Decoding is limited to 1024 frames and 32 MiB of retained raster data per animation, after reduction to 2048 pixels per axis. An animation exceeding either limit shows a clear error in its pane. For example, two 2048×2048 RGBA frames fill the 32 MiB budget. Animated WebP EXIF metadata is limited to 64 KiB. Single-frame files remain still images.
PDFs have a read-only page buffer with one row per page. Once the displayed
page is at fit size and has no selection, Escape reveals this buffer at the
current page. Use normal editor motions,
counts, or buffer search (s or /) to choose a row, then Enter displays that
page. Moving the cursor in the page buffer does not display pages until Enter.
42gg goes to page 42; gg and ge/G go to the first and last pages. Escape
or q from the page buffer opens the source directory with the PDF selected.
In Select mode, either key first clears the selection and returns to Normal mode.
Images have no page buffer: leaving their preview opens the source directory.
Escape first dismisses a pending overlay or key sequence. On zoomed-in media,
the next press returns to fit size in one step, preserving its selection;
subsequent presses clear the selection and then leave the media surface.
This fit-then-clear order applies to images and PDFs alike. Space e goes directly to
the source directory from either media type and selects the source file, just
as it does from a rendered Markdown document. Space E still opens the editor’s
working directory.
In a PDF or image preview, q performs the same fit, clear-selection, and
leave-preview action as Escape, in both Normal and Select mode. Overlays
and pending key sequences retain their own bindings.
| Input in a media pane | Action |
|---|---|
+ / = / - | Zoom in / out |
z f / z 1 | Fit pane / actual raster pixels |
z h, z j, z k, z l | Pan left, down, up, right |
h / l | Pan horizontally |
j / k, vertical arrows, counts | In Normal mode, pan a zoomed PDF vertically; change pages at fit size. Images always pan. |
Ctrl-f / Ctrl-d / Ctrl-n / PageDown | Next PDF page at any zoom |
Ctrl-b / Ctrl-u / Ctrl-p / PageUp | Previous PDF page at any zoom |
42gg / gg / ge or G | Go directly to PDF page 42 / first page / last page |
z z | Center the media |
v, then h/j/k/l or arrows | Extend a PDF word/line selection or an image-region corner; v again stops extending |
% | Select all page text, or the whole image when there is no text |
y / Ctrl-c | Copy selected PDF text or selected image region to the system clipboard |
| Escape | Dismiss overlay or pending keys; then fit → clear selection → PDF page buffer → explorer. Images go directly from cleared selection to explorer. |
| Wheel / Shift-wheel | Pan vertically / horizontally; at fit size, vertical PDF scrolling changes pages |
| Ctrl-wheel (Cmd-wheel on macOS) | Zoom around the pointer |
| Middle-drag or right-drag | Pan |
| Alt-left-drag | Move the pane using the pane drop outline |
| Shift-Alt-left-drag | Extend the pane into neighbouring panes |
| Left-drag on PDF text | Select words in reading order |
| Left-drag on an image | Pan; double-click toggles fit / 2× fit |
| Shift-left-drag | Select a rectangular image region, including on PDFs |
There is no separate PDF page picker or g p binding. The paragraph commands
goto-next-paragraph and goto-previous-paragraph remain available for configured
keys without default bindings; g p and g P do not move between text paragraphs.
Scanned PDFs without embedded text use rectangular selection; the desktop edition
does not perform OCR. Copying a region exports the base page/image raster,
including alpha, without modifying the source file; PDF zoom refinement does
not increase the resolution of copied regions. PDF text selection uses Hayro glyph geometry and content-stream order.
If glyphs lack Unicode mappings or usable geometry, extraction independently
falls back to Poppler’s pdftotext. If both fail, the page remains viewable and
region selection stays available. Complex layout reading order is heuristic;
this is not a full document-layout analysis.
Prompts and key hints remain readable above the media surface. Opening them does not expose internal image placeholder rows or enter the PDF page buffer.
PDF support includes Hayro 0.8, run in a disposable helper process of the same executable. Each page or refinement request automatically falls back to separately installed Poppler tools when Hayro fails or reports unsupported content. If both fail, the pane reports both errors. Hayro supports embedded fonts and its standard Latin substitutes (including recognized nonstandard font names); it does not consult system fonts. Substitution can change glyph shapes and spacing. Other unavailable fonts require Poppler. Encrypted PDFs with an empty user password can open; entering a PDF password is not supported. Rendering runs on one background worker and reports failures inside the pane. Input is limited to regular files up to 128 MiB, decoded images to 8192 pixels per axis and 64 MiB allocation, and PDFs to 10,000 pages. Images are reduced to at most 2048 pixels per axis. PDF pages initially render at 1600 pixels on their longest axis. When that is insufficient for the current zoom or display pixel density, the visible region is rendered again in the background. The base page remains visible while sharper text and vector graphics load. Each refinement is bounded to 4096 pixels per axis and approximately eight million pixels; unusually large or dense displays may still exceed that detail budget. Eight base page/image results and eight visible-region refinements are cached separately using least-recently-used eviction. The base cache is also bounded to 256 MiB, enough for eight animations at their individual limit. GPU images no longer displayed by any pane are released. Zooming, panning, resizing, or leaving a pane cancels refinements that are no longer needed by any visible pane. After a PDF page loads, up to two pages on either side are loaded in the background. Requested pages take priority and interrupt speculative rendering. First loads and jumps beyond the warmed pages can still show a loading message. PDF subprocesses have a 15-second limit per invocation and are killed and reaped during cancellation. Hayro additionally has a 1 GiB address-space budget (on macOS, above the executable’s initial mappings), a 15-second CPU limit, and bounded RGBA output. Its normal path uses no raster temporary files. Poppler fallback retains its temporary PNG/XHTML files and existing limits.
On Linux/macOS, runyte --window --mux creates or attaches to the same
persistent sessions as runyte --mux. Only one interactive frontend attaches
at a time. :detach closes the window and preserves the session; :quit from
the last pane and :quit-all stop a clean session and reuse the window for the
previously visited available running session, closing it when none is available.
Unsaved edits and live terminal children still refuse a stop. Session navigation
uses the same Space Space, Space 1–Space 9, Shift-Left / Shift-Right,
and Ctrl-w a bindings in either frontend.
Media panes survive frontend handoff. A terminal client retains their [pdf]
or [image] title and displays Media viewing needs the Runyte window: use the desktop edition with --window in the
body; Escape and Space e still reach the source directory. Opening a binary
while the terminal client is attached uses the external-program prompt. A
window attachment opens supported media in panes, with decoding and PDF
rasterization performed by the window process.
The window client needs the desktop edition; either edition can serve the
persistent host or attach as a terminal client. Every client, host, and
integrated runyte --wait must use the same Runyte version; a private protocol
mismatch is refused at the handshake. Integrated Claude Code and Codex Ctrl-g edits work through
this persistent host and survive detach and frontend handoff.
The native window supports ide, editor, and mux modes; host and lifecycle
modes are CLI operations. The desktop window is not available on Windows.
The window embeds JetBrainsMono Nerd Font in Medium, Medium Italic,
Bold, and Bold Italic. Set editor.font_size in Space o o (8–48 logical
pixels, default 15); the saved size is read when each window opens, including
reattachment to an existing persistent session. Reopen the window after saving
the setting. Ctrl-plus (also Ctrl-equals) and Ctrl-minus adjust the current
window by one pixel without writing the configuration. Text, pointer targeting,
panes and terminal dimensions scale together. No system font installation is required.
Ctrl-Shift-c copies the editor selection, terminal review selection, or selected
media to the system clipboard. Ctrl-Shift-v pastes clipboard text as literal input
into Insert/Replace mode, a prompt, or an integrated terminal, like a terminal
emulator’s paste shortcut. Normal mode retains ordinary modal paste commands
(Space c p or Ctrl-v). Ctrl-c remains terminal child input. Native-feature
builds use an in-process clipboard owner for Space c y, Ctrl-v and the other
system clipboard commands; external clipboard helpers are not required.
Window-local font and literal-paste shortcuts are reserved frontend controls,
listed in contextual help; they do not participate in editor key remapping.
On macOS, Cmd-c also copies, and Cmd-v also pastes literal
clipboard text. Ctrl-Shift-c/v remain available. The Command modifier is
displayed as Cmd in macOS help and key hints. Configuration accepts both
Cmd-c and Super-c for the same key (and likewise for other Command keys),
on every platform. Other Command shortcuts are left unchanged.
Search within PDF page contents is not implemented.
Image zoom and scanned PDF content remain limited by their
source resolution. PDF text and vector graphics are rendered at the view
resolution within the visible-region budget described above. PDF rendering uses
a bundled Rust helper, with separately installed Poppler as fallback. Source changes
are checked when another frame is presented; there is no automatic media reload
watcher. macOS, Wayland, IME composition, and touchpad pinch gestures still need hands-on
platform verification. Ctrl-wheel zoom is supported; native pinch gestures are
not exposed by this GPUI release.