Skip to content

feat(tui): per-VM display preference (auto/window/vnc) - #25

Merged
NovusEdge merged 2 commits into
mainfrom
tui-display-config
Aug 9, 2026
Merged

feat(tui): per-VM display preference (auto/window/vnc)#25
NovusEdge merged 2 commits into
mainfrom
tui-display-config

Conversation

@NovusEdge

Copy link
Copy Markdown
Owner

Lets an installed desktop VM opt into a real qemu window. Today only the uninstalled-disk installer console gets a window; a provisioned XFCE VM renders to the VNC socket and shows nothing on the host until you attach a viewer by hand.

Schema. A display field in vm.toml: auto (default), window, vnc. config.VM.Display empty reads as auto, so older vm.toml files are unaffected. validateDisplay gates both create and update; a bad value fails loudly.

Rule. qemu.DisplayKind gains the preference as its first argument:

if !graphical { return DisplayVNC }   // host veto, unconditional
switch pref {
case window: return window
case vnc:    return vnc
default:     installer-console default (uninstalled disk → window)
}

graphical (the host session check, plus STOAT_GRAPHICAL) stays the veto, so a window preference degrades to VNC on a headless host instead of crashing qemu's -display gtk. Threaded through NeedsWindow, core.DisplayKind/DisplayFor, qemu.Args, and the JSON DTO.

Surfaces. A three-way selector in the create and edit forms (mirrors the existing mode radio row). A d key on the detail screen cycles auto → window → vnc, saves, and notes "display: (applies at next start)" — with "restart to apply" when the VM is running, since -display is a launch argument.

Tests: DisplayKind table across pref × mode × installed × graphical; config Save/Load round-trip; invalid-value rejection; form and detail behavior. just check and just test pass.

Add config.VM.Display: "", "auto", "window", or "vnc". Empty means
auto, so existing vm.toml files keep their current behavior.

qemu.DisplayKind takes the preference as its first argument. It stays
a host veto: a "window" preference still falls back to VNC on a host
with no graphical session, since qemu exits 1 on -display gtk there.
core.validateDisplay is the one place that checks the value, called
from Create/Plan and Update.
Add a display row (auto/window/vnc) to the create form and the edit
form, next to the mode and console-password rows they already show as
a radio group.

Add a "d" key on the detail screen: it cycles auto -> window -> vnc ->
auto, saves through core.Update, and toasts the new value with a note
that it applies at next start. A running VM's toast also says to
restart, matching the wording edit.go already uses for a deferred
field.
@NovusEdge NovusEdge added the enhancement New feature label Aug 9, 2026
@NovusEdge NovusEdge self-assigned this Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@NovusEdge, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 25 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8f6ef6b1-99c8-4b62-ba3c-5d97d26e9e3c

📥 Commits

Reviewing files that changed from the base of the PR and between a63448f and 5a4fcfa.

📒 Files selected for processing (19)
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/core/core.go
  • internal/core/core_test.go
  • internal/core/display.go
  • internal/core/display_test.go
  • internal/core/update.go
  • internal/core/update_test.go
  • internal/core/vm.go
  • internal/qemu/args.go
  • internal/qemu/display_test.go
  • internal/tui/detail.go
  • internal/tui/detail_test.go
  • internal/tui/edit.go
  • internal/tui/edit_test.go
  • internal/tui/form.go
  • internal/tui/form_test.go
  • internal/tui/keymap.go
  • internal/tui/labels.go

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NovusEdge
NovusEdge merged commit ed1a0e2 into main Aug 9, 2026
8 checks passed
@NovusEdge
NovusEdge deleted the tui-display-config branch August 9, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant