Repository: nix-community/home-manager
Pull request #5930: espanso: add wayland support
Author: login: phanirithvij
Created: 2024-10-04T17:06:59Z | Merged: 2025-04-27T16:36:10Z

Tested on
- kde plasma x11 
- kde plasma wayland
- niri wm (wayland)
- xfce (x11)


Diff:
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index b0ce1549bbfb..c42d27480c23 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -62,7 +62,7 @@ let
     let
       imported = import (./news + "/${newsFile}");
     in
-    if builtins.isFunction imported then imported { inherit pkgs; } else imported
+    if builtins.isFunction imported then imported { inherit config lib pkgs; } else imported
   ) newsFiles;
 in
 {
diff --git a/modules/misc/news/2025-04-26_18-56-13.nix b/modules/misc/news/2025-04-26_18-56-13.nix
new file mode 100644
index 000000000000..645deb50131f
--- /dev/null
+++ b/modules/misc/news/2025-04-26_18-56-13.nix
@@ -0,0 +1,11 @@
+{ pkgs, config, ... }:
+{
+  time = "2025-04-26T13:26:13+00:00";
+  condition = pkgs.hostPlatform.isLinux && config.services.espanso.enable;
+  message = ''
+    `services.espanso` now supports wayland.
+    This is enabled by default on Linux as `services.espanso.waylandSupport = true;`.
+    Depending on your graphical session type, you may disable one of `services.espanso.x11Support` and `services.espanso.waylandSupport` to reduce the closure size of espanso on your system.
+    Both x11 and wayland versions come enabled by default on Linux.
+  '';
+}
diff --git a/modules/services/espanso.nix b/modules/services/espanso.nix
index 324ccfaf9c7d..b4df0e3be2da 100644
--- a/modules/services/espanso.nix
+++ b/modules/services/espanso.nix
@@ -7,6 +7,7 @@
 let
   inherit (lib)
     mkOption
+    mkPackageOption
     mkEnableOption
     mkIf
     maintainers
@@ -16,9 +17,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
+    else if isLinux && cfg.waylandSupport then
+      cfg.package-wayland
+    else
+      cfg.package;
+
   yaml = pkgs.formats.yaml { };
 in
 {
@@ -34,6 +51,7 @@ in
     maintainers.bobvanderlinden
     lib.hm.maintainers.liyangau
     maintainers.n8henrie
+    maintainers.phanirithvij
   ];
   options = {
     services.espanso = {
@@ -46,6 +64,29 @@ in
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland =
+        mkPackageOption pkgs "espanso-wayland" {
+          nullable = true;
+          extraDescription = "Which `espanso` package to use when running under wayland.";
+        }
+        // {
+          default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else null;
+        };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = "`true` on linux";
+      };
+
+      waylandSupport = mkOption {
+        type = types.bool;
+        description = "Whether to enable wayland support on linux";
+        default = isLinux;
+        defaultText = "`true` on linux";
+      };
+
       configs = mkOption {
         type = yaml.type;
         default = {
@@ -125,9 +166,16 @@ in
           The services.espanso module only supports Espanso version 2 or later.
         '';
       }
+      {
+        assertion = isLinux -> (cfg.x11Support || cfg.waylandSupport);
+        message = ''
+          In services.espanso at least one of x11 or wayland support must be enabled on linux.
+        '';
+      }
     ];
 
-    home.packages = [ cfg.package ];
+    # conflicting to have cfg.package and cfg.package-wayland
+    home.packages = [ package-bin ];
 
     xdg.configFile =
       let
@@ -151,7 +199,7 @@ in
         Description = "Espanso: cross platform text expander in Rust";
       };
       Service = {
-        ExecStart = "${cfg.package}/bin/espanso launcher";
+        ExecStart = "${lib.meta.getExe package-bin} launcher";
         Restart = "on-failure";
         RestartSec = 3;
       };
diff --git a/tests/modules/services/espanso/basic-configuration.nix b/tests/modules/services/espanso/basic-configuration.nix
index 07a72ca8d3b6..e5bd516b40c6 100644
--- a/tests/modules/services/espanso/basic-configuration.nix
+++ b/tests/modules/services/espanso/basic-configuration.nix
@@ -1,3 +1,6 @@
+espansoExtraArgs:
+{ config, ... }:
+
 {
   services.espanso = {
     enable = true;
@@ -42,12 +45,18 @@
         ];
       };
     };
