From 59513bcbb1b3c28069bfa91ad4e5dbcd0fcb109d Mon Sep 17 00:00:00 2001 From: Pierre Kisters <1524059+lhns@users.noreply.github.com> Date: Tue, 29 Sep 2026 03:01:38 +0200 Subject: [PATCH] Applications menu for KDE apps in the Steam session SteamOS only ships /etc/xdg/menus/plasma-applications.menu; the nested desktop sets XDG_MENU_PREFIX=plasma-, the Steam session doesn't, so KDE apps started there (Dolphin from the "+" menu) built an empty app database: "no installed application can open" every file. session.applicationsMenu (module applications-menu, on by default) links ~/.config/menus/applications.menu to Plasma's menu. Flake check: the link is generated by default and absent when disabled. --- README.md | 16 ++++++++------- docs/development.md | 2 ++ docs/session.md | 32 +++++++++++++++++++++++++---- flake.nix | 5 ++++- modules/applications-menu.nix | 27 ++++++++++++++++++++++++ modules/applications-menu/check.nix | 31 ++++++++++++++++++++++++++++ template/home.nix | 3 ++- 7 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 modules/applications-menu.nix create mode 100644 modules/applications-menu/check.nix diff --git a/README.md b/README.md index f1df55c..566888f 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ [Home Manager](https://github.com/nix-community/home-manager) modules for the Valve Steam Frame (SteamOS, `aarch64-linux`, standalone home-manager). They work around quirks of the Frame's [two graphical sessions](#two-sessions) -(portal, keyboard layout, clipboard, KDE wallet, Firefox), enable hardware -video decoding in Jellyfin, run rootless Docker, and extend Steam's and -SteamVR's UIs at runtime (VR keyboard, "+" menu, dashboard windows, Steam -close button, window curvature, window controls). +(portal, KDE app menu, keyboard layout, clipboard, KDE wallet, Firefox), +enable hardware video decoding in Jellyfin, run rootless Docker, and extend +Steam's and SteamVR's UIs at runtime (VR keyboard, "+" menu, dashboard +windows, Steam close button, window curvature, window controls). Everything is declarative: files are links into the Nix store, UI patches live in memory. The few things that have to be written elsewhere at runtime @@ -15,8 +15,8 @@ their lifetime and what removes them; `steam-frame-nix-cleanup` removes every one of them (on each switch what the configuration no longer uses, `--all` for everything). -All options live under `steamFrame.*`. The portal fix and clipboard sync are -on by default; everything else is opt-in. +All options live under `steamFrame.*`. The portal fix, the applications menu +and clipboard sync are on by default; everything else is opt-in. ## Features @@ -27,6 +27,7 @@ configuration, limitations and how it works. - [Session settings](docs/session.md#session-settings-and-services) (`session.*`): outer bus and user services, for launchers and the other modules. - [Portal fix](docs/session.md#portal-fix) (`session.portalFix`, on): apps in the Steam session can open links. +- [Applications menu](docs/session.md#applications-menu) (`session.applicationsMenu`, on): KDE apps in the Steam session (Dolphin from the "+" menu) know the installed apps. - [Keyboard layout](docs/session.md#keyboard-layout) (`keyboard.layout`, `keyboard.variant`): XKB layout for the Steam session. - [Clipboard sync](docs/session.md#clipboard-sync) (`clipboardSync`, on): one clipboard for the Steam session and the nested desktop. @@ -214,7 +215,7 @@ home-manager switch --flake .#steamos # manual setup, from the flake's director In your own flake, add the input as above and `steam-frame-nix.homeManagerModules.default` to the modules. `default` imports all modules; single ones: -`homeManagerModules.{session,portal,keyboard-layout,vr-keyboard-extra-keys,vr-keyboard,hidden-apps,steam-ui-patches,launcher-menu,steamvr-debugger,cleanup,dashboard-windows,steam-close-button,window-curvature,frame-controls,clipboard-sync,firefox,jellyfin,launchers,docker}` +`homeManagerModules.{session,portal,applications-menu,keyboard-layout,vr-keyboard-extra-keys,vr-keyboard,hidden-apps,steam-ui-patches,launcher-menu,steamvr-debugger,cleanup,dashboard-windows,steam-close-button,window-curvature,frame-controls,clipboard-sync,firefox,jellyfin,launchers,docker}` (`steam-keyboard-patch` and `keyring` still work as the former names of `vr-keyboard-extra-keys` and `launchers`). Every module imports `cleanup` (see [Changes outside Nix](#changes-outside-nix-exceptions)); which file is @@ -231,6 +232,7 @@ which: [Repository layout](docs/development.md). | `steamFrame.session.services.restart` | list of str | `[ ]` | User units restarted on every switch. | | `steamFrame.session.services.stop` | list of str | `[ ]` | User units stopped on switch if running (e.g. of a disabled feature). | | `steamFrame.session.portalFix.enable` | bool | `true` | Working portal config (OpenURI) for the Steam session. | +| `steamFrame.session.applicationsMenu.enable` | bool | `true` | `~/.config/menus/applications.menu` linked to Plasma's, for KDE apps in the Steam session. | | `steamFrame.keyboard.layout` | null or str | `null` | XKB layout for the Steam session, e.g. `"de"`; `null`: US. | | `steamFrame.keyboard.variant` | null or str | `null` | XKB variant for the Steam session, e.g. `"nodeadkeys"`; see [Keyboard layout](docs/session.md#keyboard-layout). | | `steamFrame.keyboard.vr.extraKeys.enable` | bool | `false` | VR keyboard with Esc/Ctrl/Alt, arrows, real chords, AltGr/non-ASCII. | diff --git a/docs/development.md b/docs/development.md index 12d13f7..af0435d 100644 --- a/docs/development.md +++ b/docs/development.md @@ -50,6 +50,8 @@ modules/ cleanup/package.nix build: install.sh as a command (cleanup, steamvr-debugger-arm) cleanup/check.nix test: install.sh cleanup on fake home/runtime dirs portal.nix Steam session portal config (session.portalFix) + applications-menu.nix applications.menu link for KDE apps (session.applicationsMenu) + applications-menu/check.nix test: the link on by default, absent when disabled keyboard-layout.nix gamescope-session drop-in with XKB_DEFAULT_* (keyboard.layout) clipboard-sync.nix app: KDE autostart of clipboard-sync (clipboardSync) hidden-apps.nix Hidden=true desktop entries (launcherMenu.hiddenApps) diff --git a/docs/session.md b/docs/session.md index 236b22e..9c2a744 100644 --- a/docs/session.md +++ b/docs/session.md @@ -1,9 +1,10 @@ # Session fixes -Four fixes for the Frame's [two graphical sessions](../README.md#two-sessions): -session settings and services, the portal, the keyboard layout and the -clipboard. Options: [README, Options](../README.md#options) (`session.*`, -`keyboard.layout`, `keyboard.variant`, `clipboardSync.*`). +Five fixes for the Frame's [two graphical sessions](../README.md#two-sessions): +session settings and services, the portal, the applications menu, the +keyboard layout and the clipboard. Options: +[README, Options](../README.md#options) (`session.*`, `keyboard.layout`, +`keyboard.variant`, `clipboardSync.*`). ## Session settings and services @@ -55,6 +56,29 @@ desktop's portal is unaffected. files plus a config (`default=holo;gamescope`), and a drop-in on `xdg-desktop-portal.service`. +## Applications menu + +`session.applicationsMenu.enable`, module `applications-menu`. On by default; +`false` turns it off. + +**Problem:** KDE apps build their app database (ksycoca) from +`applications.menu`, but SteamOS only ships +`/etc/xdg/menus/plasma-applications.menu`. The nested desktop sets +`XDG_MENU_PREFIX=plasma-`, the Steam session doesn't: KDE apps started there +(e.g. Dolphin from the "+" menu) know no apps at all ("no installed +application can open …"). + +**What you get:** KDE apps in the Steam session see every installed app, +Flatpaks included, e.g. for "Open with". The nested desktop is unaffected (it +reads Plasma's menu through its prefix). + +**Remove when** the Steam session sets `XDG_MENU_PREFIX` or SteamOS ships +`applications.menu`. + +**How it works:** `~/.config/menus/applications.menu` is a Home Manager link +to `/etc/xdg/menus/plasma-applications.menu`. If SteamOS drops that file, +the link dangles, which is the same as no menu. + ## Keyboard layout `keyboard.layout`, `keyboard.variant`, module `keyboard-layout`. diff --git a/flake.nix b/flake.nix index c25d0f2..2bb6eed 100644 --- a/flake.nix +++ b/flake.nix @@ -14,6 +14,7 @@ modules = { session = ./modules/session.nix; portal = ./modules/portal.nix; + applications-menu = ./modules/applications-menu.nix; keyboard-layout = ./modules/keyboard-layout.nix; vr-keyboard-extra-keys = ./modules/vr-keyboard-extra-keys.nix; vr-keyboard = ./modules/vr-keyboard.nix; @@ -65,8 +66,10 @@ # Tests of the VR keyboard (text model, corrector, swipe decoder on the # default German + English dictionary), the Jellyfin mpv shim, the - # Firefox wrapper, the launchers and install.sh cleanup: nix flake check + # Firefox wrapper, the launchers, install.sh cleanup and the + # applications.menu link: nix flake check checks = forSystems (pkgs: { + applications-menu = import ./modules/applications-menu/check.nix { inherit pkgs; }; cleanup = import ./modules/cleanup/check.nix { inherit pkgs; }; firefox = import ./modules/firefox/check.nix { inherit pkgs; }; jellyfin = import ./modules/jellyfin/check.nix { inherit pkgs; }; diff --git a/modules/applications-menu.nix b/modules/applications-menu.nix new file mode 100644 index 0000000..01ff08e --- /dev/null +++ b/modules/applications-menu.nix @@ -0,0 +1,27 @@ +# Workaround (SteamOS 0.3.0, build 20260922): KDE apps build their app +# database (ksycoca) from "applications.menu", but SteamOS only ships +# /etc/xdg/menus/plasma-applications.menu. The nested desktop sets +# XDG_MENU_PREFIX=plasma-, the Steam session doesn't, so KDE apps started +# there (Dolphin from the "+" menu) know no apps. We link the user's +# applications.menu to Plasma's. A missing host file leaves a dangling link, +# which KDE treats like no file. Remove once the Steam session sets the prefix. +{ config, lib, ... }: +let + sys = "/etc/xdg/menus/plasma-applications.menu"; +in { + imports = [ ./cleanup.nix ]; + + options.steamFrame.session.applicationsMenu.enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Link `~/.config/menus/applications.menu` to Plasma's menu, so KDE apps + in the Steam session find the installed apps. + ''; + }; + + config = lib.mkIf config.steamFrame.session.applicationsMenu.enable { + xdg.configFile."menus/applications.menu".source = + config.lib.file.mkOutOfStoreSymlink sys; + }; +} diff --git a/modules/applications-menu/check.nix b/modules/applications-menu/check.nix new file mode 100644 index 0000000..d7a9710 --- /dev/null +++ b/modules/applications-menu/check.nix @@ -0,0 +1,31 @@ +# Evaluates the applications-menu module against a stub of Home Manager's +# options: on by default the link to Plasma's menu is generated, disabled it +# is absent. +{ pkgs }: +let + inherit (pkgs) lib; + eval = cfg: (lib.evalModules { + modules = [ + ../applications-menu.nix + { + options.xdg.configFile = lib.mkOption { + type = lib.types.attrsOf (lib.types.attrsOf lib.types.anything); + default = { }; + }; + options.lib = lib.mkOption { type = lib.types.attrsOf lib.types.anything; }; + config = { + _module.check = false; # Home Manager options the stub doesn't declare + _module.args.pkgs = pkgs; + lib.file.mkOutOfStoreSymlink = p: "out-of-store:${p}"; + }; + } + cfg + ]; + }).config.xdg.configFile; + on = eval { }; + off = eval { steamFrame.session.applicationsMenu.enable = false; }; +in +assert on."menus/applications.menu".source + == "out-of-store:/etc/xdg/menus/plasma-applications.menu"; +assert !(off ? "menus/applications.menu"); +pkgs.runCommand "applications-menu-check" { } "touch $out" diff --git a/template/home.nix b/template/home.nix index f6a0e99..56a79fa 100644 --- a/template/home.nix +++ b/template/home.nix @@ -13,7 +13,8 @@ # home.packages = with pkgs; [ htop ripgrep ]; # Steam Frame fixes, see https://github.com/lhns/steam-frame-nix - # (session.portalFix and clipboardSync are on by default). + # (session.portalFix, session.applicationsMenu and clipboardSync are on + # by default). # steamFrame = { # keyboard.layout = "de"; # XKB layout, Steam session # keyboard.vr.extraKeys.enable = true; # Esc/Ctrl/Alt/arrows in VR