revenant-menus-audit(7)
REVENANT-MENUS-AUDIT(7)Compatibility ledgersREVENANT-MENUS-AUDIT(7)

Name

revenant-menus-audit – every xterm menu entry and its status in Revenant

Popup-menu feasibility study

Every entry from xterm patch-411's mainMenu (Ctrl-Button1), vtMenu (Ctrl-Button2) and fontMenu (Ctrl-Button3): what xterm does behind it, how much of that lives in libghostty-vt, and how approachable it is for Revenant. Reviewed against the then-selected libghostty headers on 2026-08-25.

Status key: DONE implemented; PARTIAL usable subset with documented gaps; READY can be wired now with no new subsystem; ROADMAP waits on a planned roadmap slice; BLOCKED needs a libghostty change; SKIP recommend not planning (record in the xterm differences ledger).

The tables are maintained per entry; grouped entries do not imply a current aggregate count.

The big pattern

About a third of the VT and main menus are DEC private modes. libghostty exposes all of them through ghostty_terminal_set(GHOSTTY_TERMINAL_OPT_MODE) and ghostty_terminal_get(GHOSTTY_TERMINAL_DATA_MODE), and the key encoder re-reads them via ghostty_key_encoder_setopt_from_terminal. The generic XtpTerminalSetMode/XtpTerminalGetMode pair in src/terminal.h now backs autowrap, reversewrap, autolinefeed, appcursor, appkeypad, backarrow key, num-lock and alt-esc, with checkmark state read back from DATA_MODE. Meta-esc still needs a distinct X Meta/Alt policy and allow132 needs grid-size polling after terminal input. Application cursor blinking, its presentation timer, the four-value cursorBlink resource policy, and cursorBlinkXOR are implemented; the menu toggle still needs defined transitions between configured and forced policy.

Item What xterm does libghostty involvement Approachability Status
toolbar Xaw toolbar (OPT_TOOLBAR, off in most builds) None Not worth reproducing SKIP
fullscreen Toggle _NET_WM_STATE_FULLSCREEN None One EWMH client message READY
securekbd XGrabKeyboard+XGrabServer, reverse-video flash None Pure Xlib, low value READY
allowsends Accept send_event X events None Check xany.send_event in handlers READY
redraw Full repaint — — DONE
logging Tee PTY output to logFile, honour logInhibit None (before vt_write) One coherent PTY tee with -/+l and -lf; tracked as TODO P1 ROADMAP
print-immediate Dump screen text (+SGR) to printerCommand Screen read: ghostty_row_get/cell_get or select_all+selection_format_alloc Needs a "walk screen as styled text" helper ROADMAP
print-on-error Same, from the X I/O error handler Same Same walker ROADMAP
print Buffered screen dump Same Same walker ROADMAP
print-redir Printer controller mode (CSI 5 i/4 i) Ghostty has no media copy; OPT_UNKNOWN_SEQUENCE is APC-only Needs MC callback or CSI passthrough BLOCKED
dump-html Screen with colours as HTML Screen read + DATA_COLOR_PALETTE Reuse render walker ROADMAP
dump-svg Same as SVG Same Same ROADMAP
8-bit control S8C1T single-byte C1 output No encoder/response option Ask for DRIFT entry instead BLOCKED
backarrow key DECBKM GHOSTTY_MODE_BACKARROW_KEY_MODE (?67) Mode flip DONE
num-lock Ignore keypad app mode with NumLock GHOSTTY_MODE_NUMLOCK_KEYPAD (?1035) Mode flip DONE
alt-esc altSendsEscape GHOSTTY_MODE_ALT_SENDS_ESC (?1039) Mode flip DONE
meta-esc metaSendsEscape GHOSTTY_MODE_ALT_ESC_PREFIX (?1036); Ghostty has one "alt" Mode flip + decide X Meta/Alt mapping (DRIFT note) READY
delete-is-del Delete sends 0x7F None Special-case XTP_KEY_DELETE before encoder READY
oldFunctionKeys Legacy F-key table Encoder has one table Post-mapping table; low value SKIP
tcapFunctionKeys Keys from terminfo None Needs terminfo layer SKIP
hpFunctionKeys HP table None Static table SKIP
scoFunctionKeys SCO table None Static table SKIP
sunFunctionKeys Sun table None Static table SKIP
sunKeyboard VT220 keypad mapping None Same family SKIP
suspend/continue/interrupt/hangup/terminate/kill kill(-pgrp, SIG*) None Six one-liners in pty.c READY
quit Exit — — DONE

