diff --git a/docs/ui-patches.md b/docs/ui-patches.md index f4c1e9f..9100121 100644 --- a/docs/ui-patches.md +++ b/docs/ui-patches.md @@ -125,8 +125,8 @@ Every signature must match exactly once, otherwise the patch changes nothing and reports it: `resolvePatch` returns e.g. `signature not found, Steam left unpatched: layouts.currentLayout (module 40222): ambiguous export, candidates r_, xy` as the patch's result. Results are cached per page. The -library also has `ensureStyle(doc, id, css)` and `logger(buffer)` (a capped -debug log). +library also has `ensureStyle(doc, id, css)`, `logger(buffer)` (a capped +debug log) and `keyboardPopup()` (Steam's VR keyboard popup or `null`). Signatures live in `modules/steam-ui-patches/lib/signatures.json`, shared by patches and the offline checker. An entry can also list `expects` (strings the patch relies diff --git a/modules/steam-ui-patches/lib/finders.js b/modules/steam-ui-patches/lib/finders.js index 088ccd1..f52ae38 100644 --- a/modules/steam-ui-patches/lib/finders.js +++ b/modules/steam-ui-patches/lib/finders.js @@ -3,7 +3,8 @@ // ids or minified names (which change with every Steam update). Like Decky // Loader's @decky/ui finders and Vencord's `find`. // -// Also small helpers every patch needs (resolvePatch, ensureStyle, logger). +// Also small helpers every patch needs (resolvePatch, ensureStyle, logger, +// keyboardPopup). // // A single expression: installs window.__sfuiFind (unless an equal or newer // VERSION is there) and evaluates to it; mkPatch passes it as `find`. @@ -41,7 +42,7 @@ // Every lookup must match exactly once; otherwise a FinderError names the // signature, the part that failed and the candidates. (() => { - const VERSION = 2; + const VERSION = 3; const G = globalThis; const have = G.__sfuiFind; if (have && have.version >= VERSION) return have; @@ -280,6 +281,10 @@ if (s.textContent !== css) s.textContent = css; return s; } + // Steam's VR keyboard popup (the g_PopupManager popup with [data-key] + // elements), or null. + const keyboardPopup = () => + [...(G.g_PopupManager?.GetPopups?.() || [])].find((p) => p.window?.document.querySelector('[data-key]')) ?? null; // log(msg, data?) appending { t, msg, data } to buf, keeping the last max. const logger = (buf, max = 200) => (msg, data) => { buf.push({ t: new Date().toISOString().slice(11, 23), msg, ...(data !== undefined ? { data } : {}) }); @@ -290,7 +295,7 @@ version: VERSION, FinderError, fnSource, matchText, matchValue, kindOf, getWebpackRequire, findAllModules, findModule, findAllExports, findExport, resolve, resolveAll, fiberOf, propsOf, findFiberUp, findFiberDown, findInReactTree, cache, requires, - resolvePatch, ensureStyle, logger, + resolvePatch, ensureStyle, logger, keyboardPopup, }; G.__sfuiFind = lib; return lib; diff --git a/modules/vr-keyboard-extra-keys/patch.js b/modules/vr-keyboard-extra-keys/patch.js index 1398a5c..b5197e3 100644 --- a/modules/vr-keyboard-extra-keys/patch.js +++ b/modules/vr-keyboard-extra-keys/patch.js @@ -23,7 +23,7 @@ // mkPatch patch (see steam-ui-patches/lib/default.nix); no options. On a // signature mismatch it returns an error and changes nothing. Idempotent. ((find, sigs) => { - const VERSION = 23; + const VERSION = 24; const send = (msg) => window.__vrkbdKey && window.__vrkbdKey(msg); const mods = find.resolvePatch('webpackChunksteamui', sigs); if (typeof mods === 'string') return mods; @@ -185,8 +185,7 @@ }); // ---- keyboard component ------------------------------------------------------- - const kbPopup = [...(g_PopupManager.GetPopups?.() || [])] - .find((p) => p.window?.document.querySelector('[data-key]')); + const kbPopup = find.keyboardPopup(); if (!kbPopup) return 'no keyboard popup yet'; const doc = kbPopup.window.document; // The keyboard component: nearest fiber above a key whose instance has TypeKeyInternal. diff --git a/modules/vr-keyboard-touch/keyboard-patch.js b/modules/vr-keyboard-touch/keyboard-patch.js index 75d5db7..45ed9e9 100644 --- a/modules/vr-keyboard-touch/keyboard-patch.js +++ b/modules/vr-keyboard-touch/keyboard-patch.js @@ -17,7 +17,7 @@ // "cancel" (no pose), frames stopping for STALE_MS, the keyboard moving or // closing end a touch without typing. Debugging: __sfuiTouchTypeLog. ((find, sigs, opts, hooks, TR, HUB) => { - const VERSION = 3; + const VERSION = 4; const G = window; const STALE_MS = 1000; // Steam's UI thread can stall frames for ~0.3 s const SNAP = 3; // SteamVR overlay haptic effect (1 ButtonEnter, 3 Snap) @@ -43,10 +43,6 @@ typeof f.stateNode?.HandleTouchEnd === 'function' && f.stateNode.m_mapTouched instanceof Set, 200)?.stateNode; const touches = new Map(); // hand -> { t, inst, doc } - function keyboardWindow() { - const p = [...(G.g_PopupManager?.GetPopups?.() || [])].find((x) => x.window?.document.querySelector('[data-key]')); - return p?.window ?? null; - } // Steam's handlers read target, changedTouches, touches (tracker.js // touchEvent) and the touches' target / clientX / clientY. const others = (t, inst) => [...touches.values()].filter((e) => e.inst === inst && e.t !== t).map((e) => e.t); @@ -66,7 +62,7 @@ function down(hand, u, v) { end(hand, { cancel: true }); - const win = keyboardWindow(); + const win = find.keyboardPopup()?.window; if (!win) return; const doc = win.document, x = u * win.innerWidth, y = v * win.innerWidth; const el = doc.elementsFromPoint(x, y).find((e) => e.id !== 'MouseHoverBlockerHack'); diff --git a/modules/vr-keyboard/patch.js b/modules/vr-keyboard/patch.js index 058f753..0da39b8 100644 --- a/modules/vr-keyboard/patch.js +++ b/modules/vr-keyboard/patch.js @@ -36,7 +36,7 @@ // Steam's events. Debugging: __sfuiSwipeLog, __sfuiSwipePaths // (scripts/vr-keyboard-replay.mjs). ((find, sigs, opts, hooks, D, T, C, DICT, P, HUB, F) => { - const VERSION = 28; + const VERSION = 29; const G = window; const O = opts; @@ -67,7 +67,7 @@ return `Steam internals changed, keyboard left stock: ${e.message}`; } - const popup = [...(g_PopupManager.GetPopups?.() || [])].find((p) => p.window?.document.querySelector('[data-key]')); + const popup = find.keyboardPopup(); if (!popup) return 'no keyboard popup yet'; const doc = popup.window.document; const stamp = `${VERSION}:${P.VERSION}:${HUB?.version} ${JSON.stringify(O)}`; // new code or options: re-attach