-  };
+  } // espansoExtraArgs;
 
   nmt.script = ''
     serviceFile=home-files/.config/systemd/user/espanso.service
+    expectedServiceFile=${./basic-configuration.service}
     assertFileExists "$serviceFile"
-    assertFileContent "$serviceFile" ${./basic-configuration.service}
+    # ensure espanso is in ExecStart
+    assertFileRegex "$serviceFile" 'ExecStart=.*/bin/espanso launcher'
+    # rest of the file should be identical
+    grep -v "/bin/espanso launcher" "$(_abs $serviceFile)" > espanso-service.actual
+    grep -v "/bin/espanso launcher" "$expectedServiceFile" > espanso-service.expected
+    assertFileContent "$(realpath espanso-service.actual)" espanso-service.expected
 
     configFile=home-files/.config/espanso/config/default.yml
     assertFileExists "$configFile"
diff --git a/tests/modules/services/espanso/default.nix b/tests/modules/services/espanso/default.nix
index 5df5fa3f1bd9..81a6c7909290 100644
--- a/tests/modules/services/espanso/default.nix
+++ b/tests/modules/services/espanso/default.nix
@@ -1 +1,11 @@
-{ espanso-basic-configuration = ./basic-configuration.nix; }
+{
+  espanso-basic-configuration = import ./basic-configuration.nix { };
+  espanso-basic-configuration-wayland = import ./basic-configuration.nix {
+    waylandSupport = true;
+    x11Support = false;
+  };
+  espanso-basic-configuration-x11 = import ./basic-configuration.nix {
+    waylandSupport = false;
+    x11Support = true;
+  };
+}


Reviews:
user: login: lucasew
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T22:11:50Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T01:50:48Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T04:16:59Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T06:46:46Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T13:55:22Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:04:42Z
user: login: n8henrie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-27T14:13:14Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T14:19:58Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:20:39Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:24:15Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T14:31:29Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:38:06Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:43:06Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T14:46:57Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T14:49:27Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T14:55:08Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T14:57:29Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T15:00:59Z
user: login: phanirithvij
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T15:02:49Z
user: login: khaneliman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T15:05:06Z
user: login: khaneliman
body: While combing through again, was wondering if we could simplify even further... Would it be a better UX to just have the 2 package options and not use the `support` options. We default there to be a wayland package enabled for linux users and then can just null it out when they don't need that support. This way, we can decide to use the wrapper when both package options are set and disabling either of them indicates support. 

`package-bin` would be simplified to just checking what package options are set

- both set, we create the script to check for WAYLAND_DISPLAY
- wayland only set, just pass that package
- package only set, just pass that package
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T15:18:46Z
user: login: zowoq
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-29T01:49:37Z
user: login: n8henrie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-04T03:51:35Z
user: login: zowoq
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-04T04:15:03Z
user: login: n8henrie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-04T04:16:18Z

Review comments:
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
+    else if isLinux && cfg.waylandSupport then
+      cfg.package-wayland
path: modules/services/espanso.nix
user: login: phanirithvij
body: Missed this previously. without it, it's not possible for the user to override `package-wayland` but it worked (tests passed) because the default was still correct (espanso on darwin and espanso-wayland on linux).
created_at: 2025-04-27T01:50:48Z
author_association: MEMBER
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: khaneliman
body: This makes no sense, to me. We already have a package option. You can change the desired package there. 
created_at: 2025-04-27T04:13:22Z
author_association: COLLABORATOR
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: khaneliman
body: Why do we need to create a script to choose which binary to launch? Just set the package you want and just use it. 
created_at: 2025-04-27T04:14:35Z
author_association: COLLABORATOR
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
path: modules/services/espanso.nix
user: login: khaneliman
body: Would make more sense, to me, to keep the safe default and show the `espanso-wayland` package as an example alternative. 
created_at: 2025-04-27T04:16:51Z
author_association: COLLABORATOR
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: phanirithvij
body: what would be your suggestion, for espanso to seamlessly work on both x11 and wayland by default?
Say If I switch from kde plasma x11 to wayland by logging out and logging in. or any two desktop environments, x11 to wayland for that matter

