diff --git a/README.md b/README.md index ee8b05d..684796e 100644 --- a/README.md +++ b/README.md @@ -241,7 +241,7 @@ which: [Repository layout](docs/development.md). | `steamFrame.keyboard.vr.extraKeys.enable` | bool | `false` | VR keyboard with Esc/Ctrl/Alt, arrows, real chords, AltGr/non-ASCII. | | `steamFrame.keyboard.vr.enable` | bool | `false` | Swipe typing, suggestions and Backspace drag on the VR keyboard; the sub-features below are on by default, see [VR keyboard](docs/keyboard.md#swipe-and-suggestions). | | `steamFrame.keyboard.vr.swipe.enable` | bool | `true` | Swipe typing. | -| `steamFrame.keyboard.vr.swipe.twoHanded` | bool | `true` | Swipes also with both lasers on the keyboard: the path from the pressing controller's pose (the controller bridge, sampling during a press while the keyboard is shown). | +| `steamFrame.keyboard.vr.swipe.twoHanded` | bool | `true` | Swipes also with both lasers on the keyboard: the path from the pressing controller's pose, see [VR keyboard](docs/keyboard.md#swipe-and-suggestions). | | `steamFrame.keyboard.vr.dictionary.languages` | list of submodules | layout language + English | `{ language; hunspell; words; frequencyOffset; keepFrequentAbove; }`: wordfreq language, `pkgs.hunspellDicts` name (or `null`), most frequent words taken, zipf offset, keep words Hunspell rejects from this zipf on (default `4.0`). Default: the `keyboard.layout` language (de, fr, es, it, nl, pt, sv; 60000) + English (40000, `-0.3`), else English (60000). | | `steamFrame.keyboard.vr.dictionary.contractions` | bool | `true` | Words with apostrophes (`couldn't`, `geht's`), swiped by their letters. | | `steamFrame.keyboard.vr.dictionary.extraWords` | list of str | `[ ]` | Words always included, casing as given. | diff --git a/docs/keyboard.md b/docs/keyboard.md index 80210ac..ce84360 100644 --- a/docs/keyboard.md +++ b/docs/keyboard.md @@ -2,7 +2,8 @@ Three patches of Steam's VR keyboard: [extra keys](#extra-keys), [swipe and suggestions](#swipe-and-suggestions) and -[touch typing](#touch-typing). They work together or alone. Options: [README, Options](../README.md#options) (`keyboard.vr.*`). +[touch typing](#touch-typing). They work together or alone. Options: +[README, Options](../README.md#options) (`keyboard.vr.*`). The keyboard layout of the Steam session itself is a separate fix ([keyboard layout](session.md#keyboard-layout)). @@ -184,10 +185,8 @@ has the letters. 30 px; the trigger as a tiebreak), and while its laser events pause (60 ms) the path comes from that laser's hit per frame. The bridge samples at full rate from the press to the release (asked for by the - patch) and costs nothing while the keyboard is hidden. Without fresh - frames (option off, relay or SteamVR gone) only laser events count, as - before. A second press during a swipe is Steam's (a tap): one text - field, one word at a time. + patch). Without fresh frames (option off, relay or SteamVR gone) only + laser events count, as before. - F-keys: `function-keys.js` decides what the strip shows; the suggestion state is kept as it is while F1–F12 are shown. AltGr changes reach the strip through a `componentDidUpdate` on the keyboard instance (with a @@ -231,8 +230,8 @@ the trigger. - A haptic tick on contact (`haptics`), routed by SteamVR like the keyboard's other ticks. -**Caveats:** moving the keyboard pauses touches for 0.3 s. The extra keys' Delete repeat and the swipe patch's gestures react -to the laser only. Depends on Steam and SteamVR UI internals (see +**Caveats:** moving the keyboard pauses touches for 0.3 s. The extra keys' +Delete repeat and the swipe patch's gestures react to the laser only. Depends on Steam and SteamVR UI internals (see [after a Steam update](ui-patches.md#after-a-steam-update)). **Remove when** Steam's VR keyboard gets touch input. diff --git a/modules/vr-keyboard-controllers/hub.js b/modules/vr-keyboard-controllers/hub.js index 43d162c..f007c80 100644 --- a/modules/vr-keyboard-controllers/hub.js +++ b/modules/vr-keyboard-controllers/hub.js @@ -3,17 +3,16 @@ // extraArgs (like lib/hooks.js): installs window.__sfuiControllers unless an // equal or newer VERSION is there (a newer one takes over the subscribers) // and evaluates to it. relay.mjs calls frame(f) with bridge-patch.js's -// frames and lost() when the SteamVR side goes away. +// frames (cadence there) and lost() when the SteamVR side goes away. // subscribe(fn) -> unsubscribe fn(frame) per frame, fn(null) when lost // last the last frame (null: none / lost) // demand(ms) full rate for the next ms (0: end), e.g. // during a laser press; via the relay's // CDP binding __sfuiCtlIn +// errors { count, last } of throwing subscribers // Each frame's hand points (tip, ray) get the keyboard page's px: x, y // (CSS px of the keyboard popup) and onKeyboard (inside the page), if the -// keyboard popup exists. Frames come at up to ~90 Hz while a hand's tip is -// within 10 cm of the keyboard or its trigger is pulled, else every 1 s, and -// only while SteamVR shows the keyboard (then one with keyboard null). +// keyboard popup exists. (() => { const VERSION = 2; const G = globalThis; diff --git a/modules/vr-keyboard-controllers/relay.mjs b/modules/vr-keyboard-controllers/relay.mjs index b8b6e55..af6aebe 100644 --- a/modules/vr-keyboard-controllers/relay.mjs +++ b/modules/vr-keyboard-controllers/relay.mjs @@ -56,7 +56,7 @@ async function connect(side) { const closed = new Promise((res) => { ws.onclose = res; }); // No Runtime.enable: bindings work without it, and it would stream the // page's console and context events here. - if (cfg.binding) send('Runtime.addBinding', { name: cfg.binding }); + send('Runtime.addBinding', { name: cfg.binding }); live[side] = (expression) => send('Runtime.evaluate', { expression }); console.log(`${side}: connected`); await closed; diff --git a/modules/vr-keyboard/gesture-input.js b/modules/vr-keyboard/gesture-input.js index 8741aa0..58eaa3c 100644 --- a/modules/vr-keyboard/gesture-input.js +++ b/modules/vr-keyboard/gesture-input.js @@ -30,7 +30,7 @@ // attribution. No fresh frames at the press: touch events only, as without // the bridge. (() => { - const VERSION = 2; + const VERSION = 3; const STALE = 150, GAP = 60, TOL = 30, AGREE = 40, FAR = 60, WAIT = 250, LATE = 60; function create({ now = () => performance.now() } = {}) { @@ -89,7 +89,6 @@ VERSION, get owner() { return owner; }, get hand() { return hand; }, - get mode() { return mode; }, stats, // { phase, id, x, y, target } if the event concerns the gesture (or may // start one: phase 'down'), else null. An 'up' or 'cancel' ends the @@ -148,7 +147,6 @@ if (!hand) { waitUntil = touchAt + WAIT; refs = [[c.x, c.y]]; } return hand; }, - release() { reset(); }, // A bridge frame (null: bridge lost). Returns [x, y] to add to the path, or null. frame(f) { const t = now(); diff --git a/modules/vr-keyboard/patch.js b/modules/vr-keyboard/patch.js index b6041a5..1ecd058 100644 --- a/modules/vr-keyboard/patch.js +++ b/modules/vr-keyboard/patch.js @@ -10,9 +10,10 @@ // started on at release. With both lasers on the keyboard the pressing one // may get no touchmoves; its path then comes from the controller bridge // (gesture-input.js: the hand whose laser hit the press point; full rate -// asked for from the press to the release). Once a press leaves its first key we drop that -// key from Steam's pending touches (m_mapTouched) and cancel its long press -// (Steam's own touch-end cleanup, minus the typing), then decode the path. +// asked for from the press to the release). Once a press leaves its first +// key we drop that key from Steam's pending touches (m_mapTouched) and +// cancel its long press (Steam's own touch-end cleanup, minus the typing), +// then decode the path. // - Output: one character or "Backspace" per HandleVirtualKeyDown, the path // of Steam's own keys (incl. extraKeys' xdotool fallback for non-ASCII, // which is async: we pause after such characters).