Commit Graph
38 Commits
Author SHA1 Message Date
Robin Anderson c40dba8de4 Show only the knock kinds left on in the tour's knock steps
The double and triple knock steps cycled through all three kinds, so a
card listing only together and table knocks still showed a headset
knock. With every kind off, the steps still show all three.
2026-10-16 13:08:37 -04:00
Robin Anderson a63205e140 Say where a triple knock goes while passthrough is off
A triple knock while passthrough is off switches the style, and
passthrough opens in it next time. The README table and the tour's
triple knock step now say so. The tour title names the style, not Room
View, so one card never calls passthrough by two names.
2026-10-16 13:00:34 -04:00
Robin Anderson 3d6c7d6409 Leave the passthrough tile without a hint 2026-10-16 11:17:44 -04:00
Robin Anderson 9e206f30a0 Drop the knock hints from the passthrough tile and the Style label 2026-10-16 10:50:09 -04:00
Robin Anderson cb0d853544 Show update progress, a Restart step, and the result after restart
Installing an update fills the Install button with a progress bar,
driven by the ZIP's size against its Content-Length. When the install
finishes, a blue Restart button starts the new version. After the
restart, a card names the new and old versions. A failed install or a
missed restart shows a card with the reason.

A pending update marks the Settings button and the Settings header with
Steam's alert yellow (#FFC82C) and its exclamation mark, taken from the
SettingsAlert icon in Steam's UI on the Frame. The automatic check runs
daily instead of weekly, and retries after an hour when it fails.
2026-10-15 23:43:22 -04:00
Robin Anderson 76ce58c7ee Raise the phone button contrast to 4.7:1 and use one corner radius
The off-white button text measured 4.24:1 on the old blue, under WCAG
AA for 20 px semibold text. The report box on the phone page and the QR
code's white box use the 16 px radius the rest of the UI uses.
2026-10-15 22:30:29 -04:00
Robin Anderson ba54052c60 Bundle the report and knock recording into one ZIP for the phone
With a recording, the phone page leads with Download the report file,
which gives knockthru-report.zip holding the report and the recording,
then Open GitHub, then one step to attach the file. A separate
recording link was easy to miss. Without a recording, the page keeps
the copy and paste flow.
2026-10-15 22:19:35 -04:00
Robin Anderson b3f8928155 Record knocks for a bug report
Record knocks on the report card records 20 s of headset and controller
motion in the tests/data CSV format, gzips it to
~/knockthru-knocks.csv.gz, and adds the knocks and actions heard to the
report. The phone page then offers the recording as a download to
attach to the issue.

detector_test FILE replays any recording and prints every knock and
action, for triaging a report.
2026-10-15 22:10:19 -04:00
Robin Anderson e870557c1a Log SteamVR version changes and check for updates once a week
state.json remembers the SteamVR version, the date KnockThru first saw
it, and the version before. Each change goes in the log, and the report
shows the history, so a report after a Steam update names the cause.

A minute after start, KnockThru asks GitHub for the latest release if
the last automatic check was a week ago or more. A newer release puts a
dot on the Settings button and Install in the Settings header. Failures
only go in the log. check_updates: false in config.json turns it off.
2026-10-15 22:07:20 -04:00
Robin Anderson 3151ef4eef Reword the report card and phone page
The card's title is Report a problem, and its three steps match the
phone page's button. Save to headset is the way to get the full report
into an issue without a phone, and its note sits beside it. The phone
page drops the link that opened GitHub without the report.
2026-10-15 21:58:32 -04:00
Robin Anderson 609ebbf730 Fix report and update copy, and give the phone page a light theme
The phone page follows the phone's light or dark setting. Its button
blue is darker than the panel accent, so white text reaches WCAG AA, and
it has press and focus states. The README describes the phone page, and
the Settings header says Check failed or Install failed instead of
Update failed.
2026-10-15 21:53:57 -04:00
Robin Anderson 20b7cc75c5 Hand the full report to a phone through a page the headset serves
The report card's QR code now opens a page on the Frame, over the local
Wi-Fi, with the whole report. One button copies it and opens the
prefilled GitHub form, where it goes in the Report box. The page also
offers the report as a download. It needs a random token in the path and
stops when the card closes or after 15 minutes. SteamOS's firewall opens
TCP 1024 to 65535, and the kernel picks the port from that range.