see also my above https://github.com/nix-community/home-manager/pull/5930#issuecomment-2394976953
created_at: 2025-04-27T06:46:46Z
author_association: MEMBER
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: khaneliman
body: `espanso-wayland` doesn't run on X11? 
created_at: 2025-04-27T13:55:22Z
author_association: COLLABORATOR
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: phanirithvij
body: No
created_at: 2025-04-27T14:04:42Z
author_association: MEMBER
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: n8henrie
body: > espanso-wayland doesn't run on X11?

The `espanso` crate's `wayland` feature activates different logic for reading keyboard input.
created_at: 2025-04-27T14:13:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: khaneliman
body: Hmm.. just feels like a lot of module options for a niche case of someone not committing to wayland or x11... 
Could change the example to be the script here, really...


created_at: 2025-04-27T14:19:58Z
author_association: COLLABORATOR
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: phanirithvij
body: This is to customise the wayland version of the package, say a patched version of espanso-wayland.
created_at: 2025-04-27T14:20:39Z
author_association: MEMBER
diff_hunk: @@ -125,9 +163,16 @@ in
           The services.espanso module only supports Espanso version 2 or later.
         '';
       }
+      {
+        assertion = isLinux -> (cfg.x11Support || cfg.waylandSupport);
+        message = ''
+          In services.espanso at least one of x11 or wayland support must be enabled on linux.
+        '';
+      }
path: modules/services/espanso.nix
user: login: khaneliman
body: This isn't true, is it? You have a if else condition that falls back to the original behavior of using the normal package. 
created_at: 2025-04-27T14:23:12Z
author_association: COLLABORATOR
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
+      };
+
+      waylandSupport = mkOption {
+        type = types.bool;
+        description = "Whether to enable wayland support on linux";
+        default = isLinux;
path: modules/services/espanso.nix
user: login: khaneliman
body: This will cause all linux users to unknowingly have a wayland package, all of a sudden. But, it does seem like a well intentioned change after the previous discussion. 
created_at: 2025-04-27T14:24:05Z
author_association: COLLABORATOR
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: phanirithvij
body: It allows anyone to run espanso by default is how I would look at it, without doing any debugging on why the espanso service is not starting/failing.
created_at: 2025-04-27T14:24:15Z
author_association: MEMBER
diff_hunk: @@ -16,9 +16,25 @@ let
     versionAtLeast
     ;
 
+  inherit (pkgs.stdenv.hostPlatform) isDarwin isLinux;
+
   cfg = config.services.espanso;
   espansoVersion = cfg.package.version;
 
+  package-bin =
+    if isLinux && cfg.x11Support && cfg.waylandSupport then
+      pkgs.writeShellScriptBin "espanso" ''
+        if [ -n "$WAYLAND_DISPLAY" ]; then
+          ${lib.meta.getExe cfg.package-wayland} "$@"
+        else
+          ${lib.meta.getExe cfg.package} "$@"
+        fi
+      ''
path: modules/services/espanso.nix
user: login: khaneliman
body: That's fair.. just wanted to challenge the ideas here because it feels very weird. 
created_at: 2025-04-27T14:28:11Z
author_association: COLLABORATOR
diff_hunk: @@ -125,9 +163,16 @@ in
           The services.espanso module only supports Espanso version 2 or later.
         '';
       }
+      {
+        assertion = isLinux -> (cfg.x11Support || cfg.waylandSupport);
+        message = ''
+          In services.espanso at least one of x11 or wayland support must be enabled on linux.
+        '';
+      }
path: modules/services/espanso.nix
user: login: phanirithvij
body: If the user (accidentally?) sets both to be false then it is better to advice the user, it makes no sense to disable both x11 and wayland.

If we wish to remove this warning. The overall expression does default to the wayland version if both are set to false. (`cfg.package` resolves to `pkgs.espanso-wayland` and `package-bin` resolves to `cfg.package`)

 but I think it is best to leave it in because its an invalid state.
created_at: 2025-04-27T14:38:06Z
author_association: MEMBER
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
+      };
+
+      waylandSupport = mkOption {
+        type = types.bool;
+        description = "Whether to enable wayland support on linux";
+        default = isLinux;
path: modules/services/espanso.nix
user: login: phanirithvij
body: I added an explaination in the news entry describing this. 

Yeah, this is needed for the service to start properly. Is there a better way to communicate to users that `waylandSupport` needs to be decided on without breaking eval?

maybe `lib.warnIf waylandSupport == null "services.espanso.waylandSupport needs to be set to either true or false"`
created_at: 2025-04-27T14:43:06Z
author_association: MEMBER
diff_hunk: @@ -125,9 +163,16 @@ in
           The services.espanso module only supports Espanso version 2 or later.
         '';
       }
