mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 04:04:16 +02:00
With both lasers on the keyboard SteamVR forwards per poll only one laser's movement, so the pressing one may get no touchmoves and its swipe became a tap. keyboard.vr.swipe.twoHanded (default on; turns on the controller bridge): a press is attributed to the hand whose laser hit is nearest to it (within 30 px, the trigger as a tiebreak; without recent frames the first frame after the press decides, within 60 px). The path comes from runs of one source: the touch's own moves while they flow, that hand's laser hit per bridge frame once they pause for 60 ms, touchmoves again if frames pause. A touchend disagreeing with the laser during a bridge run ends at the laser. Touchmoves on the other hand's laser move the attribution. Without fresh frames: touch events only, as before. A second press during a swipe stays Steam's tap (one text field, one word at a time). The bridge sends full rate only on demand now: hub.js demand(ms) goes back through the relay (CDP binding __sfuiCtlIn) to systemui's __sfuiCtl.demand; the swipe patch asks from the press to the release. Tests: gesture-input with the two-controller recording and synthetic bridge frames (a pressing hand without touchmoves, attribution with both lasers on the keyboard, a stale bridge, frames stopping mid-swipe, re-attribution, interleaved hover and presses); hub demand.
34 lines
1.8 KiB
Nix
34 lines
1.8 KiB
Nix
# Tests of the VR keyboard (flake check `vr-keyboard`, also built before the
|
|
# patch by vr-keyboard.nix with the configured dictionary): text model,
|
|
# gesture input (two controllers, the controller bridge's path), corrector
|
|
# and swipe-decoder accuracy
|
|
# (tests/*.test.mjs). The accuracy
|
|
# thresholds (German keyboard geometry, German and English words) fail the
|
|
# build only for German + English dictionaries, the default here.
|
|
{ pkgs
|
|
, dictionary ? {
|
|
languages = map (l: l // { keepFrequentAbove = 4.0; }) [
|
|
{ language = "de"; hunspell = "de_DE"; words = 60000; frequencyOffset = 0.0; }
|
|
{ language = "en"; hunspell = "en_US"; words = 40000; frequencyOffset = -0.3; }
|
|
];
|
|
contractions = true; extraWords = [ ]; extraWordsFrequency = 5.0; extraWordFiles = [ ]; excludeWords = [ ];
|
|
}
|
|
}:
|
|
let
|
|
inherit (pkgs) lib;
|
|
words = import ./dictionary.nix { inherit pkgs dictionary; };
|
|
strict = lib.sort lib.lessThan (map (l: l.language) dictionary.languages) == [ "de" "en" ];
|
|
in
|
|
pkgs.runCommand "vr-keyboard-checks" { nativeBuildInputs = [ pkgs.nodejs ]; } ''
|
|
set -o pipefail
|
|
node ${./tests/textmodel.test.mjs} ${./textmodel.js}
|
|
node ${./tests/gesture-input.test.mjs} ${./gesture-input.js} ${./tests/two-controllers.json}
|
|
node ${./tests/corrector.test.mjs} ${./corrector.js} ${./swipe-decoder.js} ${words} ${lib.optionalString (!strict) "|| echo warning: corrector test failed"}
|
|
node ${./tests/swipe-decoder.test.mjs} ${./swipe-decoder.js} ${words} 100 1 | tee $out ${lib.optionalString (!strict) "|| true"}
|
|
node -e '
|
|
const bad = require("fs").readFileSync(process.argv[1], "utf8").split("\n")
|
|
.filter((l) => /sigma 0.25/.test(l) && +l.match(/top-3 ([\d.]+)%/)[1] < 85);
|
|
if (bad.length) { console.error("decoder below 85 % top-3:", bad); process.exit(process.argv[2] === "strict" ? 1 : 0); }' \
|
|
$out ${if strict then "strict" else "warn"}
|
|
''
|