modules: consistency pass over patches and option docs

- pinned-desktop (VERSION 3): drop the stop() of a predecessor global that
  never existed in this repo; log errors as "sfui <NAME>:" through one
  guard helper, like the grid patch.
- steamCloseButton.enable is a mkEnableOption like the other feature
  switches; enable descriptions no longer end in a stray newline.
- launcher-menu.nix header lists show-all and no longer claims the patches
  use no webpack module; hiddenApps mentions showAllApps.
- Patch comments: frame-controls ring timing matches the code (half of
  longPressMs, at most 1 s), window-curvature names frame-controls as what
  moves its control into the bar, steam-close-button no longer refers to an
  unpublished version.
This commit is contained in:
Pierre Kisters committed 2026-09-27 23:28:05 +02:00
1 parent 93d061b458
commit e98563bf08
9 files changed
+32 -38

No files matched your search

+1 -2
View File
@@ -43,8 +43,7 @@ let
in {
options.steamFrame.firefox = {
enable = lib.mkEnableOption ''
the Firefox Flatpak (org.mozilla.firefox) launcher with Steam Frame fixes
'';
the Firefox Flatpak (org.mozilla.firefox) launcher with Steam Frame fixes'';
vrFullscreenFix = lib.mkOption {
type = lib.types.bool;
default = true;
+3 -3
View File
@@ -1,8 +1,8 @@
// frame-controls: move the control icons under SteamVR dashboard windows
// between the window's bottom bar and its More Options (three-dot) menu.
// A long press on a bar icon or a menu row (opts.longPressMs; a ring around
// the icon fills up once half a second .. a second has passed) opens a small
// popup with a "Show in bar" checkbox; toggling it moves that control for all
// the icon shows the progress from half that time, at most after 1 s) opens a
// small popup with a "Show in bar" checkbox; toggling it moves that control for all
// windows. Short presses stay stock. The three-dot button itself can't be
// moved (stock shows it while its menu has entries). opts.floatInTheater
// gives theater windows the "Float" control back.
@@ -46,7 +46,7 @@
// dashboard (no right-click; the thumbstick click arrives as nothing), so a
// long press is the trigger. Nothing is stopped or restyled while holding;
// the timer keeps running when the laser moves or leaves the control and is
// cancelled only by an early release. When it completes, the popup opens and
// cancelled by an early release (or a curvature drag, below). When it completes, the popup opens and
// the one click that follows the release on that control is swallowed, so
// its stock action doesn't run.
// window-curvature (its controls own press-and-drag) contract: its elements
+2 -1
View File
@@ -1,5 +1,6 @@
# Hide system apps from menus, including the Steam session's "+" menu (with
# Developer Mode on it lists every desktop entry GLib would show). A user
# Developer Mode on, or launcherMenu.showAllApps, it lists every desktop entry
# GLib would show). A user
# entry with Hidden=true in ~/.local/share/applications masks the one in
# /usr/share/applications. Also hides them from the nested desktop's KDE menu.
{ config, lib, ... }: {
+14 -12
View File
@@ -1,24 +1,27 @@
# 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:
# nested Plasma session) somewhere in a scrolling list. Runtime patches of
# Steam's UI (steam-ui-patches.nix, evaluated in SharedJSContext), each
# registered only when its option is set:
# - 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.
# original;
# - 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.
# launches);
# - grid/: restyles the programs section as a grid of tiles (icon, name
# below), optionally limited to maxRows visible rows.
# All are reverted when turned off (next switch).
# Depends on Steam UI internals (React props, popup names, the scroll fade's
# classes and CSS), not on webpack module ids; scripts/check-signatures.mjs
# checks them after a Steam update (lib/signatures.json). Tested with Steam
# client 1790377368.
# below), optionally limited to maxRows visible rows;
# - show-all/: empties the list of programs Steam hides without Developer
# Mode (the webpack module holding it is found by signature).
# Options reach the patches through mkPatch's `opts`. All are reverted when
# turned off (next switch). Besides that one module, they depend on Steam UI
# internals such as React props, popup names and the scroll fade's classes
# and CSS; scripts/check-signatures.mjs checks all of them after a Steam
# update (lib/signatures.json). Tested with Steam client 1790377368.
#
# iconFallbacks is not a patch: Steam's scan of host programs resolves a
# desktop entry's Icon= name only in the hicolor icon theme (and pixmaps),
@@ -91,8 +94,7 @@ in {
grid = {
enable = lib.mkEnableOption ''
the "+" menu's programs as a grid of tiles (large icon, name below)
instead of a list. Runtime patch of Steam's UI (steamFrame.uiPatches)
'';
instead of a list. Runtime patch of Steam's UI (steamFrame.uiPatches)'';
columns = lib.mkOption {
type = lib.types.ints.between 1 8;
default = 4;
@@ -27,7 +27,8 @@
// unpatch.js (or a new VERSION/position) calls __sfuiPinnedDesktop.stop(),
// which removes the pinned blocks, CSS, markers, observers and the timer.
((find, sigs, opts) => {
const VERSION = 2;
const NAME = 'launcher-menu-pinned-desktop';
const VERSION = 3;
const POS = opts.position === 'top' ? 'top' : 'bottom';
const KEY = 'steamos-nested-desktop';
const HIDDEN = 'data-sfui-desktop-hidden';
@@ -42,10 +43,10 @@
const prev = window.__sfuiPinnedDesktop;
if (prev?.version === VERSION && prev.position === POS) { prev.scan(); return 'unchanged'; }
prev?.stop?.();
window.__sfuiDesktopFooter?.stop?.(); // predecessor of this patch
if (!window.g_PopupManager) return 'g_PopupManager missing';
const docs = new Map(); // popup document -> MutationObserver
const guard = (f) => (...a) => { try { f(...a); } catch (e) { console.error(`sfui ${NAME}:`, e); } };
// The stock Desktop item: role=button element whose fiber ancestors include
// the list entry keyed by the program's exe path.
const isDesktop = (el) => {
@@ -128,7 +129,7 @@
s.id = STYLE_ID; s.textContent = CSS;
(d.head ?? d.documentElement).appendChild(s);
}
const obs = new MutationObserver(() => { try { update(d); } catch (e) { console.error('sfui pinned-desktop:', e); } });
const obs = new MutationObserver(guard(() => update(d)));
obs.observe(d.body, { childList: true, subtree: true, characterData: true });
docs.set(d, obs);
update(d);
@@ -136,10 +137,8 @@
const scan = () => {
for (const [d, obs] of docs) if (!d.defaultView || d.defaultView.closed) { obs.disconnect(); docs.delete(d); }
for (const p of g_PopupManager.GetPopups()) {
if (!/barpopup/.test(p.m_strName ?? '')) continue;
try { attach(p.window?.document); } catch (e) { console.error('sfui pinned-desktop:', e); }
}
for (const p of g_PopupManager.GetPopups())
if (/barpopup/.test(p.m_strName ?? '')) guard(() => attach(p.window?.document))();
};
const timer = setInterval(scan, 1000);
+3 -8
View File
@@ -16,20 +16,15 @@ let
in {
imports = [ ./steam-ui-patches.nix ./steamvr-debugger.nix ];
options.steamFrame.dashboard.steamCloseButton.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Close (X) button on the SteamVR dashboard's main Steam window. It
options.steamFrame.dashboard.steamCloseButton.enable = lib.mkEnableOption ''
a Close (X) button on the SteamVR dashboard's main Steam window. It
docks the window back into the dashboard if it was placed in the world,
then switches to the most recently active other dashboard window, or,
with none, leaves the dashboard open with just its bar ("bar only";
kept when the dashboard is closed and reopened, until a window is
activated, e.g. with the Steam tab). Runtime patch of the SteamVR
dashboard (steamFrame.uiPatches), applied immediately; turning it off
removes the button (next switch).
'';
};
removes the button (next switch)'';
config = lib.mkIf cfg.enable {
steamFrame.uiPatches.patches = [ {
+1 -2
View File
@@ -46,8 +46,7 @@
//
// State that must outlive this instance (bar-only flag, last open time,
// pending Steam request, frame history, suppression log) is kept in
// window.__sfuiSteamCloseState (schema 1, shared with the earlier personal
// version 4 of this patch, whose instance is handed over seamlessly).
// window.__sfuiSteamCloseState (schema 1), which upgrades take over.
// Teardown (unpatch.js, a newer VERSION) only removes overrides, reactions
// and markers: it never switches frames and leaves the state, so a
// re-injection (service restart, switch) continues bar-only. It is in-page
+1 -2
View File
@@ -29,8 +29,7 @@ in {
separate arrow keys, real Ctrl/Alt chords (held while toggled, e.g. for
Ctrl+scroll), and working AltGr/non-ASCII characters. Injected into Steam's
UI through its CEF DevTools port by an xdotool helper service; disabling
it reverts the patch on the next switch
'';
it reverts the patch on the next switch'';
config = lib.mkMerge [
(lib.mkIf config.steamFrame.steamKeyboardPatch.enable {
+1 -1
View File
@@ -2,7 +2,7 @@
// stock "Toggle Curvature" control becomes a wheel wherever it is shown: the
// row of a window's More Options (three-dot) menu (with the value on the
// right of the row) and, when the control sits in the window's bottom bar
// (e.g. moved there by another patch), that bar button (no value shown:
// (e.g. moved there by frame-controls), that bar button (no value shown:
// the steps and snap points are felt as controller haptics). Click toggles
// (curved -> flat, flat -> stock curve), dragging up/down with the laser sets
// the curvature live.