Without a network, the QR code opens the GitHub form directly, as before.
2026-10-15 21:50:04 -04:00
Robin Anderson 4a84f1fdd3 Walk through sending a report in three steps, with an optional file
The report card numbers the steps: open the phone camera, scan the code
through a lens, then sign in and press Create. Save report file is a
separate button that keeps the full report on the headset and says it
sends nothing. The issue link also carries the last error KnockThru
showed, in a new last-error field on the bug form.
2026-10-15 21:44:22 -04:00
Robin Anderson d421116efe Show a QR code that opens a GitHub issue from the report card
Report in Settings opens a card with a QR code. A phone held up to a lens
scans it and opens the bug form in .github/ISSUE_TEMPLATE/bug.yml, with
the KnockThru version, SteamVR version, and passthrough status filled in.
The full report still goes to ~/knockthru-report.txt.

Vendors nayuki/QR-Code-generator (MIT) to encode the code.
2026-10-15 21:38:42 -04:00
Robin Anderson 59b5b21d63 Put the version and update button at the top right of Settings
Settings rows are 92 px so a sixth row fits: Something wrong?, with a
Report button. The update button reads Check for updates, Checking,
Install X.Y.Z, Installing, or Try again.
2026-10-15 21:30:56 -04:00
Robin Anderson c8887532ad Confirm before skipping the tour and fix tour copy
Skip opens a confirm card that says the tour can be replayed from
Settings. The knock steps list only the knock kinds that are on, and
pick-your-knocks says why Next is off when every kind is off. Errors
show in the strip under the buttons, where no step draws. The knock
steps ignore pause and per-game blocks only while the panel shows them.
2026-10-15 20:54:23 -04:00
Robin Anderson 7df3a7edf5 Add a first-run tour, tour replay, and factory reset
The tour shows the first time someone opens the KnockThru tab. It walks
through picking knock kinds, calibrating each kind that is on, and a
live double and triple knock that really switch passthrough and style.
Next stays off until a step is complete. Skip ends the tour from any step.
Anyone with an existing config.json or calibration.json skips it.

Settings now holds Calibrate, which moves off the main screen, plus a
Sounds switch, Replay for the tour, and Factory reset. Reset deletes
config.json and calibration.json, keeps application.log, and starts
the tour again.
2026-10-15 20:49:50 -04:00
Robin Anderson 97b52de12c Click on every panel button, with a stream opened ahead of time
Back, Settings, Calibrate, Done, and the knock kind cards now click too.

Opening an audio stream takes about 250 ms on the Frame, so pw-play clicked
late. A background thread now plays the click through libpulse-simple, loaded
at run time. Like Steam's own UI, it opens the stream when needed and closes it
after 10 s without a click. The panel opening and the first knock of a sequence
open it early, so the click lands about 300 ms sooner.
2026-10-15 20:03:43 -04:00
Robin Anderson 8353df585b Call every knock a knock
The panel said "tap" for headset knocks and the docs said "hits" in
places. Everything now says knock, including the headset spike
threshold, renamed from tap_peak to headset_knock_peak.
2026-10-15 19:25:32 -04:00
Robin Anderson bb2f4f5db8 Log one summary per recording and close usability gaps
Recording logs one line with how each knock ended (counted, too soon,
too light, other kind, ignored) instead of a line per knock, and the
panel no longer logs frame timings. Canceling a recording logs the same
summary.