+      {
+        assertion = isLinux -> (cfg.x11Support || cfg.waylandSupport);
+        message = ''
+          In services.espanso at least one of x11 or wayland support must be enabled on linux.
+        '';
+      }
path: modules/services/espanso.nix
user: login: khaneliman
body: This isn't a warning, it's an assertion. Which means the eval cannot continue, but there's no reason for it not to since we handle the configuration fine. If both new options are set to false, it should default to the legacy behavior and issue a warning, imo. 
created_at: 2025-04-27T14:46:57Z
author_association: COLLABORATOR
diff_hunk: @@ -125,9 +163,16 @@ in
           The services.espanso module only supports Espanso version 2 or later.
         '';
       }
+      {
+        assertion = isLinux -> (cfg.x11Support || cfg.waylandSupport);
+        message = ''
+          In services.espanso at least one of x11 or wayland support must be enabled on linux.
+        '';
+      }
path: modules/services/espanso.nix
user: login: phanirithvij
body: yeah meant to say assertion. and since it is an invalid state to be in: disabling both x11 and wayland support IF we are on linux. then better to break eval instead of silently handling it to be x11 and breaking it silently again for wayland users.
created_at: 2025-04-27T14:49:27Z
author_association: MEMBER
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
+      };
+
+      waylandSupport = mkOption {
+        type = types.bool;
+        description = "Whether to enable wayland support on linux";
+        default = isLinux;
path: modules/services/espanso.nix
user: login: khaneliman
body: > I added an explaination in the news entry describing this.

The news entry will only be seen by those who use that functionality, though. Which, I don't know how many actually do.. 

>Yeah, this is needed for the service to start properly. Is there a better way to communicate to users that waylandSupport needs to be decided on without breaking eval?
>
>maybe lib.warnIf waylandSupport == null "services.espanso.waylandSupport needs to be set to either true or false"

Since this is all new confguration, I don't see why we would force users to have to change their configuration to silence a warning that might not apply to them. But, without checking against all the possible wayland platforms enabled, I'm not sure of a better way to gracefully enable it for those who might expect it to work...
created_at: 2025-04-27T14:55:08Z
author_association: COLLABORATOR
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: khaneliman
body: I think this should just be strictly a default of `espanso-wayland`, at least. Makes no sense for the wayland package to not be wayland compatible by default, ever. 
created_at: 2025-04-27T14:57:29Z
author_association: COLLABORATOR
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: phanirithvij
body: yes these `default` conditions for both `package` and `package-wayland` are actually redundant I realised. the package-bin does handle all of them.
created_at: 2025-04-27T15:00:59Z
author_association: MEMBER
diff_hunk: @@ -42,10 +59,31 @@ in
       package = mkOption {
         type = types.package;
         description = "Which espanso package to use";
-        default = pkgs.espanso;
+        default = if isDarwin || cfg.x11Support then pkgs.espanso else pkgs.espanso-wayland;
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else pkgs.espanso;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: phanirithvij
body: removed these conditions
created_at: 2025-04-27T15:02:49Z
author_association: MEMBER
diff_hunk: @@ -46,6 +63,27 @@ in
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkOption {
+        type = types.package;
+        description = "Which espanso package to use when running under wayland on linux";
+        default = pkgs.espanso-wayland;
+        defaultText = literalExpression "pkgs.espanso-wayland";
+      };
path: modules/services/espanso.nix
user: login: khaneliman
body: ```suggestion
      package-wayland = mkPackageOption pkgs "espanso-wayland {
        nullable = true;
        extraDescription = "Which `espanso` package to use when running under wayland.";
      } // { 
        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else null; };
```

We should utilize `mkPackageOption` and perhaps just null it out on darwin, since it never applies. Might require tweaking elsewhere/formatting, though. 
created_at: 2025-04-27T15:05:06Z
author_association: COLLABORATOR
diff_hunk: @@ -46,6 +63,26 @@ in
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkPackageOption pkgs "espanso-wayland {
+        nullable = true;
+        extraDescription = "Which `espanso` package to use when running under wayland.";
+      } // { 
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else null; };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
path: modules/services/espanso.nix
user: login: khaneliman
body: ```suggestion
        defaultText = literalExpression "`true` on linux";
```
created_at: 2025-04-27T15:14:25Z
author_association: COLLABORATOR
diff_hunk: @@ -46,6 +63,26 @@ in
         defaultText = literalExpression "pkgs.espanso";
       };
 
