Commit Graph
267 Commits
Author SHA1 Message Date
Alex Southwell 1a08258e3d Merge pull request #49 from saphid/theatre-media-device-fixes
Media player: keep playing through headset standby (real-Frame test fixes)
2026-09-29 12:40:35 +10:00
Alex Southwell a84d6b912b Merge pull request #44 from saphid/apk-store-fixes
Android game store: every source in one search, and proper Steam library entries
2026-09-29 12:39:16 +10:00
saphidandClaude Opus 5.5 448720d8d6 Tests: skip the SIGINT launcher case on bash 3.2 (macOS's), which doesn't run the trap during wait
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 12:35:23 +10:00
saphidandClaude Opus 5.5 1cd56740a6 Media player: keep retrying the theatre surround after a still is shown
Review (GPT-6 Astra, P2): the still-image loop stopped calling show() once
the screen took its first frame, so a surround refused during standby was
never retried and stayed missing for PNG and splat playback until restart.
hold() now keeps draining pending uploads after the screen is shown, until
both are up.

Also: stills and the surround wait out standby without counting as dropped
video frames or tripping the five-minute limit (video only); teardown
errors no longer overwrite a finished status; Stop is ignored once the
outcome is decided.

Tests: PNG and splat where the screen is accepted before the surround
recovers (fail on the old loop); fake-clock coverage of the five-minute
limit and its reset; status keeps filename/metadata layout sources and
explicit layouts stay explicit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 12:32:12 +10:00
Alex Southwell 31de17aab8 Merge pull request #48 from saphid/frame-mcp-verified
Record real-Frame MCP end-to-end results
2026-09-29 12:27:26 +10:00
saphidandGPT-6 Astra 5aea46afd0 Merge latest origin/main VR utilities into apk-store-fixes
Preserve the complete store, artwork, telemetry, input, media and agent route table alongside the newly landed VR utilities and performance HUD.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
2026-09-29 12:09:04 +10:00
saphidandGPT-6 Astra 8fca0fe0a2 Merge origin/main into apk-store-fixes, preserving store and headset features
Keep the union of server routes, desktop resources and responsive controls. Preserve OpenXR install defaults and telemetry hooks alongside library artwork. Adapt the resource test to single-file entries and avoid a completed-refresh race in the F-Droid test.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
2026-09-29 12:07:09 +10:00
Alex Southwell 6d3cde64fe Merge pull request #43 from saphid/vr-utilities
feat: add OpenVR performance HUD and optional VR utilities
2026-09-29 12:05:38 +10:00
saphidandClaude Opus 5.5 3f280ba59a Merge main into vr-utilities: the performance HUD alongside comfort, keyboard, panels and media
Also from review: a SteamVR build without the timing exports can't break status
(AttributeError), and the device test class runs when the file is run directly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:59:15 +10:00
Alex Southwell 83fa5c6c5b Merge pull request #41 from saphid/panel-workspaces
Add panel switchers and document workspace feasibility
2026-09-29 11:56:15 +10:00
saphidandClaude Opus 5.5 094c12c6d8 Keep media playing through headset standby
Real-Frame testing (2026-09-29) found an unworn headset enters standby
within seconds; SetOverlayRaw then returns RequestFailed (23) and the
movie died. The player now drops frames during standby, keeps audio
and pacing, re-sends stills and the theatre surround after waking, and
only errors after five minutes without an accepted frame.

A Stop arriving while the player is already shutting down is ignored,
so a finished video stays 'ended' instead of 'error: Stopped'. The
status now reports the layout's real source (filename/metadata).

Docs record the end-to-end device matrix (API, web UI, CLI).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:54:05 +10:00
saphidandClaude Opus 5.5 3ef7312654 Merge main into panel-workspaces (testing notes)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:50:17 +10:00
Alex Southwell 70e7f7f5e5 Merge pull request #39 from saphid/family-comfort
Family and comfort: safe timers, casting, alerts and breaks
2026-09-29 11:38:47 +10:00
saphidandClaude Opus 5.5 2bd86207c7 Merge main into panel-workspaces: the panel switcher alongside media, analytics and the Mac view
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:37:18 +10:00
saphidandClaude Opus 5.5 be1ab129c9 Tests: read the page as UTF-8 (Windows' default codec can't read its arrows)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:33:34 +10:00
saphid a38d0cda6e Document shared Frame test procedure and blocked recheck 2026-09-29 11:16:29 +10:00
saphidandClaude Opus 5.5 c46bf68dd0 Record real-Frame MCP end-to-end results, including approved mutations
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:15:07 +10:00
Alex SouthwellandClaude Opus 5.5 e702adbd77 Live view: a Desktop view that stays still, and Control to tap on the Frame (#46)
* Live view: a Desktop view that stays still, and Control to tap on the Frame

The live view gets a second source and a way to use the Frame from it:

- Desktop: the app panel in use in the headset, streamed from its own window
  (x11grab of gamescope's redirected window), so it doesn't move as the
  wearer looks around. A picker shows any other panel, view only.
- Control: on the Desktop view a tap or click lands exactly where you put it;
  drag is a mouse drag, press and hold right-clicks, two fingers scroll, and
  on a computer the mouse, wheel and keyboard work directly. On the headset
  view the view is a trackpad. A text field and key row type from a phone.

Input goes through gamescope's own EIS socket (the way Steam feeds Remote
Play input) with the libei already on the image: ui/frame_touch.py, over
the same long-lived ssh machinery as the keyboard agent, nothing to
install. It reaches the panel that has focus on either X display, which
the KDE Connect route can't. Verified on the Frame and from the iPhone app
in the Simulator.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Control: fixes from review

- Keys held on the Frame are released with buttons when Control stops or
  the view loses focus; keys for the Frame no longer trigger Frame Control's
  own shortcuts.
- Taps only act when the picture on screen is the panel in use; positions,
  presses, keys, text and scrolls name their panel (display and window: ids
  repeat across :0 and :1, told apart by pid), and the Frame drops them if
  focus has moved on. Releases always go.
- While connecting, a tap keeps its position; on an error only releases wait
  and retries back off; trimming a long queue never drops a release.
- Lifting one of two scrolling fingers ends the scroll; a cancelled touch
  isn't a tap; clicks and holds on the bars around the picture do nothing.
- A capture loop from before a Live restart can't stop the new video.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Control: close the targeting gaps from the second review

- The focused panel's display comes from GAMESCOPE_FOCUS_DISPLAY (gamescope
  packs ":1" into the first value), so a window id repeated across :0 and :1
  can't be mistaken; the pid is only the fallback.
- Presses, keys, text and scrolls read focus afresh on the Frame; only moves
  use a reading up to a second old.
- A gesture remembers the panel it started on and does nothing more if that
  stops being the one in use; a press with no panel to aim at isn't sent.
- Opening a screenshot clears the panel Control would act on; switching to
  another app releases held keys and buttons.
- Trimming keeps a click with its position; the error backoff holds for new
  input too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Control: fixes from the SWE-2 Max review

- The Frame side tracks keys as well as buttons and lets go of both when the
  session ends.
- A stale tap tells the page, which re-reads the panels at once.
- A paused input device waits instead of ending the session; only a
  disconnect does. An OS error on one event skips it.
- Presses check focus with two property reads and do the full lookup only
  when it changed.
- Writes to an agent's stdin are serialized, so two devices sending at once
  can't tear a line (the keyboard agent too).
- Connecting gives up with a message after 15 s instead of hanging on
  "Connecting…"; text goes in 100-character pieces so releases don't wait
  behind a long paste; a cancelled mouse gesture releases what's held.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Control: stale clears, pauses reconverge, pastes split per request

- The Frame says it has caught up as soon as an aimed event lands after a
  stale one, so the page stops re-reading the panels.
- After a device pause it lets go of everything it holds (releases that
  arrived while paused were dropped), and waits for the device once per
  batch, not once per event.
- The quick focus check no longer freshens the panel geometry's age.
- Each request carries at most about 100 characters of text.
- Turning Control off while it connects doesn't report an error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* frame_touch: build the socket path on the Frame, so Windows can import it for tests

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* frame_touch: any event that goes through clears the stale flag

A trackpad move names no panel, so waiting for an aimed event could leave
the page re-reading panels for the rest of the session; a release still
aimed at the old panel doesn't count.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:13:21 +10:00
saphidandClaude Opus 5.5 ab1985b6b3 Comfort: a state missing 'started' can't crash status (timestamps of 0 still count)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:12:41 +10:00
saphidandClaude Opus 5.5 1203ec0a9e Merge main into family-comfort; a session state without 'started' can't crash status
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:09:35 +10:00
Alex Southwell ef56025ad1 Merge pull request #19 from saphid/frame-input
Keyboard and trackpad for the Frame, through its own KDE Connect
2026-09-29 10:33:35 +10:00
Alex Southwell 697452e5a9 Merge pull request #42 from saphid/theatre-media
Add owned Frame-side theatre and stereo media previews
2026-09-29 10:27:40 +10:00
saphidandClaude Opus 5.5 4bb7a1ee86 Merge main into frame-input: keyboard and trackpad alongside analytics, the Mac view and MCP
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 10:25:26 +10:00
saphid ae7f733b90 Merge remote-tracking branch 'origin/main' into theatre-media
# Conflicts:
#	ui/server.py
2026-09-29 10:21:27 +10:00
saphidandClaude Opus 5.5 b00db2484d Keep the backslash upload-name test POSIX-only
Windows treats the backslash as a separator, so that name can't occur there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 10:15:37 +10:00
Alex Southwell 363497fdd5 Merge pull request #20 from saphid/vr-apks
Run Quest and other VR APKs on the Frame: VR detection, launcher fix, OpenXR 1.1 compatibility layer
2026-09-29 10:13:11 +10:00
Alex Southwell ff52f50c0c Merge pull request #22 from saphid/mac-in-headset
Mac in the headset: Mac windows as panels, measured and adapting to the network
2026-09-29 10:12:46 +10:00
saphid b0d6039eec Merge remote-tracking branch 'origin/main' into theatre-media
# Conflicts:
#	docs/testing.md
#	ui/server.py
2026-09-29 10:08:45 +10:00
saphidandClaude Opus 5.5 48158d1fe9 Merge main into mac-in-headset (README index)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 10:05:27 +10:00
saphidandClaude Opus 5.5 86b8ab1d82 Assert the start-failure test reaches systemd-run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 10:01:17 +10:00
saphidandClaude Opus 5.5 e288946b81 Merge main into vr-apks: VR installs report through install_hooks like every other install
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:58:55 +10:00
Alex Southwell 66b6d46e0e Merge pull request #37 from saphid/flat2vr-mods
docs: record VR mod feasibility and own-manager requirements
2026-09-29 09:57:59 +10:00
saphidandClaude Opus 5.5 d970107716 Merge main into mac-in-headset: the Mac view alongside analytics and Report a problem
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:57:35 +10:00
Alex Southwell 6fbc450eea Merge pull request #17 from saphid/analytics-and-updates
Analytics, self-update and Report a problem
2026-09-29 09:55:12 +10:00
saphidandClaude Opus 5.5 f7573e3565 Merge main into mac-in-headset (MCP agent routes alongside the Mac view); skip the bash syntax test on Windows
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:41:24 +10:00
Alex Southwell 4f6d40625a Merge pull request #36 from saphid/linux-vr-streaming
docs: Linux VR feasibility and first-party streaming options
2026-09-29 09:39:01 +10:00
saphid c6ed6c9ea1 Merge remote-tracking branch 'origin/main' into analytics-and-updates
# Conflicts:
#	docs/frame-control.md
#	ui/server.py
2026-09-29 09:38:44 +10:00
saphidandClaude Opus 5.5 020e3386e1 Make media stop race-free and cover start failures
Stop always calls systemctl and treats exit 5 (unit already collected)
as done, so there is no is-active/stop race. Cleanup never masks the
copy error, the play ssh timeout covers the remote worst case, and
tests cover stop exit codes and systemd-run stderr reporting.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:30:03 +10:00
Alex Southwell 6d03317970 Merge pull request #15 from saphid/docs-announcements
Docs: house style for announcing features and fixes
2026-09-29 09:26:22 +10:00
saphidandClaude Opus 5.5 f81f70ed5d Fix media stop, upload cleanup and review findings
- Stop is a no-op when the collected player unit is already gone
  (raw systemctl stop exits 5 on the Frame; verified 2026-09-29).
- Surface systemd-run stderr when the player can't start.
- Keep the copy error if the cleanup ssh also fails; reject upload
  names that the play path can never accept.
- Allow 60 s for play (ffprobe 30 s + systemd-run 15 s remote).
- Docs: four-hour cap is unconditional; no delete action yet; fix a
  garbled timing sentence.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:22:22 +10:00
Alex Southwell 976008065f Merge pull request #16 from saphid/keep-awake
Keep the Frame awake during agent work
2026-09-29 09:16:03 +10:00
Alex Southwell 8b5ada1272 Merge pull request #35 from saphid/frame-mcp
Add Frame Control MCP tools and an opt-in assistant panel
2026-09-29 09:04:49 +10:00
saphidandClaude Opus 5.5 48a9914124 Skip reverse-DNS lookup when binding the loopback server
HTTPServer.server_bind calls socket.getfqdn, which stalled past the MCP
backend's 10-second startup window on GitHub's macOS runners.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 08:54:17 +10:00
saphid 222d5eccc9 fix(comfort): harden timer recovery and notification UX after review 2026-09-29 08:31:00 +10:00
saphid 002c859572 Set up self-contained MCP startup and inspect Frame computer-use capabilities 2026-09-29 08:18:47 +10:00
saphidandClaude Opus 5.5 2c8e2fb2a8 SteamGridDB: request PNG only for logos and icons
The live API rejects mimes=image/jpeg on /logos and /icons, so every logo and
icon lookup fell back to generated art. Found with a real key: SuperTux now
gets grid, wide, hero and logo; Beat Saber all five.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 08:08:08 +10:00
saphidandClaude Opus 5.5 d18f1655be e2e: the app icon lives under artwork/ now
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 00:08:44 +10:00
saphidandClaude Opus 5.5 f81c98a87b Fix CI: title removal order, Windows fixtures and POSIX-only tests
- Title removal ran the Steam shortcut tidy-up before steamos-delete, which
  finds the Proton prefix through that shortcut, so compatdata was left behind
  (e2e caught it). steamos-delete runs first again; art/collection tidy-up after.
- Test fixtures are byte-exact: never convert line endings (a text-looking
  fixture APK got CRLF on Windows and failed its SHA-256).
- Read index.html/artwork-settings.js as UTF-8 in tests; app-data backup and
  OBB shell tests run only on POSIX (they exercise the Frame-side scripts).
- e2e expects the icon under artwork/ now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 23:59:44 +10:00
saphidandClaude Opus 5.5 cb05395280 Artwork fetch: release the DNS slot if its thread can't start; stricter GIF control blocks
Final review follow-up. A failed Thread.start() leaked a resolver slot (four
failures disabled artwork lookups). GIF graphic-control blocks must have the
fixed 4-byte payload (otherwise dropped) and an image with no pixel data is
rejected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 23:48:20 +10:00
saphidandClaude Opus 5.5 3b36feff52 Keep worker notes and proof logs out of the repository
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 23:38:54 +10:00