The learn step names the ring it asks people to wait for. The Saved
banner says when the calibrated kind or KnockThru itself is turned off,
since knocks would do nothing until it is back on. The calibration plan
records the current decisions.
2026-10-15 19:16:46 -04:00
Robin Anderson 55eef3c62d Count a calibration knock only once the pacing ring fills
The ring started when a knock was confirmed, about 0.3 s after it, and
filled over 1 s, while counting only needed 0.6 s of quiet. So a knock
could count with the ring partway full. The ring now runs from the knock
itself, and a knock before it fills, or during Get ready, shows "Too
soon. Wait for the ring." The surface knock animation turns the
controller to 135 degrees, so it lies flatter with the handle to the
right.
2026-10-15 19:08:06 -04:00
Robin Anderson 9934462345 Lengthen the get-ready time to 3 s and drop the pick subtitle
The pick cards move up into the space the subtitle left.
2026-10-15 18:57:30 -04:00
Robin Anderson 8dd6bd3927 Drop the sensitivity step and go straight to trying the knocks
The slider earned little in testing. Its middle and most sensitive ends
gave nearly the same replay results, and its least sensitive end only
lost real knocks. The walkthrough is now four steps: pick, learn,
record, and try. Recording goes straight to the try step, with the
approach threshold fixed at 55 percent of the second slowest knock,
and a miss offers Record again.
2026-10-15 18:54:26 -04:00
Robin Anderson f2fcce5893 Ignore knocks right after Start and let Less drop weak knocks
On the Frame, the hand coming down from pressing Start counted as a
knock 1 s in. Recording now opens with a 1.5 s Get ready ring, and
knocks during it do not count.

The sensitivity range sat below every recorded knock, so moving the
line changed nothing on the chart. The least sensitive end is now the
speed a quarter of the way up from the slowest recorded knock, so
dragging toward Less greys out the weakest ones. Middle and More are
unchanged. Replays at Less keep 14 to 17 of the real doubles, with no
false or wrong actions.
2026-10-15 18:47:28 -04:00
Robin Anderson 55a927bf51 Make the sensitivity step foolproof and polish the calibration screens
The sensitivity chart is logarithmic from a quarter to two and a half
times the second slowest knock, so the scale is the same height for
everyone. Bars stay under the heading. Knocks too light to count at any
sensitivity are turned away while recording with a hint, so every bar
on the chart can count.

The pick cards fill the panel, recording bars are blue like counted
knocks on the chart, the chart heading says All when every knock
counts, and the try step goes Back by name.
2026-10-15 18:40:52 -04:00
Robin Anderson 8b70acea03 Calibrate an approach-speed threshold and drag it on the knock chart
Each calibrated kind now saves a spike threshold and an approach
threshold, with the slider position and the recorded knocks. A sequence
needs its fastest knock to reach the approach threshold. Slow knocks
still join their sequence, so clapping runs stay rejected. Together and
headset knocks get separate spike thresholds. Older calibration files
load with their shared threshold as before.

The sensitivity step charts approach speeds, and the threshold line is
the control: a press anywhere on the chart drags it, and it clicks into
Less, Middle, and More notches. A new test calibrates each kind on its
recording and replays every recording at each notch, with no false
actions and no wrong actions in mixed.
2026-10-15 18:27:48 -04:00
Robin Anderson 1d5fca9dae Label the threshold and the sensitivity slider, and buzz on notches
The line on the knock chart says Threshold, the slider says Sensitivity,
and the screen is titled Your knocks. Releasing the slider into a notch
gives one buzz.
2026-10-15 16:43:03 -04:00
Robin Anderson 0291d2e566 Show knock strength as approach speed and smooth the animations
The spike size divides by pose update gaps that vary from 2 to 7 ms. In
the knock recordings, the top tenth of spikes ran 2.8 to 8.3 times the
bottom tenth. The controller's fastest speed in the 100 ms before the
knock ran 1.7 to 2.5 times, so the recording bars use it now.

The panel paints its background once and copies it, which halves the
frame time, and draws 30 times a second while something moves.
2026-10-15 16:22:13 -04:00
Robin Anderson 26dc163158 Count only deliberate knocks while calibrating
Calibration lowers the thresholds, so waving the controllers or getting
ready to knock counted about one knock a second in the play and noise
recordings. A calibration knock now needs 0.6 s without another knock
before it, and a nearly still controller before its swing. That leaves
2 knocks in the 90 s of play and noise, and every knock recording still
gives 10 of 10. Knocks of another kind only show the hint when they are
deliberate too.
2026-10-15 16:15:15 -04:00
Robin Anderson fae831244d Show a double knock on the calibration kind cards
Knocks act in pairs outside calibration, so a single knock on the cards
read as the gesture itself.
2026-10-15 15:28:13 -04:00
Robin Anderson 1e7669c2d3 Walk calibration through five animated steps
Pick a kind, learn the knock, record single knocks, adjust sensitivity
on a notched slider, and try a double knock before saving. The knock
animations port the README timing and draw controllers and the headset
traced from the CAD sprites. The slider's middle notch keeps the old
60 percent rule. The tuning comes in a later change.
2026-10-15 15:16:56 -04:00
Robin Anderson 4049f0cabe Add a classic bar icon setting and clearer panel states
The knocks switch is now a KnockThru On/Off card with a larger switch,
tinted with the accent while on, so it no longer looks like the
per-knock switches below it.

A Settings screen holds a "Classic bar icon" switch, saved as
classic_bar_icon. Off, the bar icon is white with half-transparent
accent parts, and Steam's tint turns it grey, and white on hover. On,
it is the same mark in the logo colors, without the tint.

Calibration hints say to knock 10 times, at least 1 second apart, and
to knock as softly as KnockThru should catch. A finished calibration
shows a Saved banner with a Done button.
2026-10-15 14:53:51 -04:00
Robin Anderson 707a3b6628 Widen the gaps in the dashboard bar icon
At the bar's 38 px, one logo unit is about one pixel, so the gaps between
the heads, between head and grip, and around the sticks blurred shut. The
bar icon uses its own shapes with those gaps widened. The face buttons keep
their size.
2026-10-15 14:32:52 -04:00
Robin Anderson 9113421865 Keep the logo colors in the dashboard bar icon
The bar icon draws in white and blue. A layer cut to its shape multiplies
it by the bar button's text color, so it dims when idle and lightens on
hover and focus, like Steam's own icons. If the debug port is closed, the
icon shows at full color.
2026-10-15 14:27:07 -04:00
Robin Anderson 552ae873be Draw the dashboard bar icon in the bar's idle grey
Steam's own bar icons use rgb(139, 146, 154), read from the bar's CEF page.
The library tile and the panel header keep the white and blue.
2026-10-15 14:03:39 -04:00
Robin Anderson 6fc03ad3fa Draw the dashboard bar icon as the bare mark at full size
The dashboard bar shows the thumbnail small, and the dark tile shrank the
mark to about three quarters of it. The bar icon now drops the tile and
fills the canvas. The SteamVR library tile and the panel header keep it.
2026-10-15 14:00:40 -04:00
Robin Anderson d71ac38114 Draw the logo as the SteamVR app icon and panel icon
Panel::draw_icon now draws the two-controller logo from polygon data in
src/logo_shapes.hpp, on an opaque kBackground tile. The data comes from the
same traced controller layers as images/logo.svg. Canvas::polygon fills rings
with the even-odd rule, sampling four lines per pixel row with exact
horizontal coverage, so the icon stays sharp at 56 px and 256 px.
2026-10-15 13:21:52 -04:00
Robin Anderson d6bd54ef77 Add a KnockThru tab to the SteamVR dashboard
The tab has a passthrough button, a translucent or opaque switch,
switches to pause knocks, pick knock kinds, and turn knocks off in the
running game, and a calibration screen with step-by-step progress.

The panel draws into an RGBA image with stb_truetype and Noto Sans, and
shows it through two Vulkan textures that take turns. SetOverlayRaw made
the panel flash on every update. Calibration moved into a Calibrator
class shared by the panel and --calibrate. Panel changes write to the
user config.json. SteamVR also gets an app icon.
2026-10-15 13:18:08 -04:00