+      package-wayland = mkPackageOption pkgs "espanso-wayland {
+        nullable = true;
+        extraDescription = "Which `espanso` package to use when running under wayland.";
+      } // { 
+        default = if isLinux && cfg.waylandSupport then pkgs.espanso-wayland else null; };
+
+      x11Support = mkOption {
+        type = types.bool;
+        description = "Whether to enable x11 support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
+      };
+
+      waylandSupport = mkOption {
+        type = types.bool;
+        description = "Whether to enable wayland support on linux";
+        default = isLinux;
+        defaultText = literalExpression "enabled on linux";
path: modules/services/espanso.nix
user: login: khaneliman
body: ```suggestion
        defaultText = literalExpression "`true` on linux";
```
created_at: 2025-04-27T15:14:41Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,11 @@
+{ pkgs, config, ... }:
+{
+  time = "2025-04-26T13:26:13+00:00";
+  condition = pkgs.hostPlatform.isLinux && config.services.espanso.enable;
path: modules/misc/news/2025-04-26_18-56-13.nix
user: login: zowoq
body: `pkgs.hostPlatform` is an alias. https://github.com/nix-community/home-manager/pull/6931
created_at: 2025-04-29T01:49:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,11 @@
+{ pkgs, config, ... }:
+{
+  time = "2025-04-26T13:26:13+00:00";
+  condition = pkgs.hostPlatform.isLinux && config.services.espanso.enable;
path: modules/misc/news/2025-04-26_18-56-13.nix
user: login: n8henrie
body: @zowoq for my learning, why is using an alias a problem here? Actually, NM -- looks like that's made pretty clear [here](https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/aliases.nix). Did you pick this up just from memory? Or is there a linter or something that might help me notice this going forward?
created_at: 2025-05-04T03:51:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,11 @@
+{ pkgs, config, ... }:
+{
+  time = "2025-04-26T13:26:13+00:00";
+  condition = pkgs.hostPlatform.isLinux && config.services.espanso.enable;
path: modules/misc/news/2025-04-26_18-56-13.nix
user: login: zowoq
body: nixpkgs has an [allowAliases](https://github.com/NixOS/nixpkgs/blob/88b87b7a62ef7c1c70510097f01f656a428d293e/pkgs/top-level/config.nix#L86) option.
created_at: 2025-05-04T04:15:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,11 @@
+{ pkgs, config, ... }:
+{
+  time = "2025-04-26T13:26:13+00:00";
+  condition = pkgs.hostPlatform.isLinux && config.services.espanso.enable;
path: modules/misc/news/2025-04-26_18-56-13.nix
user: login: n8henrie
body: Thanks!
created_at: 2025-05-04T04:16:18Z
author_association: CONTRIBUTOR

PR comments:
user: login: phanirithvij
created_at: 2024-10-05T08:16:50Z
body: One thing is clear, for it to work seamlessly without explicitly requiring user to choose wayland or x11 the only solution is the upstream espanso package should provide a `fat` binary (not possible currently).

In this pr the fat binary is `package-bin` which brings in both the verisons of espanso (x11, wayland) into the store. If and only if both are enabled.

But I guess on darwin there is no such thing as wayland and thus the `pkgs.espanso` should be chosen always. (edit: made the change, someone with darwin system can try it out)

more things to consider
- [x] tty (using espanso makes no sense in a tty, I think)
- [x] override wayland package fix
- [x] ~shell completions, for the 'fat' binary~ idk how to do that
- [x] update news.nix

author_association: MEMBER
user: login: phanirithvij
created_at: 2024-10-16T04:41:50Z
body: so I've tried `espanso-wayland = callPackage ../applications/office/espanso { ...; x11 = false; wayland = true; };` in own nixpkgs instance instead of using override and got
```shell
$ nix build .#test-espanso-basic-configuration
> --- actual
> +++ expected
> @@ -2,7 +2,7 @@
>  WantedBy=default.target
>
> [Service]
> -ExecStart=/nix/store/nq21hfj3v74hd640ggzvmdd2zgmqv51y-espanso/bin/espanso daemon
> +ExecStart=@espanso@/bin/espanso daemon
> Restart=on-failure
```

`nq21hfj3v74hd640ggzvmdd2zgmqv51y-espanso/bin/espanso` here is the `package-bin` script, and `@espanso@` seems to be the pkgs.espanso?
author_association: MEMBER
user: login: phanirithvij
created_at: 2024-10-16T17:06:32Z
body: Fixed the test (with the `@espanso@` stub) but I don't know how to fix the `espanso.override attribute missing` error.
author_association: MEMBER
user: login: phanirithvij
created_at: 2024-10-21T03:42:13Z
body: @rycee I need some help, please have a look at it when you're free.

```shell
$ nix build .#test-espanso-basic-configuration
error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:34:12:
           33|
           34|   strict = derivationStrict drvAttrs;
             |            ^
           35|

       … while evaluating derivation 'nmt-test-espanso-basic-configuration'
         whose name attribute is located at /nix/store/riqkpszjqk02bi1wppfg8ip5xvh102qd-source/pkgs/stdenv/generic/make-derivation.nix:336:7

       … while evaluating attribute 'buildCommand' of derivation 'nmt-test-espanso-basic-configuration'
         at /nix/store/riqkpszjqk02bi1wppfg8ip5xvh102qd-source/pkgs/build-support/trivial-builders/default.nix:59:17:
           58|         enableParallelBuilding = true;
           59|         inherit buildCommand name;
             |                 ^
           60|         passAsFile = [ "buildCommand" ]

       … while evaluating the option `home.activation.installPackages.data':

       … while evaluating definitions from `/nix/store/vv3xqpi8hwcciy7labjysw3s6qwafch4-source/modules/home-environment.nix':

       … while evaluating the option `services.espanso.package-wayland':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: attribute 'override' missing
       at /nix/store/riqkpszjqk02bi1wppfg8ip5xvh102qd-source/pkgs/top-level/all-packages.nix:4857:21:
         4856|   };
         4857|   espanso-wayland = espanso.override {
             |                     ^
         4858|     x11Support = false;
```
author_association: MEMBER
user: login: stale[bot]
created_at: 2025-03-08T16:22:34Z
body: <p>
  Thank you for your contribution!
  I marked this pull request as stale due to inactivity.
  <b>Please read the relevant sections below before commenting.</b>
</p>

<details>
<summary><b>If you are the original author of the PR</b></summary>
<p>

* GitHub sometimes doesn't notify people who commented / reviewed a PR previously when you (force) push commits. *If you have addressed the reviews* you can [officially ask for a review](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from those who commented to you or anyone else.
* If it is unfinished but you plan to finish it, please mark it as a draft.
* If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work.
* To get things rolling again, rebase the PR against the target branch and address valid comments.

</p>
</details>

<details>
<summary><b>If you are <i>not</i> the original author of the PR</b></summary>
<p>

* If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR.

</p>
</details>

author_association: NONE
user: login: phanirithvij
created_at: 2025-03-11T18:42:33Z
body: still plan to work on this, but need some help with the above.
author_association: MEMBER
user: login: phanirithvij
created_at: 2025-04-26T11:51:41Z
body: The eval error was fixed in 7a3f0b3b8df1b913890f5fad04d34f2af91da858 no clue where in that commit exactly (git bisect on home-manger)
author_association: MEMBER
user: login: phanirithvij
created_at: 2025-04-26T14:02:51Z
body: @n8henrie @lucasew @liyangau @bobvanderlinden 
author_association: MEMBER
user: login: phanirithvij
created_at: 2025-04-27T15:56:10Z
body: this is how the UX looks like as of now.

```nix
services.espanso.enable = true;
services.espanso = {
    enable = true;
    waylandSupport = false;
};
services.espanso = {
    enable = true;
    x11Support = false;
};
```

Let me know if I misunderstood something but you're suggesting it to be

```nix
services.espanso.enable = true; # UNCHANGED
services.espanso = {
    enable = true;
    package = null;
};
services.espanso = {
    enable = true;
    package-wayland = null;
};
```

is that right?

if so I'd prefer the first one because I can tell right away what's happening. (and those support option names are the same in `espanso` package derivation in nixpkgs)
author_association: MEMBER
user: login: khaneliman
created_at: 2025-04-27T16:36:04Z
body: Alright, sounds good. Annoying you have to do all this just because of their packaging/runtime issues. 
author_association: COLLABORATOR