vtMenu

Item What xterm does libghostty involvement Approachability Status
scrollbar Show/hide Xaw scrollbar DATA_SCROLLBAR, scroll_viewport (already wrapped) Xaw widget, layout, thumb and navigation DONE
jumpscroll Batch lines per repaint None Render-scheduling knob; subtle drift READY
reversevideo Swap fg/bg — — DONE
autowrap DECAWM GHOSTTY_MODE_WRAPAROUND (?7) Mode flip DONE
reversewrap Reverse wrap GHOSTTY_MODE_REVERSE_WRAP (?45) Mode flip DONE
autolinefeed LNM GHOSTTY_MODE_LINEFEED (20) Mode flip DONE
appcursor DECCKM GHOSTTY_MODE_DECCKM (?1) Mode flip DONE
appkeypad DECKPAM GHOSTTY_MODE_KEYPAD_KEYS (?66) Mode flip DONE
scrollkey Keypress snaps to bottom scroll_viewport Resource, CLI, and menu policy DONE
scrollttyoutput Output snaps to bottom Same Resource, CLI, and menu policy DONE
allow132 Allow DECCOLM resize GHOSTTY_MODE_ENABLE_MODE_3 (?40); no mode-change callback, poll DATA_COLS after feed Mode flip + small poll READY
keepSelection Keep highlight after loss None Roadmap #4 ROADMAP
keepClipboard Don't clear CLIPBOARD None Roadmap #4 ROADMAP
selectToClipboard Selection owns CLIPBOARD Xt named-selection ownership Resource, set-select, and menu policy DONE
visualbell Flash Bell callback exists Invert + timer READY
bellIsUrgent WM urgency hint Bell callback XUrgencyHint READY
poponbell Raise window Bell callback XRaiseWindow READY
cursorblink Blink cursor OPT_DEFAULT_CURSOR_BLINK, DATA_CURSOR_STYLE Toggle false/true as xterm does; RIS and DECSTR restore the startup four-value policy READY
titeInhibit Ignore alt-screen switches No way to disable a mode handler Needs "permanently reset mode" option BLOCKED
activeicon Terminal in icon window None Modern WMs ignore SKIP
copy_area Toggle xterm's XCopyArea scroll optimization None Revenant does not use xterm's scroll-copy path; see the drift ledger SKIP
softreset DECSTR Pinned Ghostty does not handle CSI ! p Needs DECSTR support or a soft-reset API BLOCKED
hardreset RIS, keep saved lines ghostty_terminal_reset() clears scrollback Needs a reset-preserving-history API or a complete local RIS implementation BLOCKED
clearsavedlines Reset + drop scrollback ghostty_terminal_reset() performs RIS and clears scrollback Add the action and Meta+Button-2 binding; test reset state and DATA_SCROLLBACK_ROWS against xterm READY
tekshow/tekmode/vthide Tek 4014 window None, ever See Tek section SKIP
altscreen Show alternate screen DATA_ACTIVE_SCREEN; OPT_MODE ?1047 should switch — verify the set path runs the full handler Probably one call ROADMAP
sixelScrolling DECSDM No sixel in Ghostty Blocked upstream BLOCKED
privateColorRegisters Sixel colour registers Sixel-only Blocked BLOCKED

fontMenu

Item What xterm does libghostty involvement Approachability Status
fontdefault, font1–font7 Font slot — — DONE
fontescape Font from OSC 50 OSC 50 ignored, not forwarded Needs unknown-OSC passthrough BLOCKED
fontsel Font from PRIMARY None Small after Roadmap #4 ROADMAP
allow-bold-fonts Real bold faces None; bold flag in XtpRenderCell Renderer toggle READY
font-linedrawing Internal box glyphs None Procedural Glyphs label; toggles forceBoxChars for every supported procedural range DONE
font-packed Min glyph width for bitmap fonts None Cell-metric choice ROADMAP
font-doublesize DECDHL/DECDWL Not in Ghostty Blocked upstream BLOCKED
font-loadable DECDLD soft fonts Not in Ghostty Blocked, unused BLOCKED
render-font Xft vs bitmap — — DONE
utf8-mode UTF-8 vs Latin-1 Ghostty is UTF-8 only iconv possible; recommend permanently on (DRIFT) BLOCKED
utf8-fonts utf8Fonts slot set None Only meaningful with utf8-mode ROADMAP
utf8-title UTF-8 _NET_WM_NAME Title callback and pop path utf8Title, set-utf8-title(); EWMH labels written or deleted; entry state follows the locale as in xterm DONE
allow-color-ops Gate dynamic-color OSC 10–19 and 110–119 Selector observer enforces the live backend permission Sets, queries, resets, deny-list exceptions and palette queries gated; remaining differences in drift ledger PARTIAL
allow-font-ops Gate OSC 50 No public OSC 50 callback Policy/resources and menu identity prepared; entry stays insensitive until fontescape BLOCKED
allow-mouse-ops Gate mouse and focus reports Encoder master gate Live toggle; requested modes preserved; named deny-list exceptions pending PARTIAL
allow-tcap-ops Gate XTGETTCAP Complete generated replies gated at PTY effect Live toggle and GetTcap deny-list exceptions; TN integration and XTSETTCAP pending PARTIAL
allow-title-ops Gate displayed title changes and applying saved labels Title callback and pop path Live toggle; OSC 1/icon changes still lack a backend callback; reports use Window Ops PARTIAL
allow-window-ops Toggle window-operation permissions OSC 52 callbacks and title observer Live selection and title stack/report policy; full Window Ops still pending PARTIAL

Tektronix 4014

In xterm the Tek items drive a second top-level widget (TekWidget, Tekproc.c ≈ 2,100 lines plus TekPrsTbl.c state tables). Nothing about it is a mode of the VT100 engine:

  • Separate parser. In Tek mode the PTY byte stream bypasses the VT parser. Switching is by CSI ? 38 h (DECTEK), ESC ^X, ESC ETX, or the menu. libghostty would treat ?38 as unknown and keep consuming bytes as text.
  • Vector renderer: four text sizes, vector/point/incremental plot modes, 1024×780 virtual coordinates, persistent display list for redraw.
  • GIN mode: crosshair cursor; a keypress sends key plus encoded coordinates.
  • Copy: writes the display list as raw Tek escapes to COPY files.

Revenant would have to intercept bytes before XtpTerminalFeed, own a Tek state machine and display list, and add a widget with its own tekMenu. libghostty contributes nothing. xterm's own --disable-tek4014 builds leave the three items insensitive, which is what Revenant does today. Recommendation: record "Tek 4014 not planned" in the xterm differences ledger.

Suggested order

  1. Slice A: the generic mode helper and eight mode-backed items are complete. Continue with signals ×6; allowsends; visualbell/bellIsUrgent/ poponbell; delete-is-del; and logging. (utf8-title is done.)
  2. Slice B, ride the roadmap: scrollbar family with #2; selection policies and fontsel with #4; named Mouse Ops exceptions; allow-bold-fonts and font-packed with #5.
  3. Slice C, screen-dump family: one styled-text walker unlocks print, print-immediate, print-on-error, dump-html, dump-svg.
  4. Upstream asks, by value: unknown OSC/CSI passthrough (fontescape, print-redir, full XTWINOPS); permanently-reset mode (titeInhibit); effective mouse tracking and OSC 50 hooks. Not worth asking: DECDHL, sixel, DECDLD, S8C1T.
  5. Drift-ledger entries: Tek 4014, toolbar, activeicon, copy_area, legacy keyboard tables/sunKeyboard, UTF-8-only, 8-bit controls, soft fonts.
RevenantSeptember 23, 2026REVENANT-MENUS-AUDIT(7)