Skip to content

TV UI foundation: introduce a real ten-foot responsive layout system, not 960x540 stretching #156

Description

@EriArk

Parent: #153. Coordinate with #78 device/output profiles, #111 primary navigation and existing Theme/QML shell.

Current implementation and problem

src/qml/Main.qml builds a single centered viewport at Theme.viewportWidth=960, Theme.viewportHeight=540 and applies scale: Math.min(window.width/width, window.height/height). Theme.qml and many pages use fixed logical geometry/font sizes. This makes a TV look like a scaled-up handheld chassis, not a purpose-built couch UI.

Product goal

Deliver two coordinated presentation profiles over one shared feature/service/navigation backend:

  • Handheld — current compact TrainerOS/physical-device aesthetic and reliable 960×540 controller navigation.
  • TV / ten-foot — a composition designed for living-room viewing on 1080p/4K televisions, with larger readable content, fewer cramped regions, clear focus and couch-friendly navigation.

Do not fork Social, library, emulators or controller semantics into 'TV TrainerOS'. Use shared data/controllers and responsive components/layout presenters.

Layout architecture

  • Add explicit app-level presentationProfile/viewingContext rather than using raw screen pixel size as a synonym for viewing distance.
  • Support Auto / Handheld / TV preference: auto may use external-display/device-profile signals, but user override is authoritative (large desktop monitors are not automatically televisions).
  • Replace one globally scaled 960×540 geometry with profile-aware layout tokens: effective usable surface, safe area, content density, gutters, typography, media size, focus style, row/card sizing, max readable line lengths, modal/dialog layout.
  • A 4K TV should show a carefully composed amount of content at comfortably readable physical size, not tiny 4× more controls or the same handheld screen blown up 4×.
  • Avoid hard-coded pixel coordinates in feature UI where composition genuinely differs; keep existing Theme colors, branding and visual identity.
  • TV is landscape-first. Handle 1920×1080 and 3840×2160 correctly, relevant overscan/letterbox/safe-area behavior, and at least a sensible 16:10/ultrawide desktop fallback without broken navigation.
  • Don't force an enormous ornamental handheld chassis/frame into the TV canvas. The content and navigational hierarchy should be primary, with restrained TrainerOS motifs.

Mode changes

Switching TV ↔ handheld when safe should preserve page, current selection, conversation, draft, party/call and game context. Prevent focus from falling onto stale/unmounted controls during layout swap.

During an active emulator, changing display/profile must preserve the owned game session; don't relaunch or break save/streaming/call lifecycle to redraw shell chrome.

Performance

Stay within existing Qt Quick/Gamescope constraints: prevent redundant expensive art decode, excessive Canvas redraw or scaling blur at 4K; use appropriate image resolution and sane animation/reduced-motion policy.

Acceptance

  • At 1080p and 4K, TV mode renders a genuine redesigned hierarchy, not simply 960x540 × scale.
  • Handheld 960×540 composition and performance do not regress.
  • TV can be selected even when resolution does not meet a specific threshold; desktop/handheld can be forced on a high-resolution display.
  • TV mode uses true safe-area and legible typography/focus from sofa distance.
  • Dynamic resizing/external display switching restores focus and does not lose Trainer-owned app state.
  • Shared services/controllers remain single implementations.
  • Automated screenshots and an actual TV/controller check document the difference.

TV implementation tasks

Shared controllers/data remain authoritative: #111 navigation, #113 reviews, #127–#135 Social/Together, #144–#152 OddCrate. Screen size or device name must not fork these backends.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions