mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 04:04:16 +02:00
Runtime patches no longer use webpack module ids or minified export names, which change with every Steam UI build: - modules/lib/finders.js: finder library (getWebpackRequire, findModule/findExport by source text and shape, resolveAll with a per-page cache, findFiberUp/findFiberDown/findInReactTree), installed once per page as window.__sfuiFind. - modules/lib/signatures.json: the signatures, per patch, shared by the patches and the checker. lib/default.nix mkPatch wraps a patch `(find, sigs, opts) => ...` with the library, its signatures and options; exposed as steamFrame.uiPatches.lib. - Keyboard patch (VERSION 10): layouts module, current/enabled layout getters, arrow keys, VR keyboard status and VirtualKeyboardManager are found by signature; if one doesn't match it reports which and leaves Steam untouched. unpatch.js uses references the patch remembered. The helper logs inject results when they change. - launcher-menu launch/pinned-desktop use the library's fiber helpers; launch no longer depends on the bar popup's window name. - scripts/check-signatures.mjs (+ webpack-modules.mjs): extracts module factories from the installed bundles without a browser and checks every signature (found / ambiguous / missing, with module ids and export names). README: "Finders and signatures", "After a Steam update".
105 lines
4.4 KiB
Nix
105 lines
4.4 KiB
Nix
# The VR dashboard's "+" menu (non-Steam programs, #VRDashboard_LaunchNonSteamApp)
|
|
# lists programs in the order SteamClient.Apps.ScanForInstalledNonSteamApps()
|
|
# returns them: GLib hash-table order, effectively random, with "Desktop" (the
|
|
# nested Plasma session) somewhere in a scrolling list. Two runtime patches of
|
|
# Steam's UI (steam-ui-patches.nix, evaluated in SharedJSContext) fix that:
|
|
# - order/: wraps ScanForInstalledNonSteamApps to sort the list by name;
|
|
# - pinned-desktop/: hides Desktop in the scrolling list and pins a copy above
|
|
# or below it, with a separator; clicking the copy clicks the hidden
|
|
# original. The position is passed by calling the patch's function.
|
|
# - launch/: wraps SteamClient.Apps.LaunchNonSteamApp (only called by this
|
|
# menu) to close the menu right after a program is started, and/or to
|
|
# ignore repeated launches of the same program within a few seconds (stock,
|
|
# the menu stays open until the program's window appears, inviting double
|
|
# launches). Options are passed by calling the patch's function.
|
|
# All are reverted when turned off (next switch).
|
|
# Depends on Steam UI internals (React props, popup names), not on webpack
|
|
# module ids; scripts/check-signatures.mjs checks them after a Steam update
|
|
# (lib/signatures.json). Tested with Steam client 1790377368.
|
|
{ config, lib, pkgs, ... }:
|
|
let
|
|
cfg = config.steamFrame.launcherMenu;
|
|
inherit (import ./lib { inherit pkgs; }) mkPatch;
|
|
sharedJSContext = { title = "SharedJSContext"; };
|
|
in {
|
|
imports = [ ./steam-ui-patches.nix ];
|
|
|
|
options.steamFrame.launcherMenu = {
|
|
sort = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = ''
|
|
Sort the VR dashboard's "+" menu (non-Steam programs) alphabetically
|
|
instead of Steam's random-looking order. Runtime patch of Steam's UI
|
|
(steamFrame.uiPatches).
|
|
'';
|
|
};
|
|
pinDesktop = lib.mkOption {
|
|
type = lib.types.nullOr (lib.types.enum [ "top" "bottom" ]);
|
|
default = null;
|
|
example = "bottom";
|
|
description = ''
|
|
Pin "Desktop" (the nested Plasma session) above ("top", below the
|
|
menu heading) or below ("bottom") the scrolling program list of the
|
|
"+" menu, separated by a thin line, so it is always visible; it is
|
|
hidden in the list itself. null leaves it a normal list entry. Runtime
|
|
patch of Steam's UI (steamFrame.uiPatches).
|
|
'';
|
|
};
|
|
closeOnLaunch = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = ''
|
|
Close the "+" menu as soon as a program in it is activated (pointer,
|
|
controller or the pinned Desktop entry). Stock, it stays open until the
|
|
program's window appears, so it looks as if the click did nothing and
|
|
programs get launched twice. Runtime patch of Steam's UI
|
|
(steamFrame.uiPatches); off by default like the other launcherMenu
|
|
options, so nothing is injected unless asked for.
|
|
'';
|
|
};
|
|
launchDebounce = lib.mkOption {
|
|
type = lib.types.ints.unsigned;
|
|
default = 0;
|
|
example = 10;
|
|
description = ''
|
|
Seconds during which another launch of the same program (same command
|
|
line) from the "+" menu is ignored, counted from the last launch that
|
|
went through; ignored launches are logged (steam-ui-patches journal).
|
|
0 disables it. Runtime patch of Steam's UI (steamFrame.uiPatches).
|
|
'';
|
|
};
|
|
};
|
|
|
|
config.steamFrame.uiPatches.patches =
|
|
lib.optional cfg.sort {
|
|
name = "launcher-menu-order";
|
|
target = sharedJSContext;
|
|
patch = ./launcher-menu/order/patch.js;
|
|
unpatch = ./launcher-menu/order/unpatch.js;
|
|
}
|
|
++ lib.optional (cfg.pinDesktop != null) {
|
|
name = "launcher-menu-pinned-desktop";
|
|
target = sharedJSContext;
|
|
patch = mkPatch {
|
|
name = "launcher-menu-pinned-desktop";
|
|
src = ./launcher-menu/pinned-desktop/patch.js;
|
|
opts.position = cfg.pinDesktop;
|
|
};
|
|
unpatch = ./launcher-menu/pinned-desktop/unpatch.js;
|
|
}
|
|
++ lib.optional (cfg.closeOnLaunch || cfg.launchDebounce > 0) {
|
|
name = "launcher-menu-launch";
|
|
target = sharedJSContext;
|
|
patch = mkPatch {
|
|
name = "launcher-menu-launch";
|
|
src = ./launcher-menu/launch/patch.js;
|
|
opts = {
|
|
inherit (cfg) closeOnLaunch;
|
|
debounceSeconds = cfg.launchDebounce;
|
|
};
|
|
};
|
|
unpatch = ./launcher-menu/launch/unpatch.js;
|
|
};
|
|
}
|