-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow using deckbd for password entry during boot #382
base: development
Are you sure you want to change the base?
Changes from all commits
3fc4839
8e5a896
ea55d82
377912d
77b2876
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,105 @@ | ||||||||
{ config, lib, pkgs, utils, ... }: | ||||||||
|
||||||||
let | ||||||||
cfg = config.jovian.devices.steamdeck; | ||||||||
in | ||||||||
{ | ||||||||
options = { | ||||||||
jovian.devices.steamdeck = { | ||||||||
fde = { | ||||||||
deckbd = { | ||||||||
enable = lib.mkOption { | ||||||||
default = cfg.enable; | ||||||||
defaultText = lib.literalExpression "config.jovian.devices.steamdeck.enable"; | ||||||||
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, good thing I'm testing on my system, I missed this. This can't be enabled by default. It should be considered an opt-in option from the end-user. Especially since it changes the existing semantics of the gamepad during boot.
Suggested change
(And also because it will cause a sudden |
||||||||
type = lib.types.bool; | ||||||||
description = '' | ||||||||
Whether to enable deckbd for initrd password entry. | ||||||||
|
||||||||
You must hold the menu button (≡) for a second before entering | ||||||||
your password. | ||||||||
''; | ||||||||
}; | ||||||||
bindsTo = lib.mkOption { | ||||||||
inherit (utils.systemdUtils.unitOptions.commonUnitOptions.options.bindsTo) type; | ||||||||
description = '' | ||||||||
systemd units that require deckbd. | ||||||||
|
||||||||
For example, if you want controller input in unl0kr, add `config.boot.initrd.systemd.services.unl0kr-ask-password.name`. | ||||||||
|
||||||||
Plymouth and the console work by default. | ||||||||
''; | ||||||||
}; | ||||||||
debug = lib.mkOption { | ||||||||
default = false; | ||||||||
type = lib.types.bool; | ||||||||
description = '' | ||||||||
Enable debug output for deckbd. | ||||||||
|
||||||||
This will log keycodes to the journal. | ||||||||
''; | ||||||||
}; | ||||||||
}; | ||||||||
}; | ||||||||
}; | ||||||||
}; | ||||||||
|
||||||||
config = lib.mkMerge [ | ||||||||
(lib.mkIf cfg.fde.deckbd.enable { | ||||||||
assertions = [ | ||||||||
{ | ||||||||
assertion = cfg.enableDefaultStage1Modules; | ||||||||
message = '' | ||||||||
deckbd cannot be used without the required kernel modules. | ||||||||
|
||||||||
jovian.devices.steamdeck.enableDefaultStage1Modules must be enabled. | ||||||||
''; | ||||||||
} | ||||||||
{ | ||||||||
assertion = config.boot.initrd.systemd.enable; | ||||||||
message = '' | ||||||||
deckbd requires systemd-in-initrd. | ||||||||
|
||||||||
boot.initrd.systemd.enable must be set to true. Note that this may impact other NixOS features. | ||||||||
''; | ||||||||
} | ||||||||
]; | ||||||||
|
||||||||
jovian.devices.steamdeck.fde.deckbd.bindsTo = [ | ||||||||
"systemd-ask-password-console.service" | ||||||||
(lib.mkIf config.boot.plymouth.enable config.systemd.services.systemd-ask-password-plymouth.name) | ||||||||
# Note: Agents that have optional keyboard input, such as unl0kr, should not be added here. The user may not want it. | ||||||||
]; | ||||||||
|
||||||||
boot.initrd = { | ||||||||
kernelModules = [ "uinput" ]; | ||||||||
|
||||||||
services.udev.packages = [ | ||||||||
(pkgs.writeTextDir "lib/udev/rules.d/70-steam-deck-controller.rules" '' | ||||||||
ACTION=="add", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="28de", ENV{ID_MODEL_ID}=="1205", ENV{PRODUCT}=="?*", ENV{ID_INPUT_JOYSTICK}=="1", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/class/input/input_steam_deck_controller" | ||||||||
'') | ||||||||
]; | ||||||||
|
||||||||
systemd = { | ||||||||
storePaths = with pkgs; [ deckbd ]; # https://github.com/NixOS/nixpkgs/issues/309316 | ||||||||
services.deckbd = { | ||||||||
description = "Steam Deck controller keymapper"; | ||||||||
unitConfig.DefaultDependencies = false; | ||||||||
wantedBy = cfg.fde.deckbd.bindsTo; | ||||||||
before = cfg.fde.deckbd.bindsTo; | ||||||||
inherit (cfg.fde.deckbd) bindsTo; | ||||||||
requires = [ "sys-class-input-input_steam_deck_controller.device" ]; | ||||||||
after = [ "sys-class-input-input_steam_deck_controller.device" ]; | ||||||||
path = with pkgs; [ deckbd ]; | ||||||||
environment.G_MESSAGES_DEBUG = lib.mkIf cfg.fde.deckbd.debug "all"; | ||||||||
# Note: The lizard_mode parameter does not work as intended. The | ||||||||
# Steam Deck must also be manually put into gamepad mode by holding | ||||||||
# the menu button (≡) for a second. | ||||||||
preStart = "echo 0 > /sys/module/hid_steam/parameters/lizard_mode"; | ||||||||
script = "deckbd"; | ||||||||
postStop = "echo 1 > /sys/module/hid_steam/parameters/lizard_mode"; | ||||||||
Comment on lines
+94
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've dived into trying to understand why it wouldn't work "as expected". First, here's what the
This comment has aged poorly... That's only true for the original Steam controller... But still has interesting hints as to what is happening. So, here's one reason why it "doesn't work" for the Steam Deck controller: ... Except that this is only about automatically enabling/disabling lizard mode on open. And that's why things gets kinda confusing fast. When the parameter is changed live, this happens: See how there's no check for the hardware in use? So, as long as the device is not opened, the switch will happen... EXCEPT it's not that easy... If the device has been “forced” into gamepad mode, attempting to set it to lizard mode won't work. In turn this is what the (≡) button does; it flips that flag: (Though also notice how if So, to recap, for a steam deck, when the device is registered to the driver, if it was not already opened, it will be out into the mode set by the kernel module parameter: If the device is not opened, changing the kernel module parameter will change the mode of the controller... ... unless it's been “put” into gamepad mode (via the ≡ button) And the last situation where the Did you get all that? :) (I'm still somewhat confused.) |
||||||||
}; | ||||||||
}; | ||||||||
}; | ||||||||
}) | ||||||||
]; | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ in | |
|
||
# Gamepad | ||
"usbhid" | ||
"hid-steam" | ||
]; | ||
boot.initrd.availableKernelModules = [ | ||
"nvme" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ lib | ||
, stdenv | ||
, fetchFromGitHub | ||
, pkg-config | ||
, glib | ||
, libevdev | ||
}: | ||
|
||
stdenv.mkDerivation { | ||
pname = "deckbd"; | ||
version = "0-unstable-2024-07-01"; | ||
|
||
src = fetchFromGitHub { | ||
owner = "Ninlives"; | ||
repo = "deckbd"; | ||
rev = "1d2c71f2c096fbfa42624dd820a9d11a35c64826"; | ||
hash = "sha256-Svp/5Mo/XkiptbTM3E4QhSRxC6rMeF0t3eTq9BUjLbs="; | ||
}; | ||
|
||
nativeBuildInputs = [ pkg-config ]; | ||
|
||
buildInputs = [ glib libevdev ]; | ||
|
||
makeFlags = [ "PREFIX=$(out)" ]; | ||
|
||
meta = { | ||
description = "Steam Deck controller keymapper"; | ||
homepage = "https://github.com/Ninlives/deckbd"; | ||
license = lib.licenses.gpl3Only; | ||
mainProgram = "deckbd"; | ||
platforms = lib.platforms.linux; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... not sure about the
jovian.devices.steamdeck
.fde
.deckbd
namespace...I don't have a suggestion at the exact moment, but it's less directly about FDE, but about a device-specific tool and integration to make FDE work, so maybe it should be categorized as such. 🤔 Any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning was that the launch is directly tied to FDE-related password prompting services. I too can't really think of a better name - I'm open to suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(You don't need to do anything. I'll handle moving the option[s].)
So I've spent a few more minutes thinking about it. I think I know why I found the namespacing off. No options in NixOS uses the
fde
wording, even the word “encryption” isn't used by the NixOS docs around that. (And uuuuh... that's another issue to solve, just an observation.)Now, couple that with this being a device-specific "service". We have a single one at the moment (
jovian.devices.steamdeck.enableGyroDsuService
), and it too I think is somewhat miscategorized. (Side-note, this other option was moved since its inception, and was "grandfathered-in" into thesteamdeck
namespace instead of being globally awkwardly available...)So, what I want is thoughts about my thought:
Let's have
jovian.devices.*.[some word].[tool name].[options]
. I'm not sure if.services
or.tools
or what would be appropriate. Though I think it should encompass things likesdgyrodsu
and other device-specific services.My train of thoughts here is that being for
FDE
is an implementation detail; it's an input device "interceptor" service that is intended for usage in stage-1 for passphrase input. And it's not strictly limited to being a stage-1 tool. While there's no use-case yet, it could be used in the booted system, too, right?.So I suppose the
enable
option might be better described asenableStage1
or/*...*/.deckbd.initrd.enable
or something like that?Sorry if that's a lot of useless stuff to consider / think of, and I know it's pedantry, but I don't want to just declare my pedantry as the way forward, I want to know if I'm missing something, or even if you think I'm wrong :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(side-note: I'll try to get this tested and verified on my system soon, and make it so the last issues are those tiny little details so it can be merged)