mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 01:00:13 +02:00
Options regrouped: session.*, keyboard.*, launcherMenu.hiddenApps
- runtimeDir, userBus, outerBusEnv, userServices.*, portalFix.enable
-> session.{runtimeDir, bus, busEnv, services.*, portalFix.enable}
- keyboardLayout/keyboardVariant -> keyboard.layout/variant;
steamKeyboardPatch.enable -> keyboard.vr.extraKeys.enable
- hiddenApps -> launcherMenu.hiddenApps
- launcherMenu.launchDebounce -> launchDebounceSeconds (also the patch's
option key; launcher-menu-launch VERSION 3)
- "Steam UI patch" in option descriptions
Old names keep working with a rename warning (outerBusEnv is read-only:
reading it warns).
This commit is contained in:
1 parent
36fcb207bd
commit
a0c3e0846f
8 files changed
+124
-63
No files matched your search
+11
-3
@@ -1,15 +1,23 @@
|
||||
# Hide desktop entries from the "+" menu and the KDE menu: a user entry with
|
||||
# Hidden=true masks the system one.
|
||||
{ config, lib, ... }: {
|
||||
options.steamFrame.hiddenApps = lib.mkOption {
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "steamFrame" "hiddenApps" ] [ "steamFrame" "launcherMenu" "hiddenApps" ])
|
||||
];
|
||||
|
||||
options.steamFrame.launcherMenu.hiddenApps = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "lxterminal" "cmake-gui" "firewall-config" "renderdoc" ];
|
||||
description = "Desktop entry ids (without .desktop) to hide from the \"+\" menu and the KDE menu.";
|
||||
description = ''
|
||||
Desktop entry ids (without .desktop) to hide from the "+" menu and the
|
||||
KDE menu.
|
||||
'';
|
||||
};
|
||||
|
||||
config.xdg.dataFile = lib.genAttrs
|
||||
(map (id: "applications/${id}.desktop") config.steamFrame.hiddenApps)
|
||||
(map (id: "applications/${id}.desktop") config.steamFrame.launcherMenu.hiddenApps)
|
||||
(_: {
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
|
||||
@@ -4,10 +4,15 @@
|
||||
# (next session start).
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.steamFrame;
|
||||
cfg = config.steamFrame.keyboard;
|
||||
in {
|
||||
options.steamFrame = {
|
||||
keyboardLayout = lib.mkOption {
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "steamFrame" "keyboardLayout" ] [ "steamFrame" "keyboard" "layout" ])
|
||||
(lib.mkRenamedOptionModule [ "steamFrame" "keyboardVariant" ] [ "steamFrame" "keyboard" "variant" ])
|
||||
];
|
||||
|
||||
options.steamFrame.keyboard = {
|
||||
layout = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "de";
|
||||
@@ -15,7 +20,7 @@ in {
|
||||
XKB layout for the Steam session (XKB_DEFAULT_LAYOUT); null = US.
|
||||
'';
|
||||
};
|
||||
keyboardVariant = lib.mkOption {
|
||||
variant = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "nodeadkeys";
|
||||
@@ -23,12 +28,12 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.keyboardLayout != null || cfg.keyboardVariant != null) {
|
||||
config = lib.mkIf (cfg.layout != null || cfg.variant != null) {
|
||||
xdg.configFile."systemd/user/gamescope-session.service.d/keyboard.conf".text =
|
||||
"[Service]\n"
|
||||
+ lib.optionalString (cfg.keyboardLayout != null)
|
||||
"Environment=XKB_DEFAULT_LAYOUT=${cfg.keyboardLayout}\n"
|
||||
+ lib.optionalString (cfg.keyboardVariant != null)
|
||||
"Environment=XKB_DEFAULT_VARIANT=${cfg.keyboardVariant}\n";
|
||||
+ lib.optionalString (cfg.layout != null)
|
||||
"Environment=XKB_DEFAULT_LAYOUT=${cfg.layout}\n"
|
||||
+ lib.optionalString (cfg.variant != null)
|
||||
"Environment=XKB_DEFAULT_VARIANT=${cfg.variant}\n";
|
||||
};
|
||||
}
|
||||
+18
-15
@@ -1,5 +1,5 @@
|
||||
# The VR dashboard's "+" menu (non-Steam programs). Steam lists them in GLib
|
||||
# hash-table order (random-looking). Runtime patches in SharedJSContext, each
|
||||
# hash-table order (random-looking). Steam UI patches in SharedJSContext, each
|
||||
# registered only when its option is set, reverted when unset (next switch):
|
||||
# - order/: sorts ScanForInstalledNonSteamApps() by name;
|
||||
# - pinned-desktop/: hides Desktop in the list, pins a proxy above/below it;
|
||||
@@ -26,14 +26,19 @@ let
|
||||
text = builtins.readFile ./launcher-menu/icon-fallbacks.sh;
|
||||
};
|
||||
in {
|
||||
imports = [ ./steam-ui-patches.nix ];
|
||||
imports = [
|
||||
./steam-ui-patches.nix
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "steamFrame" "launcherMenu" "launchDebounce" ]
|
||||
[ "steamFrame" "launcherMenu" "launchDebounceSeconds" ])
|
||||
];
|
||||
|
||||
options.steamFrame.launcherMenu = {
|
||||
sort = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Sort the "+" menu (non-Steam programs) by name. Runtime patch.
|
||||
Sort the "+" menu (non-Steam programs) by name. Steam UI patch.
|
||||
'';
|
||||
};
|
||||
pinDesktop = lib.mkOption {
|
||||
@@ -43,7 +48,7 @@ in {
|
||||
description = ''
|
||||
Pin "Desktop" (the nested Plasma session) above ("top") or below
|
||||
("bottom") the "+" menu's scrolling list, so it is always visible;
|
||||
null = normal list entry. Runtime patch.
|
||||
null = normal list entry. Steam UI patch.
|
||||
'';
|
||||
};
|
||||
closeOnLaunch = lib.mkOption {
|
||||
@@ -51,23 +56,24 @@ in {
|
||||
default = false;
|
||||
description = ''
|
||||
Close the "+" menu as soon as a program is launched (stock: it stays
|
||||
open until the window appears, inviting double launches). Runtime patch.
|
||||
open until the window appears, inviting double launches). Steam UI
|
||||
patch.
|
||||
'';
|
||||
};
|
||||
launchDebounce = lib.mkOption {
|
||||
launchDebounceSeconds = lib.mkOption {
|
||||
type = lib.types.ints.unsigned;
|
||||
default = 0;
|
||||
example = 10;
|
||||
description = ''
|
||||
Ignore another "+" menu launch of the same command line within this
|
||||
many seconds of the last one that went through (logged); 0 = off.
|
||||
Runtime patch.
|
||||
Steam UI patch.
|
||||
'';
|
||||
};
|
||||
grid = {
|
||||
enable = lib.mkEnableOption ''
|
||||
the "+" menu's programs as a grid of tiles (icon, name below) instead
|
||||
of a list. Runtime patch'';
|
||||
of a list. Steam UI patch'';
|
||||
columns = lib.mkOption {
|
||||
type = lib.types.ints.between 1 8;
|
||||
default = 4;
|
||||
@@ -93,8 +99,8 @@ in {
|
||||
List all programs in the "+" menu without Developer Mode (Steam
|
||||
otherwise hides konsole, systemsettings, dolphin, plasma-discover, vlc,
|
||||
firewall-config, cmake-gui, qrenderdoc, lxterminal, sh). Developer Mode
|
||||
itself is untouched; hide single programs with steamFrame.hiddenApps.
|
||||
Runtime patch.
|
||||
itself is untouched; hide single programs with
|
||||
steamFrame.launcherMenu.hiddenApps. Steam UI patch.
|
||||
'';
|
||||
};
|
||||
iconFallbacks = lib.mkOption {
|
||||
@@ -179,16 +185,13 @@ in {
|
||||
};
|
||||
unpatch = ./launcher-menu/pinned-desktop/unpatch.js;
|
||||
}
|
||||
++ lib.optional (cfg.closeOnLaunch || cfg.launchDebounce > 0) {
|
||||
++ lib.optional (cfg.closeOnLaunch || cfg.launchDebounceSeconds > 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;
|
||||
};
|
||||
opts = { inherit (cfg) closeOnLaunch launchDebounceSeconds; };
|
||||
};
|
||||
unpatch = ./launcher-menu/launch/unpatch.js;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// launch: what activating a program in the VR dashboard's "+" menu does.
|
||||
// mkPatch patch (see lib/default.nix); opts: { closeOnLaunch, debounceSeconds }.
|
||||
// mkPatch patch (see lib/default.nix); opts: { closeOnLaunch, launchDebounceSeconds }.
|
||||
//
|
||||
// Stock, an item only calls SteamClient.Apps.LaunchNonSteamApp(cmdline) and
|
||||
// the popup stays open until the new window appears, so users click twice.
|
||||
// That call is its only UI use and is looked up at call time, so it is wrapped
|
||||
// here in SharedJSContext:
|
||||
// - debounceSeconds > 0: the same command line within that many seconds of
|
||||
// - launchDebounceSeconds > 0: the same command line within that many seconds of
|
||||
// the last accepted launch is ignored (console.info; reported in the
|
||||
// steam-ui-patches journal on the next re-injection);
|
||||
// - closeOnLaunch: afterwards the "+" popup is closed via the bar button's
|
||||
@@ -16,10 +16,10 @@
|
||||
// Covers every activation path (pointer, controller, pinned Desktop copy).
|
||||
// Original kept as __sfuiOrig for unpatch.js; bump VERSION on changes.
|
||||
((find, sigs, opts) => {
|
||||
const VERSION = 2;
|
||||
const VERSION = 3;
|
||||
const NAME = 'launcher-menu-launch';
|
||||
const CLOSE = opts.closeOnLaunch === true;
|
||||
const DEBOUNCE_MS = Math.max(0, Number(opts.debounceSeconds) || 0) * 1000;
|
||||
const DEBOUNCE_MS = Math.max(0, Number(opts.launchDebounceSeconds) || 0) * 1000;
|
||||
const Apps = window.SteamClient?.Apps;
|
||||
const cur = Apps?.LaunchNonSteamApp;
|
||||
if (typeof cur !== 'function') return 'SteamClient.Apps.LaunchNonSteamApp missing';
|
||||
|
||||
+8
-2
@@ -8,7 +8,13 @@ let
|
||||
sys = "/usr/share/xdg-desktop-portal/gamescope-portals";
|
||||
dir = "xdg-desktop-portal/gamescope-portals";
|
||||
in {
|
||||
options.steamFrame.portalFix.enable = lib.mkOption {
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "steamFrame" "portalFix" "enable" ]
|
||||
[ "steamFrame" "session" "portalFix" "enable" ])
|
||||
];
|
||||
|
||||
options.steamFrame.session.portalFix.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
@@ -17,7 +23,7 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
config = lib.mkIf config.steamFrame.portalFix.enable {
|
||||
config = lib.mkIf config.steamFrame.session.portalFix.enable {
|
||||
xdg.dataFile."${dir}/holo.portal".source =
|
||||
config.lib.file.mkOutOfStoreSymlink "${sys}/holo.portal";
|
||||
xdg.dataFile."${dir}/gamescope.portal".source =
|
||||
|
||||
+52
-20
@@ -5,66 +5,98 @@
|
||||
# and private bus. `switch` usually runs from the nested desktop, where
|
||||
# home-manager's reloadSystemd is skipped ("User systemd daemon not running"),
|
||||
# so `steamFrameUserServices` does it against the outer session: always
|
||||
# daemon-reload, then start/stop/restart the units in `userServices`.
|
||||
# daemon-reload, then start/stop/restart the units in `session.services`.
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.steamFrame;
|
||||
cfg = config.steamFrame.session;
|
||||
units = lib.escapeShellArgs;
|
||||
rename = from: to: lib.mkRenamedOptionModule ([ "steamFrame" ] ++ from) [ "steamFrame" "session" to ];
|
||||
in {
|
||||
options.steamFrame = {
|
||||
imports = [
|
||||
(rename [ "runtimeDir" ] "runtimeDir")
|
||||
(rename [ "userBus" ] "bus")
|
||||
] ++ map (n: lib.mkRenamedOptionModule
|
||||
[ "steamFrame" "userServices" n ] [ "steamFrame" "session" "services" n ])
|
||||
[ "start" "restart" "stop" ];
|
||||
|
||||
# Read-only, so no mkRenamedOptionModule (its alias definition would be a
|
||||
# second one); reading the old name warns.
|
||||
options.steamFrame.outerBusEnv = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
readOnly = true;
|
||||
visible = false;
|
||||
default = lib.warn
|
||||
"The option `steamFrame.outerBusEnv' has been renamed to `steamFrame.session.busEnv'."
|
||||
cfg.busEnv;
|
||||
defaultText = lib.literalExpression "config.steamFrame.session.busEnv";
|
||||
description = "Alias of {option}`steamFrame.session.busEnv`.";
|
||||
};
|
||||
|
||||
options.steamFrame.session = {
|
||||
runtimeDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/run/user/1000";
|
||||
description = "XDG_RUNTIME_DIR of the outer (Steam/VR) session.";
|
||||
};
|
||||
userBus = lib.mkOption {
|
||||
bus = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "unix:path=${cfg.runtimeDir}/bus";
|
||||
defaultText = lib.literalExpression ''"unix:path=''${config.steamFrame.runtimeDir}/bus"'';
|
||||
defaultText = lib.literalExpression
|
||||
''"unix:path=''${config.steamFrame.session.runtimeDir}/bus"'';
|
||||
description = ''
|
||||
Outer session D-Bus address; the only bus that reaches the user
|
||||
systemd manager and the running kwalletd6.
|
||||
'';
|
||||
};
|
||||
outerBusEnv = lib.mkOption {
|
||||
busEnv = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
readOnly = true;
|
||||
default = "env DBUS_SESSION_BUS_ADDRESS=${cfg.userBus}";
|
||||
defaultText = lib.literalExpression ''"env DBUS_SESSION_BUS_ADDRESS=''${config.steamFrame.userBus}"'';
|
||||
default = "env DBUS_SESSION_BUS_ADDRESS=${cfg.bus}";
|
||||
defaultText = lib.literalExpression
|
||||
''"env DBUS_SESSION_BUS_ADDRESS=''${config.steamFrame.session.bus}"'';
|
||||
description = ''
|
||||
Exec= prefix for launchers that must use the outer bus, e.g. so apps
|
||||
in the nested desktop use the running kwalletd6 instead of a second one.
|
||||
in the nested desktop use the running kwalletd6 instead of a second
|
||||
one.
|
||||
'';
|
||||
};
|
||||
userServices = {
|
||||
services = {
|
||||
start = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "docker.service" ];
|
||||
description = "User units started on switch if not already running (outer user manager).";
|
||||
description = ''
|
||||
User units started on switch if not already running (outer user
|
||||
manager).
|
||||
'';
|
||||
};
|
||||
restart = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "steam-keyboard-patch.service" ];
|
||||
description = "User units restarted on every switch (outer user manager).";
|
||||
description = ''
|
||||
User units restarted on every switch (outer user manager).
|
||||
'';
|
||||
};
|
||||
stop = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "User units stopped on switch if running (e.g. of a just-disabled feature).";
|
||||
description = ''
|
||||
User units stopped on switch if running (e.g. of a just-disabled
|
||||
feature).
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.home.activation.steamFrameUserServices = lib.hm.dag.entryAfter [ "reloadSystemd" ] (''
|
||||
export XDG_RUNTIME_DIR=${lib.escapeShellArg cfg.runtimeDir} DBUS_SESSION_BUS_ADDRESS=${lib.escapeShellArg cfg.userBus}
|
||||
export XDG_RUNTIME_DIR=${lib.escapeShellArg cfg.runtimeDir} DBUS_SESSION_BUS_ADDRESS=${lib.escapeShellArg cfg.bus}
|
||||
run /usr/bin/systemctl --user daemon-reload
|
||||
'' + lib.optionalString (cfg.userServices.start != [ ]) ''
|
||||
run /usr/bin/systemctl --user start ${units cfg.userServices.start}
|
||||
'' + lib.optionalString (cfg.userServices.stop != [ ]) ''
|
||||
run /usr/bin/systemctl --user stop ${units cfg.userServices.stop} || true
|
||||
'' + lib.optionalString (cfg.userServices.restart != [ ]) ''
|
||||
run /usr/bin/systemctl --user restart ${units cfg.userServices.restart}
|
||||
'' + lib.optionalString (cfg.services.start != [ ]) ''
|
||||
run /usr/bin/systemctl --user start ${units cfg.services.start}
|
||||
'' + lib.optionalString (cfg.services.stop != [ ]) ''
|
||||
run /usr/bin/systemctl --user stop ${units cfg.services.stop} || true
|
||||
'' + lib.optionalString (cfg.services.restart != [ ]) ''
|
||||
run /usr/bin/systemctl --user restart ${units cfg.services.restart}
|
||||
'');
|
||||
}
|
||||
@@ -13,16 +13,22 @@ let
|
||||
name = "steam-keyboard-patch";
|
||||
src = ./steam-keyboard-patch/patch.js;
|
||||
};
|
||||
cfg = config.steamFrame.keyboard.vr.extraKeys;
|
||||
in {
|
||||
imports = [ ./session.nix ];
|
||||
imports = [
|
||||
./session.nix
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "steamFrame" "steamKeyboardPatch" "enable" ]
|
||||
[ "steamFrame" "keyboard" "vr" "extraKeys" "enable" ])
|
||||
];
|
||||
|
||||
options.steamFrame.steamKeyboardPatch.enable = lib.mkEnableOption ''
|
||||
options.steamFrame.keyboard.vr.extraKeys.enable = lib.mkEnableOption ''
|
||||
Esc/Ctrl/Alt, arrow keys, Ctrl/Alt chords (held while toggled) and
|
||||
AltGr/non-ASCII characters on Steam's VR keyboard (runtime patch plus an
|
||||
AltGr/non-ASCII characters on Steam's VR keyboard (Steam UI patch plus an
|
||||
xdotool helper service); off reverts it on the next switch'';
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf config.steamFrame.steamKeyboardPatch.enable {
|
||||
(lib.mkIf cfg.enable {
|
||||
systemd.user.services.steam-keyboard-patch = {
|
||||
Unit.Description = "Modifier keys for Steam's VR keyboard (CEF patch + xdotool)";
|
||||
Service = {
|
||||
@@ -41,11 +47,11 @@ in {
|
||||
};
|
||||
|
||||
# Restart on switch to re-inject a changed patch.
|
||||
steamFrame.userServices.restart = [ "steam-keyboard-patch.service" ];
|
||||
steamFrame.session.services.restart = [ "steam-keyboard-patch.service" ];
|
||||
})
|
||||
# Disabled: stopping the helper reverts the patch right away.
|
||||
(lib.mkIf (!config.steamFrame.steamKeyboardPatch.enable) {
|
||||
steamFrame.userServices.stop = [ "steam-keyboard-patch.service" ];
|
||||
(lib.mkIf (!cfg.enable) {
|
||||
steamFrame.session.services.stop = [ "steam-keyboard-patch.service" ];
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -23,7 +23,8 @@ let
|
||||
default = "http://127.0.0.1:8080";
|
||||
example = "http://127.0.0.1:8087";
|
||||
description = ''
|
||||
DevTools base URL (its /json/list is polled): Steam 8080, SteamVR 8087.
|
||||
DevTools base URL (its /json/list is polled): Steam 8080, SteamVR
|
||||
8087.
|
||||
'';
|
||||
};
|
||||
target = {
|
||||
@@ -134,11 +135,11 @@ in {
|
||||
|
||||
# Restart on switch: re-inject changed patches; the old instance reverts
|
||||
# removed ones.
|
||||
steamFrame.userServices.restart = [ "steam-ui-patches.service" ];
|
||||
steamFrame.session.services.restart = [ "steam-ui-patches.service" ];
|
||||
})
|
||||
# No patches: stopping the injector reverts them right away.
|
||||
(lib.mkIf (cfg.patches == [ ]) {
|
||||
steamFrame.userServices.stop = [ "steam-ui-patches.service" ];
|
||||
steamFrame.session.services.stop = [ "steam-ui-patches.service" ];
|
||||
})
|
||||
];
|
||||
}
|
||||
Reference in new issue
Block a user