mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 03:00:13 +02:00
lib: shared resolvePatch, ensureStyle, logger; legacy wrapper code removed
- finders.js (VERSION 2): resolvePatch (resolveAll or the "signature not found, ... left unpatched" status), ensureStyle and logger, used by the patches instead of their own copies. - hooks.js (VERSION 2) no longer unwinds per-patch wrappers of old patch versions; dashboard-windows and steam-close-button drop their handling of versions <= 2 / <= 6 (in-page only, gone with any SteamVR restart). - VERSIONs: dashboard-windows 4, steam-close-button 9, window-curvature 21, frame-controls 7, steam-keyboard-patch 22, launcher-menu grid 7, pinned-desktop 4, show-all 2.
This commit is contained in:
1 parent
36886d61df
commit
a5ecbad76d
11 files changed
+68
-108
No files matched your search
@@ -23,13 +23,11 @@
|
|||||||
// scheduler) applies new limits at once.
|
// scheduler) applies new limits at once.
|
||||||
//
|
//
|
||||||
// State: window.__sfuiDashboardWindows (proto, resend, options id, counters in
|
// State: window.__sfuiDashboardWindows (proto, resend, options id, counters in
|
||||||
// .hits); hook name NAME. (VERSION 2 wrapped SendMessage itself and read
|
// .hits); hook name NAME. Signature mismatch -> error, nothing changed. Same
|
||||||
// state.rewrite, no longer set, so a leftover wrapper is inert; hooks.js
|
|
||||||
// unwinds one on top.) Signature mismatch -> error, nothing changed. Same
|
|
||||||
// VERSION and options -> "unchanged", else the rewrite is replaced in place.
|
// VERSION and options -> "unchanged", else the rewrite is replaced in place.
|
||||||
((find, sigs, opts, hooks) => {
|
((find, sigs, opts, hooks) => {
|
||||||
const NAME = 'dashboard-windows';
|
const NAME = 'dashboard-windows';
|
||||||
const VERSION = 3;
|
const VERSION = 4;
|
||||||
const GRAB = {
|
const GRAB = {
|
||||||
world: { type: 'grab-scale', min: 0.25, max: 5 },
|
world: { type: 'grab-scale', min: 0.25, max: 5 },
|
||||||
theater: { type: 'grab-transform', min: 1, max: 6 },
|
theater: { type: 'grab-transform', min: 1, max: 6 },
|
||||||
@@ -49,12 +47,8 @@
|
|||||||
|
|
||||||
let st = window.__sfuiDashboardWindows;
|
let st = window.__sfuiDashboardWindows;
|
||||||
if (!st?.proto) {
|
if (!st?.proto) {
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunkvrwebui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunkvrwebui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, dashboard left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
// Mailbox: SendMessage(target, msg) -> WebSocketSend("mailbox_send ...").
|
// Mailbox: SendMessage(target, msg) -> WebSocketSend("mailbox_send ...").
|
||||||
// resend: debounced "send the scene graph again" (0 args, NextSGID(), setTimeout).
|
// resend: debounced "send the scene graph again" (0 args, NextSGID(), setTimeout).
|
||||||
st = window.__sfuiDashboardWindows = {
|
st = window.__sfuiDashboardWindows = {
|
||||||
@@ -62,7 +56,6 @@
|
|||||||
id: null, hits: {},
|
id: null, hits: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
delete st.rewrite; // VERSION 2's wrapper reads it: keep that inert
|
|
||||||
|
|
||||||
const active = maxScale !== null || rules.length > 0;
|
const active = maxScale !== null || rules.length > 0;
|
||||||
if (st.version === VERSION && st.id === id && active === hooks.has(st.proto, 'SendMessage', NAME)) return 'unchanged';
|
if (st.version === VERSION && st.id === id && active === hooks.has(st.proto, 'SendMessage', NAME)) return 'unchanged';
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
// Reverts dashboard-windows/patch.js: removes its SendMessage hook (and a
|
// Reverts dashboard-windows/patch.js: removes its SendMessage hook and
|
||||||
// VERSION 2 own wrapper if on top) and resends the scene graph so the stock
|
// resends the scene graph so the stock limits apply at once. Safe when not
|
||||||
// limits apply at once. Safe when not patched.
|
// patched.
|
||||||
(() => {
|
(() => {
|
||||||
const NAME = 'dashboard-windows';
|
|
||||||
const st = window.__sfuiDashboardWindows;
|
const st = window.__sfuiDashboardWindows;
|
||||||
if (!st) return 'not patched';
|
if (!st) return 'not patched';
|
||||||
delete window.__sfuiDashboardWindows;
|
delete window.__sfuiDashboardWindows;
|
||||||
window.__sfuiHooks?.remove(st.proto, 'SendMessage', NAME);
|
window.__sfuiHooks?.remove(st.proto, 'SendMessage', 'dashboard-windows');
|
||||||
const f = st.proto.SendMessage;
|
|
||||||
if (f?.__sfuiPatch === NAME) st.proto.SendMessage = f.__sfuiOrig;
|
|
||||||
try { st.resend?.(); } catch { /* ignore */ }
|
try { st.resend?.(); } catch { /* ignore */ }
|
||||||
return 'unpatched';
|
return 'unpatched';
|
||||||
})()
|
})()
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
// setPlacement(name or "icon:N", 'bar' | 'menu' | null), reset().
|
// setPlacement(name or "icon:N", 'bar' | 'menu' | null), reset().
|
||||||
((find, sigs, opts) => {
|
((find, sigs, opts) => {
|
||||||
const NAME = 'frame-controls';
|
const NAME = 'frame-controls';
|
||||||
const VERSION = 6;
|
const VERSION = 7;
|
||||||
const T_SPACER = 1, T_ACTION = 2;
|
const T_SPACER = 1, T_ACTION = 2;
|
||||||
// Action icon enums (sigs.controls anchors them): names for the options.
|
// Action icon enums (sigs.controls anchors them): names for the options.
|
||||||
const NAMES = { keyboard: 22, float: 26, dashboard: 27, theater: 28, dockLeft: 29, dockRight: 30, close: 31, curvature: 40 };
|
const NAMES = { keyboard: 22, float: 26, dashboard: 27, theater: 28, dockLeft: 29, dockRight: 30, close: 31, curvature: 40 };
|
||||||
@@ -96,12 +96,8 @@
|
|||||||
|
|
||||||
const FS = window.FrameStore;
|
const FS = window.FrameStore;
|
||||||
if (!FS) return 'not patched: window.FrameStore missing';
|
if (!FS) return 'not patched: window.FrameStore missing';
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunkvrwebui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunkvrwebui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, dashboard left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
const mx = mods.mobx.module;
|
const mx = mods.mobx.module;
|
||||||
const P = mods.frame.exports.Frame.prototype;
|
const P = mods.frame.exports.Frame.prototype;
|
||||||
const actions = mods.actions.exports.store;
|
const actions = mods.actions.exports.store;
|
||||||
@@ -122,10 +118,7 @@
|
|||||||
S = window.__sfuiFrameControlsState = { schema: 1, placement: ok ? { ...saved.placement } : {}, nixSeen: ok ? { ...saved.nixSeen } : {}, log: [] };
|
S = window.__sfuiFrameControlsState = { schema: 1, placement: ok ? { ...saved.placement } : {}, nixSeen: ok ? { ...saved.nixSeen } : {}, log: [] };
|
||||||
}
|
}
|
||||||
const logBuf = S.log ??= [];
|
const logBuf = S.log ??= [];
|
||||||
const log = (msg, data) => {
|
const log = find.logger(logBuf);
|
||||||
logBuf.push({ t: new Date().toISOString().slice(11, 23), msg, ...(data !== undefined ? { data } : {}) });
|
|
||||||
if (logBuf.length > 200) logBuf.splice(0, logBuf.length - 200);
|
|
||||||
};
|
|
||||||
if (restored) log('state restored', { from: restored, popup: S.placement });
|
if (restored) log('state restored', { from: restored, popup: S.placement });
|
||||||
let unsaved = true; // last save not sent (no injector binding): retried by check()
|
let unsaved = true; // last save not sent (no injector binding): retried by check()
|
||||||
const save = () => {
|
const save = () => {
|
||||||
@@ -342,12 +335,7 @@
|
|||||||
border: solid #fff; border-width: 0 3px 3px 0; transform: rotate(45deg); }
|
border: solid #fff; border-width: 0 3px 3px 0; transform: rotate(45deg); }
|
||||||
.sfui-fc-pressing { position: relative; }
|
.sfui-fc-pressing { position: relative; }
|
||||||
`;
|
`;
|
||||||
const ensureStyle = () => {
|
const ensureStyle = () => find.ensureStyle(document, STYLE_ID, CSS);
|
||||||
if (document.getElementById(STYLE_ID)) return;
|
|
||||||
const s = document.createElement('style');
|
|
||||||
s.id = STYLE_ID; s.textContent = CSS;
|
|
||||||
document.head.appendChild(s);
|
|
||||||
};
|
|
||||||
|
|
||||||
const PANEL_RE = /^legacy-frame-controls-(additional-options-)?(\d+)$/;
|
const PANEL_RE = /^legacy-frame-controls-(additional-options-)?(\d+)$/;
|
||||||
// The control under an event target: { frame, actionId, where, button, panel } or null.
|
// The control under an event target: { frame, actionId, where, button, panel } or null.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
// unpatch.js (or a new VERSION/options) calls __sfuiLauncherGrid.stop().
|
// unpatch.js (or a new VERSION/options) calls __sfuiLauncherGrid.stop().
|
||||||
((find, sigs, opts) => {
|
((find, sigs, opts) => {
|
||||||
const NAME = 'launcher-menu-grid';
|
const NAME = 'launcher-menu-grid';
|
||||||
const VERSION = 6;
|
const VERSION = 7;
|
||||||
const COLS = opts.columns;
|
const COLS = opts.columns;
|
||||||
const ROWS = opts.maxRows ?? null;
|
const ROWS = opts.maxRows ?? null;
|
||||||
if (!(Number.isInteger(COLS) && COLS >= 1) || !(ROWS === null || (Number.isInteger(ROWS) && ROWS >= 1)))
|
if (!(Number.isInteger(COLS) && COLS >= 1) || !(ROWS === null || (Number.isInteger(ROWS) && ROWS >= 1)))
|
||||||
@@ -258,13 +258,7 @@ ${PINNED} > [role=button] * { flex-grow: 0 !important; text-align: center !impor
|
|||||||
|
|
||||||
const attach = (d) => {
|
const attach = (d) => {
|
||||||
if (docs.has(d) || !d?.body) return;
|
if (docs.has(d) || !d?.body) return;
|
||||||
let s = d.getElementById(STYLE_ID);
|
find.ensureStyle(d, STYLE_ID, CSS);
|
||||||
if (!s) {
|
|
||||||
s = d.createElement('style');
|
|
||||||
s.id = STYLE_ID;
|
|
||||||
(d.head ?? d.documentElement).appendChild(s);
|
|
||||||
}
|
|
||||||
if (s.textContent !== CSS) s.textContent = CSS;
|
|
||||||
const obs = new MutationObserver(guard(() => update(d)));
|
const obs = new MutationObserver(guard(() => update(d)));
|
||||||
obs.observe(d.body, { childList: true, subtree: true, characterData: true });
|
obs.observe(d.body, { childList: true, subtree: true, characterData: true });
|
||||||
const ro = new d.defaultView.ResizeObserver(guard(() => regionsOf(d).forEach(layout)));
|
const ro = new d.defaultView.ResizeObserver(guard(() => regionsOf(d).forEach(layout)));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// unpatch.js (or a new VERSION/position) calls __sfuiPinnedDesktop.stop().
|
// unpatch.js (or a new VERSION/position) calls __sfuiPinnedDesktop.stop().
|
||||||
((find, sigs, opts) => {
|
((find, sigs, opts) => {
|
||||||
const NAME = 'launcher-menu-pinned-desktop';
|
const NAME = 'launcher-menu-pinned-desktop';
|
||||||
const VERSION = 3;
|
const VERSION = 4;
|
||||||
const POS = opts.position === 'top' ? 'top' : 'bottom';
|
const POS = opts.position === 'top' ? 'top' : 'bottom';
|
||||||
const KEY = 'steamos-nested-desktop';
|
const KEY = 'steamos-nested-desktop';
|
||||||
const HIDDEN = 'data-sfui-desktop-hidden';
|
const HIDDEN = 'data-sfui-desktop-hidden';
|
||||||
@@ -109,11 +109,7 @@
|
|||||||
|
|
||||||
const attach = (d) => {
|
const attach = (d) => {
|
||||||
if (docs.has(d) || !d?.body) return;
|
if (docs.has(d) || !d?.body) return;
|
||||||
if (!d.getElementById(STYLE_ID)) {
|
find.ensureStyle(d, STYLE_ID, CSS);
|
||||||
const s = d.createElement('style');
|
|
||||||
s.id = STYLE_ID; s.textContent = CSS;
|
|
||||||
(d.head ?? d.documentElement).appendChild(s);
|
|
||||||
}
|
|
||||||
const obs = new MutationObserver(guard(() => update(d)));
|
const obs = new MutationObserver(guard(() => update(d)));
|
||||||
obs.observe(d.body, { childList: true, subtree: true, characterData: true });
|
obs.observe(d.body, { childList: true, subtree: true, characterData: true });
|
||||||
docs.set(d, obs);
|
docs.set(d, obs);
|
||||||
|
|||||||
@@ -11,13 +11,9 @@
|
|||||||
// nothing while its contents (and the signature) stay intact and the setting
|
// nothing while its contents (and the signature) stay intact and the setting
|
||||||
// itself is untouched. Remembered as window.__sfuiShowAllApps for unpatch.js.
|
// itself is untouched. Remembered as window.__sfuiShowAllApps for unpatch.js.
|
||||||
((find, sigs) => {
|
((find, sigs) => {
|
||||||
const VERSION = 1;
|
const VERSION = 2;
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunksteamui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunksteamui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, Steam left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
const list = mods.devModeApps.exports.devModeOnly;
|
const list = mods.devModeApps.exports.devModeOnly;
|
||||||
if (!Array.isArray(list)) return 'Developer Mode app list is not an array, Steam left unpatched';
|
if (!Array.isArray(list)) return 'Developer Mode app list is not an array, Steam left unpatched';
|
||||||
const prev = window.__sfuiShowAllApps;
|
const prev = window.__sfuiShowAllApps;
|
||||||
|
|||||||
+29
-1
@@ -3,6 +3,8 @@
|
|||||||
// ids or minified names (which change with every Steam update). Like Decky
|
// ids or minified names (which change with every Steam update). Like Decky
|
||||||
// Loader's @decky/ui finders and Vencord's `find`.
|
// Loader's @decky/ui finders and Vencord's `find`.
|
||||||
//
|
//
|
||||||
|
// Also small helpers every patch needs (resolvePatch, ensureStyle, logger).
|
||||||
|
//
|
||||||
// A single expression: installs window.__sfuiFind (unless an equal or newer
|
// A single expression: installs window.__sfuiFind (unless an equal or newer
|
||||||
// VERSION is there) and evaluates to it; mkPatch passes it as `find`.
|
// VERSION is there) and evaluates to it; mkPatch passes it as `find`.
|
||||||
// scripts/check-signatures.mjs evaluates the same file in Node, so the
|
// scripts/check-signatures.mjs evaluates the same file in Node, so the
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
// Every lookup must match exactly once; otherwise a FinderError names the
|
// Every lookup must match exactly once; otherwise a FinderError names the
|
||||||
// signature, the part that failed and the candidates.
|
// signature, the part that failed and the candidates.
|
||||||
(() => {
|
(() => {
|
||||||
const VERSION = 1;
|
const VERSION = 2;
|
||||||
const G = globalThis;
|
const G = globalThis;
|
||||||
const have = G.__sfuiFind;
|
const have = G.__sfuiFind;
|
||||||
if (have && have.version >= VERSION) return have;
|
if (have && have.version >= VERSION) return have;
|
||||||
@@ -259,10 +261,36 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- patch helpers ------------------------------------------------------------
|
||||||
|
// resolveAll on the page's webpack chunk array, or the status string
|
||||||
|
// "signature not found, <Steam|dashboard> left unpatched: <why>".
|
||||||
|
function resolvePatch(chunkGlobal, sigs) {
|
||||||
|
try { return resolveAll(getWebpackRequire(chunkGlobal), sigs); } catch (e) {
|
||||||
|
return `signature not found, ${chunkGlobal === 'webpackChunkvrwebui' ? 'dashboard' : 'Steam'} left unpatched: ${e.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <style id> in doc's head with the given text (created or updated).
|
||||||
|
function ensureStyle(doc, id, css) {
|
||||||
|
let s = doc.getElementById(id);
|
||||||
|
if (!s) {
|
||||||
|
s = doc.createElement('style');
|
||||||
|
s.id = id;
|
||||||
|
(doc.head ?? doc.documentElement).appendChild(s);
|
||||||
|
}
|
||||||
|
if (s.textContent !== css) s.textContent = css;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
// 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 } : {}) });
|
||||||
|
if (buf.length > max) buf.splice(0, buf.length - max);
|
||||||
|
};
|
||||||
|
|
||||||
const lib = {
|
const lib = {
|
||||||
version: VERSION, FinderError, fnSource, matchText, matchValue, kindOf,
|
version: VERSION, FinderError, fnSource, matchText, matchValue, kindOf,
|
||||||
getWebpackRequire, findAllModules, findModule, findAllExports, findExport, resolve, resolveAll,
|
getWebpackRequire, findAllModules, findModule, findAllExports, findExport, resolve, resolveAll,
|
||||||
fiberOf, propsOf, findFiberUp, findFiberDown, findInReactTree, cache, requires,
|
fiberOf, propsOf, findFiberUp, findFiberDown, findInReactTree, cache, requires,
|
||||||
|
resolvePatch, ensureStyle, logger,
|
||||||
};
|
};
|
||||||
G.__sfuiFind = lib;
|
G.__sfuiFind = lib;
|
||||||
return lib;
|
return lib;
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
// has(obj, method, name) registered and wrapper installed.
|
// has(obj, method, name) registered and wrapper installed.
|
||||||
// The wrapper (fn.__sfuiHooks = method, original in fn.__sfuiOrig) looks hooks
|
// The wrapper (fn.__sfuiHooks = method, original in fn.__sfuiOrig) looks hooks
|
||||||
// up per call, in registration order, and runs them once per call even if it
|
// up per call, in registration order, and runs them once per call even if it
|
||||||
// is in the chain twice. Legacy per-patch wrappers (fn.__sfuiPatch === name)
|
// is in the chain twice.
|
||||||
// on top of obj[method] are unwound when `name` registers.
|
|
||||||
(() => {
|
(() => {
|
||||||
const VERSION = 1;
|
const VERSION = 2;
|
||||||
const G = globalThis;
|
const G = globalThis;
|
||||||
const have = G.__sfuiHooks;
|
const have = G.__sfuiHooks;
|
||||||
if (have && have.version >= VERSION) return have;
|
if (have && have.version >= VERSION) return have;
|
||||||
@@ -36,11 +35,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function install(obj, method) {
|
function install(obj, method) {
|
||||||
const names = hooksOf(obj, method);
|
|
||||||
// Unwind legacy per-patch wrappers of registered names from the top.
|
|
||||||
for (let f = obj[method], i = 0; typeof f === 'function' && typeof f.__sfuiPatch === 'string' &&
|
|
||||||
typeof f.__sfuiOrig === 'function' && names?.has(f.__sfuiPatch) && i < 50; f = obj[method], i++)
|
|
||||||
obj[method] = f.__sfuiOrig;
|
|
||||||
if (inChain(obj, method)) return;
|
if (inChain(obj, method)) return;
|
||||||
const orig = obj[method];
|
const orig = obj[method];
|
||||||
if (typeof orig !== 'function') throw new Error(`hooks: ${method} is not a function`);
|
if (typeof orig !== 'function') throw new Error(`hooks: ${method} is not a function`);
|
||||||
|
|||||||
@@ -35,13 +35,12 @@
|
|||||||
// -> just stays hidden (the overrides below keep stock from showing it).
|
// -> just stays hidden (the overrides below keep stock from showing it).
|
||||||
//
|
//
|
||||||
// Contract: state in window.__sfuiSteamCloseState (schema 1: steamHidden,
|
// Contract: state in window.__sfuiSteamCloseState (schema 1: steamHidden,
|
||||||
// barOnly, history, redirected, redirects, restorePending; older versions'
|
// barOnly, history, redirected, redirects, restorePending) survives
|
||||||
// fields are left for a rollback) survives re-injection; teardown restores
|
// re-injection; teardown restores all overrides and never switches frames.
|
||||||
// all overrides and never switches frames.
|
|
||||||
// window.__sfuiSteamClose: plan(), homePlan(), steamHidden, barOnly, state.
|
// window.__sfuiSteamClose: plan(), homePlan(), steamHidden, barOnly, state.
|
||||||
((find, sigs, opts) => {
|
((find, sigs, opts) => {
|
||||||
const NAME = 'steam-close-button';
|
const NAME = 'steam-close-button';
|
||||||
const VERSION = 8;
|
const VERSION = 9;
|
||||||
const MAIN_KEY = 'valve.steam.gamepadui.main'; // sigs.overlayKeys
|
const MAIN_KEY = 'valve.steam.gamepadui.main'; // sigs.overlayKeys
|
||||||
const FRAME_ALIVE = 2; // sigs.frame
|
const FRAME_ALIVE = 2; // sigs.frame
|
||||||
const REASON = 'sfui steam-close-button';
|
const REASON = 'sfui steam-close-button';
|
||||||
@@ -53,12 +52,8 @@
|
|||||||
|
|
||||||
const DS = window.DashboardStore, FS = window.FrameStore;
|
const DS = window.DashboardStore, FS = window.FrameStore;
|
||||||
if (!DS || !FS) return 'not patched: window.DashboardStore/FrameStore missing';
|
if (!DS || !FS) return 'not patched: window.DashboardStore/FrameStore missing';
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunkvrwebui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunkvrwebui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, dashboard left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
const mx = mods.mobx.module;
|
const mx = mods.mobx.module;
|
||||||
if (typeof mx.runInAction !== 'function' || typeof mx.reaction !== 'function')
|
if (typeof mx.runInAction !== 'function' || typeof mx.reaction !== 'function')
|
||||||
return 'signature not found, dashboard left unpatched: mobx.runInAction/reaction';
|
return 'signature not found, dashboard left unpatched: mobx.runInAction/reaction';
|
||||||
@@ -75,9 +70,8 @@
|
|||||||
return (window.__sfuiSteamCloseState = { schema: 1, steamHidden: hidden, barOnly: false, history: [],
|
return (window.__sfuiSteamCloseState = { schema: 1, steamHidden: hidden, barOnly: false, history: [],
|
||||||
redirected: 0, redirects: [], restorePending: hidden, restored: saved?.schema === 1 ? { steamHidden: hidden } : null });
|
redirected: 0, redirects: [], restorePending: hidden, restored: saved?.schema === 1 ? { steamHidden: hidden } : null });
|
||||||
}
|
}
|
||||||
s.steamHidden ??= !!s.barOnly; // version <= 5: bar-only implied hidden
|
|
||||||
s.barOnly = !!s.barOnly && DS.activeFrame == null;
|
s.barOnly = !!s.barOnly && DS.activeFrame == null;
|
||||||
s.history ??= []; s.redirected ??= 0; s.redirects ??= []; s.restorePending = !!s.restorePending && s.steamHidden;
|
s.restorePending = !!s.restorePending && s.steamHidden;
|
||||||
return s;
|
return s;
|
||||||
})();
|
})();
|
||||||
let persisted; // last steamHidden sent to the store
|
let persisted; // last steamHidden sent to the store
|
||||||
@@ -181,7 +175,6 @@
|
|||||||
__sfuiHadOwn: old ? cur.__sfuiHadOwn : !!own });
|
__sfuiHadOwn: old ? cur.__sfuiHadOwn : !!own });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const DASH_NAMES = [...Object.keys(methodWrappers), 'onShowOverlayRequestFromSteam']; // + version <= 6
|
|
||||||
const unwrapAll = (obj, names) => {
|
const unwrapAll = (obj, names) => {
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
const f = obj?.[name];
|
const f = obj?.[name];
|
||||||
@@ -197,7 +190,6 @@
|
|||||||
if (!dash) return false;
|
if (!dash) return false;
|
||||||
if (guarded && guarded !== dash) unguard(); // Dashboard remounted
|
if (guarded && guarded !== dash) unguard(); // Dashboard remounted
|
||||||
guarded = dash;
|
guarded = dash;
|
||||||
unwrapAll(dash, DASH_NAMES.filter((n) => !(n in methodWrappers))); // left by an older version
|
|
||||||
wrapAll(dash, methodWrappers);
|
wrapAll(dash, methodWrappers);
|
||||||
const h = dash.m_mailbox?.m_oHandlers; // registered once the mailbox is up
|
const h = dash.m_mailbox?.m_oHandlers; // registered once the mailbox is up
|
||||||
if (h && typeof h === 'object') {
|
if (h && typeof h === 'object') {
|
||||||
@@ -207,7 +199,7 @@
|
|||||||
return ours(dash.autoSwitchOverlayIfNeeded);
|
return ours(dash.autoSwitchOverlayIfNeeded);
|
||||||
};
|
};
|
||||||
const unguard = () => {
|
const unguard = () => {
|
||||||
unwrapAll(guarded, DASH_NAMES);
|
unwrapAll(guarded, Object.keys(methodWrappers));
|
||||||
unwrapAll(guardedHandlers, Object.keys(handlerWrappers));
|
unwrapAll(guardedHandlers, Object.keys(handlerWrappers));
|
||||||
guarded = guardedHandlers = null;
|
guarded = guardedHandlers = null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,14 +22,10 @@
|
|||||||
// mkPatch patch (see lib/default.nix); no options. On a signature mismatch
|
// mkPatch patch (see lib/default.nix); no options. On a signature mismatch
|
||||||
// it returns an error and changes nothing. Idempotent.
|
// it returns an error and changes nothing. Idempotent.
|
||||||
((find, sigs) => {
|
((find, sigs) => {
|
||||||
const VERSION = 21;
|
const VERSION = 22;
|
||||||
const send = (msg) => window.__vrkbdKey && window.__vrkbdKey(msg);
|
const send = (msg) => window.__vrkbdKey && window.__vrkbdKey(msg);
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunksteamui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunksteamui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, Steam left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
const Layouts = mods.layouts.exports; // currentLayout(), enabledLayouts(), arrow keys
|
const Layouts = mods.layouts.exports; // currentLayout(), enabledLayouts(), arrow keys
|
||||||
const Status = mods.vrStatus.exports.holder; // .VRKeyboardStatus
|
const Status = mods.vrStatus.exports.holder; // .VRKeyboardStatus
|
||||||
const Manager = mods.keyboardManager.exports.VirtualKeyboardManager.prototype;
|
const Manager = mods.keyboardManager.exports.VirtualKeyboardManager.prototype;
|
||||||
@@ -214,9 +210,7 @@
|
|||||||
const sel = (keys, suffix = '') => keys.map((key) => `[data-key="${key}"]${suffix}`).join(',');
|
const sel = (keys, suffix = '') => keys.map((key) => `[data-key="${key}"]${suffix}`).join(',');
|
||||||
const lastRow = Math.max(...[...doc.querySelectorAll('[data-key-row]')].map((e) => +e.getAttribute('data-key-row')));
|
const lastRow = Math.max(...[...doc.querySelectorAll('[data-key-row]')].map((e) => +e.getAttribute('data-key-row')));
|
||||||
const added = [...MODS, ...ARROWS.map(first), ...ALTGR_ARROWS].map((x) => x.key);
|
const added = [...MODS, ...ARROWS.map(first), ...ALTGR_ARROWS].map((x) => x.key);
|
||||||
let style = doc.getElementById('vrkbd-style');
|
find.ensureStyle(doc, 'vrkbd-style', [
|
||||||
if (!style) { style = doc.createElement('style'); style.id = 'vrkbd-style'; doc.head.appendChild(style); }
|
|
||||||
style.textContent = [
|
|
||||||
`${sel(added)} { width: 43px !important; }`,
|
`${sel(added)} { width: 43px !important; }`,
|
||||||
'[data-key="AltGr"] { width: 52px !important; }',
|
'[data-key="AltGr"] { width: 52px !important; }',
|
||||||
// Steam draws the AltGr variant as a small secondary label: hide it in the
|
// Steam draws the AltGr variant as a small secondary label: hide it in the
|
||||||
@@ -236,7 +230,7 @@
|
|||||||
// Motiva Sans descent 0.24 em, } 0.094 em below the baseline).
|
// Motiva Sans descent 0.24 em, } 0.094 em below the baseline).
|
||||||
`.vrkbd-del-hint [role="gridcell"]:has(+ [role="gridcell"] > [data-key="Backspace"]) > [data-key]:not([data-key="${DEL}"]) > div > span:last-child:not(:first-child) {` +
|
`.vrkbd-del-hint [role="gridcell"]:has(+ [role="gridcell"] > [data-key="Backspace"]) > [data-key]:not([data-key="${DEL}"]) > div > span:last-child:not(:first-child) {` +
|
||||||
' font-size: 7px !important; bottom: 4.42px !important; }',
|
' font-size: 7px !important; bottom: 4.42px !important; }',
|
||||||
].join('\n');
|
].join('\n'));
|
||||||
|
|
||||||
// ---- key handling ----------------------------------------------------------
|
// ---- key handling ----------------------------------------------------------
|
||||||
const release = (v) => { const z = v & 3; return (z === 1 ? 0 : z) | (v & 4); };
|
const release = (v) => { const z = v & 3; return (z === 1 ? 0 : z) | (v & 4); };
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
// scalePressDragThreshold(factor), pressing, dragValue(v0, dy, ppu, cur).
|
// scalePressDragThreshold(factor), pressing, dragValue(v0, dy, ppu, cur).
|
||||||
((find, sigs, opts, hooks) => {
|
((find, sigs, opts, hooks) => {
|
||||||
const NAME = 'window-curvature';
|
const NAME = 'window-curvature';
|
||||||
const VERSION = 20;
|
const VERSION = 21;
|
||||||
const FLAT = 999; // origin distances >= this are "flat"
|
const FLAT = 999; // origin distances >= this are "flat"
|
||||||
const ICON_OFF = 40, ICON_ON = 39; // Toggle Curvature action icons (sigs.curvatureAction)
|
const ICON_OFF = 40, ICON_ON = 39; // Toggle Curvature action icons (sigs.curvatureAction)
|
||||||
const HAPTIC = { Snap: 3, Sliding: 4, SlidingEdge: 5 }; // EOverlayHapticEffect (sigs.hapticEffects)
|
const HAPTIC = { Snap: 3, Sliding: 4, SlidingEdge: 5 }; // EOverlayHapticEffect (sigs.hapticEffects)
|
||||||
@@ -92,12 +92,8 @@
|
|||||||
|
|
||||||
const DS = window.DashboardStore, FS = window.FrameStore;
|
const DS = window.DashboardStore, FS = window.FrameStore;
|
||||||
if (!DS || !FS) return 'not patched: window.DashboardStore/FrameStore missing';
|
if (!DS || !FS) return 'not patched: window.DashboardStore/FrameStore missing';
|
||||||
let mods;
|
const mods = find.resolvePatch('webpackChunkvrwebui', sigs);
|
||||||
try {
|
if (typeof mods === 'string') return mods;
|
||||||
mods = find.resolveAll(find.getWebpackRequire('webpackChunkvrwebui'), sigs);
|
|
||||||
} catch (e) {
|
|
||||||
return `signature not found, dashboard left unpatched: ${e.message}`;
|
|
||||||
}
|
|
||||||
const mx = mods.mobx.module;
|
const mx = mods.mobx.module;
|
||||||
if (typeof mx.reaction !== 'function') return 'signature not found, dashboard left unpatched: mobx.reaction';
|
if (typeof mx.reaction !== 'function') return 'signature not found, dashboard left unpatched: mobx.reaction';
|
||||||
const proto = mods.mailbox.exports.Mailbox.prototype;
|
const proto = mods.mailbox.exports.Mailbox.prototype;
|
||||||
@@ -113,10 +109,7 @@
|
|||||||
let S = window.__sfuiWindowCurvatureState;
|
let S = window.__sfuiWindowCurvatureState;
|
||||||
if (S?.schema !== 1) S = window.__sfuiWindowCurvatureState = { schema: 1, values: {} };
|
if (S?.schema !== 1) S = window.__sfuiWindowCurvatureState = { schema: 1, values: {} };
|
||||||
const logBuf = S.log ??= [];
|
const logBuf = S.log ??= [];
|
||||||
const log = (msg, data) => {
|
const log = find.logger(logBuf);
|
||||||
logBuf.push({ t: new Date().toISOString().slice(11, 23), msg, ...(data ? { data } : {}) });
|
|
||||||
if (logBuf.length > 200) logBuf.splice(0, logBuf.length - 200);
|
|
||||||
};
|
|
||||||
const hits = { sends: 0, origins: 0, scaled: 0, haptics: 0 };
|
const hits = { sends: 0, origins: 0, scaled: 0, haptics: 0 };
|
||||||
|
|
||||||
// ---- values ------------------------------------------------------------------------
|
// ---- values ------------------------------------------------------------------------
|
||||||
@@ -265,12 +258,7 @@ ${ROW}:last-child > .sfui-curv-ind { margin-bottom: -14px; }
|
|||||||
.sfui-curv-ind > .sfui-curv-dn { top: calc(50% + 1.05em); clip-path: polygon(0 0, 100% 0, 50% 100%); }
|
.sfui-curv-ind > .sfui-curv-dn { top: calc(50% + 1.05em); clip-path: polygon(0 0, 100% 0, 50% 100%); }
|
||||||
.sfui-curv-ind > .sfui-curv-up:empty, .sfui-curv-ind > .sfui-curv-dn:empty { visibility: hidden; }
|
.sfui-curv-ind > .sfui-curv-up:empty, .sfui-curv-ind > .sfui-curv-dn:empty { visibility: hidden; }
|
||||||
`;
|
`;
|
||||||
const ensureStyle = () => {
|
const ensureStyle = () => find.ensureStyle(document, STYLE_ID, CSS);
|
||||||
if (document.getElementById(STYLE_ID)) return;
|
|
||||||
const s = document.createElement('style');
|
|
||||||
s.id = STYLE_ID; s.textContent = CSS;
|
|
||||||
document.head.appendChild(s);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Toggle Curvature action: invocation 2 with the curvature icons. Menu row:
|
// Toggle Curvature action: invocation 2 with the curvature icons. Menu row:
|
||||||
// by position, verified (else found) by label; bar button: by React
|
// by position, verified (else found) by label; bar button: by React
|
||||||
|
|||||||
Reference in new issue
Block a user