at 25.11-pre 4.7 kB view raw
1# INTEGRATION NOTES: 2# Buffyboard integrates as a virtual device in /dev/input 3# which reads touch or pointer events from other input devices 4# and generates events based on where those map to the keys it renders to the framebuffer. 5# 6# Buffyboard generates these events whether or not its onscreen keyboard is actually visible. 7# Hence special care is needed if running anything which claims ownership of the display (such as a desktop environment), 8# to avoid unwanted input events being triggered during normal desktop operation. 9# 10# Desktop users are recommended to either: 11# 1. Stop buffyboard once your DE is started. 12# e.g. `services.buffyboard.unitConfig.Conflicts = [ "my-de.service" ];` 13# 2. Configure your DE to ignore input events from buffyboard (product-id=25209; vendor-id=26214; name=rd) 14# e.g. `echo 'input "26214:25209:rd" events disabled' > ~/.config/sway/config` 15 16{ 17 config, 18 lib, 19 pkgs, 20 utils, 21 ... 22}: 23let 24 cfg = config.services.buffyboard; 25 ini = pkgs.formats.ini { }; 26in 27{ 28 meta.maintainers = with lib.maintainers; [ colinsane ]; 29 30 options = { 31 services.buffyboard = with lib; { 32 enable = mkEnableOption "buffyboard framebuffer keyboard (on-screen keyboard)"; 33 package = mkPackageOption pkgs "buffybox" { }; 34 35 extraFlags = mkOption { 36 type = types.listOf types.str; 37 default = [ ]; 38 description = '' 39 Extra CLI arguments to pass to buffyboard. 40 ''; 41 example = [ 42 "--geometry=1920x1080@640,0" 43 "--dpi=192" 44 "--rotate=2" 45 "--verbose" 46 ]; 47 }; 48 49 configFile = mkOption { 50 type = lib.types.path; 51 default = ini.generate "buffyboard.conf" (lib.filterAttrsRecursive (_: v: v != null) cfg.settings); 52 defaultText = lib.literalExpression ''ini.generate "buffyboard.conf" cfg.settings''; 53 description = '' 54 Path to an INI format configuration file to provide Buffyboard. 55 By default, this is generated from whatever you've set in `settings`. 56 If specified manually, then `settings` is ignored. 57 58 For an example config file see [here](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/blob/master/buffyboard/buffyboard.conf) 59 ''; 60 }; 61 62 settings = mkOption { 63 description = '' 64 Settings to include in /etc/buffyboard.conf. 65 Every option here is strictly optional: 66 Buffyboard will use its own baked-in defaults for those options left unset. 67 ''; 68 type = types.submodule { 69 freeformType = ini.type; 70 71 options.input.pointer = mkOption { 72 type = types.nullOr types.bool; 73 default = null; 74 description = '' 75 Enable or disable the use of a hardware mouse or other pointing device. 76 ''; 77 }; 78 options.input.touchscreen = mkOption { 79 type = types.nullOr types.bool; 80 default = null; 81 description = '' 82 Enable or disable the use of the touchscreen. 83 ''; 84 }; 85 86 options.theme.default = mkOption { 87 type = types.either types.str ( 88 types.enum [ 89 null 90 "adwaita-dark" 91 "breezy-dark" 92 "breezy-light" 93 "nord-dark" 94 "nord-light" 95 "pmos-dark" 96 "pmos-light" 97 ] 98 ); 99 default = null; 100 description = '' 101 Selects the default theme on boot. Can be changed at runtime to the alternative theme. 102 ''; 103 }; 104 options.quirks.fbdev_force_refresh = mkOption { 105 type = types.nullOr types.bool; 106 default = null; 107 description = '' 108 If true and using the framebuffer backend, this triggers a display refresh after every draw operation. 109 This has a negative performance impact. 110 ''; 111 }; 112 }; 113 default = { }; 114 }; 115 }; 116 }; 117 118 config = lib.mkIf cfg.enable { 119 systemd.packages = [ cfg.package ]; 120 systemd.services.buffyboard = { 121 # upstream provides the service (including systemd hardening): we just configure it to start by default 122 # and override ExecStart so as to optionally pass extra arguments 123 serviceConfig.ExecStart = [ 124 "" # clear default ExecStart 125 (utils.escapeSystemdExecArgs ( 126 [ 127 (lib.getExe' cfg.package "buffyboard") 128 "--config-override" 129 cfg.configFile 130 ] 131 ++ cfg.extraFlags 132 )) 133 ]; 134 wantedBy = [ "getty.target" ]; 135 before = [ "getty.target" ]; 136 }; 137 }; 138}