GNU bug report logs - #62101
[PATCH] home: services: Add xmodmap.

Previous Next

Package: guix-patches;

Reported by: conses <contact <at> conses.eu>

Date: Fri, 10 Mar 2023 19:59:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 62101 in the body.
You can then email your comments to 62101 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Fri, 10 Mar 2023 19:59:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to conses <contact <at> conses.eu>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Fri, 10 Mar 2023 19:59:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: conses <contact <at> conses.eu>
To: guix-patches <at> gnu.org
Cc: contact <at> conses.eu, Andrew Tropin <andrew <at> trop.in>
Subject: [PATCH] home: services: Add xmodmap.
Date: Fri, 10 Mar 2023 20:57:48 +0100
---
 gnu/home/services/desktop.scm | 109 ++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/gnu/home/services/desktop.scm b/gnu/home/services/desktop.scm
index cb25b03b64..b3c60b017e 100644
--- a/gnu/home/services/desktop.scm
+++ b/gnu/home/services/desktop.scm
@@ -22,10 +22,13 @@ (define-module (gnu home services desktop)
   #:use-module (gnu home services shepherd)
   #:use-module (gnu services configuration)
   #:autoload   (gnu packages glib)    (dbus)
+  #:autoload   (gnu packages xorg) (xmodmap)
   #:autoload   (gnu packages xdisorg) (redshift)
+  #:use-module (guix packages)
   #:use-module (guix records)
   #:use-module (guix gexp)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-43)
   #:use-module (ice-9 match)
   #:export (home-redshift-configuration
             home-redshift-configuration?
@@ -226,3 +229,109 @@ (define home-dbus-service-type
    (default-value (home-dbus-configuration))
    (description
     "Run the session-specific D-Bus inter-process message bus.")))
+
+
+;;;
+;;; xmodmap
+;;;
+
+(define-configuration/no-serialization home-xmodmap-configuration
+  (xmodmap
+   (package xmodmap)
+   "The @code{xmodmap} package to use.")
+  (config
+   (alist '())
+   "Association list of key and value pairs for the
+ @code{xmodmap} configuration file.  Its syntax can take something like
+the following:
+
+@example
+'((#(add mod4) . Print)
+    (clear lock)
+    (clear control)
+    (#(keycode 66) . Control_L)
+    (#(add control) . #(Control_L Control_R)))
+@end example"))
+
+(define (home-xmodmap-shepherd-service config)
+  (list
+   (shepherd-service
+    (provision '(xmodmap))
+    (start #~(make-system-constructor
+              (string-join
+               (list #$(file-append
+                        (home-xmodmap-configuration-xmodmap config)
+                        "/bin/xmodmap")
+                     #$(home-xmodmap-file config)))))
+    (one-shot? #t))))
+
+(define (get-xmodmap-configuration field-name val)
+  (define serialize-term
+    (match-lambda
+      ((? vector? e)
+       (string-join
+        (vector-fold
+         (lambda (i acc e)
+           (append
+             acc
+             (list (serialize-term e))))
+         '() e) " "))
+      ((? symbol? e) (symbol->string e))
+      ((? number? e) (number->string e))
+      (e e)))
+
+  (define serialize-field
+    (match-lambda
+      ((? list? e)
+       (string-join
+        (map
+         (lambda (x)
+           (serialize-term x))
+         e)
+        " "))
+      ((key . value)
+       (format #f "~a = ~a"
+               (serialize-term key)
+               (serialize-term value)))
+      (key (string-append (serialize-term key)))))
+
+  #~(string-append
+     #$@(interpose
+         (map serialize-field val)
+         "\n" 'suffix)))
+
+(define (home-xmodmap-files-service config)
+  `(("xmodmap/config"
+     ,(home-xmodmap-file config))))
+
+(define (home-xmodmap-file config)
+  (mixed-text-file
+   "config"
+   (get-xmodmap-configuration
+    #f (home-xmodmap-configuration-config config))))
+
+(define (home-xmodmap-profile-service config)
+  (list (home-xmodmap-configuration-xmodmap config)))
+
+(define home-xmodmap-service-type
+  (service-type
+   (name 'home-xmodmap)
+   (extensions
+    (list
+     (service-extension
+      home-profile-service-type
+      home-xmodmap-profile-service)
+     (service-extension
+      home-xdg-configuration-files-service-type
+      home-xmodmap-files-service)
+     (service-extension
+      home-shepherd-service-type
+      home-xmodmap-shepherd-service)))
+   (description "Configure @code{xmodmap} bindings and rules.")
+   (default-value (home-xmodmap-configuration))))
+
+(define (generate-home-xmodmap-documentation)
+  (generate-documentation
+   `((home-xmodmap-configuration
+      ,home-xmodmap-configuration-fields))
+   'home-xmodmap-configuration))
-- 
2.39.1



-- 
Best regards,
conses




Information forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Mon, 13 Mar 2023 14:01:01 GMT) Full text and rfc822 format available.

Message #8 received at 62101 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: conses <contact <at> conses.eu>
Cc: Andrew Tropin <andrew <at> trop.in>, 62101 <at> debbugs.gnu.org
Subject: Re: bug#62101: [PATCH] home: services: Add xmodmap.
Date: Mon, 13 Mar 2023 15:00:17 +0100
Hello,

This looks like a useful addition!

Some comments below; maybe Andrew will bring a different perspective.

conses <contact <at> conses.eu> skribis:

> ---
>  gnu/home/services/desktop.scm | 109 ++++++++++++++++++++++++++++++++++

It’d be great if you could provide a ChangeLog-style commit log (you can
check the manual and ‘git log’ to see what it’s like); if you can’t, we
can help with that.

More importantly, could you add documentation to guix.texi, similar to
what is done for the other Home services?  That is: a few introductory
lines, an example, and the reference (data types, variables,
procedures).

> +   (alist '())
> +   "Association list of key and value pairs for the
> + @code{xmodmap} configuration file.  Its syntax can take something like
> +the following:
> +
> +@example
> +'((#(add mod4) . Print)
> +    (clear lock)
> +    (clear control)
> +    (#(keycode 66) . Control_L)
> +    (#(add control) . #(Control_L Control_R)))
> +@end example"))

I don’t quite get the syntax.

Use of vectors is unusual in this context, I’d recommend against it.

Regarding pairs: in some cases, the cdr is a symbol/vector, in other
cases it’s a one-element list (as in ‘(clear lock)’).  That also makes
it a bit confusing to me.

Perhaps we should try to make it look more consistent?  WDYT?

> +(define (home-xmodmap-shepherd-service config)
> +  (list
> +   (shepherd-service
> +    (provision '(xmodmap))
> +    (start #~(make-system-constructor
> +              (string-join
> +               (list #$(file-append
> +                        (home-xmodmap-configuration-xmodmap config)
> +                        "/bin/xmodmap")
> +                     #$(home-xmodmap-file config)))))
> +    (one-shot? #t))))

Perhaps it’d be useful to have a ‘stop’ procedure that undoes that
changes?  In which case it wouldn’t be one-shot anymore.

> +  (define serialize-field
> +    (match-lambda
> +      ((? list? e)
> +       (string-join
> +        (map
> +         (lambda (x)
> +           (serialize-term x))
> +         e)
> +        " "))

Just: (string-join (map serialize-term e)).

> +(define home-xmodmap-service-type
> +  (service-type
> +   (name 'home-xmodmap)
> +   (extensions
> +    (list
> +     (service-extension
> +      home-profile-service-type
> +      home-xmodmap-profile-service)
> +     (service-extension
> +      home-xdg-configuration-files-service-type
> +      home-xmodmap-files-service)
> +     (service-extension
> +      home-shepherd-service-type
> +      home-xmodmap-shepherd-service)))
> +   (description "Configure @code{xmodmap} bindings and rules.")

Please expand the description a bit.

TIA!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Thu, 16 Mar 2023 13:04:02 GMT) Full text and rfc822 format available.

Message #11 received at 62101 <at> debbugs.gnu.org (full text, mbox):

From: conses <contact <at> conses.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: contact <at> conses.eu, 62101 <at> debbugs.gnu.org
Subject: [PATCH v2] home: services: Add home-xmodmap-service-type.
Date: Thu, 16 Mar 2023 14:03:34 +0100
* gnu/home/services/desktop.scm (home-xmodmap-service-type)
(home-xmodmap-configuration): New variables;
(xmodmap-shepherd-service)
(get-xmodmap-configuration)
(get-xmodmap-file)
(add-xmodmap-config-file)
(add-xmodmap-package): New procedures;
* doc/guix.texi (Desktop Services): Document it.
---
 doc/guix.texi                 | 51 +++++++++++++++++++++
 gnu/home/services/desktop.scm | 85 +++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 6671ba9305..c9ec781e8b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -42541,6 +42541,57 @@ Desktop Home Services
 @end table
 @end deftp
 
+@defvar home-xmodmap-service-type
+This is the service type for the
+@uref{https://gitlab.freedesktop.org/xorg/app/xmodmap,xmodmap} utility
+to modify keymaps and pointer button mappings under the Xorg display
+server.  Its associated value must be a
+@code{home-xmodmap-configuration} record, as shown below.
+
+The syntax for the expression grammar is quite straightforward.  You can
+either provide a list of cons cells and strings like this:
+
+@lisp
+(service home-xmodmap-service-type
+         (home-xmodmap-configuration
+          (config '(("add mod4" . "Print")
+                    "clear lock"
+                    "clear control"
+                    ("keycode 66" . "Control_L")
+                    ("add control" . "Control_L Control_R")))))
+@end lisp
+
+Alternatively, there is a more Lisp-like configuration syntax via Scheme
+symbols, lists, and vectors, that you can use like this:
+
+@lisp
+(service home-xmodmap-service-type
+         (home-xmodmap-configuration
+          (config '((#(add mod4) . Print)
+                    (clear lock)
+                    (clear control)
+                    (#(keycode 66) . Control_L)
+                    (#(add control) . #(Control_L Control_R))))))
+@end lisp
+@end defvar
+
+@deftp {Data Type} home-xmodmap-configuration
+The configuration record for @code{home-xmodmap-service-type}.  Its
+available fields are:
+
+@table @asis
+@item @code{xmodmap} (default: @code{xmodmap}) (type: file-like)
+The @code{xmodmap} package to use.
+
+@item @code{config} (default: @code{config}) (type: list)
+The list of expressions to be placed in the
+@file{~/.config/xmodmap/config} configuration file and read on service
+startup.
+
+@end table
+@end deftp
+
+
 @node Guix Home Services
 @subsection Guix Home Services
 
diff --git a/gnu/home/services/desktop.scm b/gnu/home/services/desktop.scm
index cb25b03b64..8bc3d82cba 100644
--- a/gnu/home/services/desktop.scm
+++ b/gnu/home/services/desktop.scm
@@ -22,10 +22,12 @@ (define-module (gnu home services desktop)
   #:use-module (gnu home services shepherd)
   #:use-module (gnu services configuration)
   #:autoload   (gnu packages glib)    (dbus)
+  #:autoload   (gnu packages xorg) (setxkbmap xmodmap)
   #:autoload   (gnu packages xdisorg) (redshift)
   #:use-module (guix records)
   #:use-module (guix gexp)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-43)
   #:use-module (ice-9 match)
   #:export (home-redshift-configuration
             home-redshift-configuration?
@@ -226,3 +228,86 @@ (define home-dbus-service-type
    (default-value (home-dbus-configuration))
    (description
     "Run the session-specific D-Bus inter-process message bus.")))
+
+
+;;;
+;;; xmodmap
+;;;
+
+(define-configuration/no-serialization home-xmodmap-configuration
+  (xmodmap
+   (file-like xmodmap)
+   "The @code{xmodmap} package to use.")
+  (config
+   (list '())
+   "List of expressions to be inserted in the @file{.config/xmodmap/config}
+configuration file."))
+
+(define (xmodmap-shepherd-service config)
+  (list
+   (shepherd-service
+    (provision '(xmodmap))
+    (start #~(make-system-constructor
+              (string-join
+               (list #$(file-append
+                        (home-xmodmap-configuration-xmodmap config)
+                        "/bin/xmodmap")
+                     #$(get-xmodmap-file config)))))
+    (stop #~(make-system-constructor
+             #$(file-append setxkbmap "/bin/setxkbmap")))
+    (documentation "On startup, run @code{xmodmap} and read the expressions in
+the configuration file.  On stop, reset all the mappings back to the
+defaults."))))
+
+(define (get-xmodmap-configuration field-name val)
+  (define serialize-term
+    (match-lambda
+      ((? vector? e)
+       (string-join
+        (vector-fold (lambda (_ acc e)
+                       (append acc (list (serialize-term e))))
+                     '() e)))
+      ((? symbol? e) (symbol->string e))
+      ((? number? e) (number->string e))
+      (e e)))
+
+  (define serialize-field
+    (match-lambda
+      ((? list? e)
+       (string-join (map serialize-term e)))
+      ((key . value)
+       (format #f "~a = ~a" (serialize-term key) (serialize-term value)))
+      (key (string-append (serialize-term key)))))
+
+  #~(string-append
+     #$@(interpose
+         (map serialize-field val)
+         "\n" 'suffix)))
+
+(define (get-xmodmap-file config)
+  (mixed-text-file
+   "config"
+   (get-xmodmap-configuration
+    #f (home-xmodmap-configuration-config config))))
+
+(define (add-xmodmap-config-file config)
+  `(("xmodmap/config"
+     ,(get-xmodmap-file config))))
+
+(define (add-xmodmap-package config)
+  (list (home-xmodmap-configuration-xmodmap config)))
+
+(define home-xmodmap-service-type
+  (service-type
+   (name 'home-xmodmap)
+   (extensions
+    (list
+     (service-extension home-profile-service-type
+                        add-xmodmap-package)
+     (service-extension home-xdg-configuration-files-service-type
+                        add-xmodmap-config-file)
+     (service-extension home-shepherd-service-type
+                        xmodmap-shepherd-service)))
+   (default-value (home-xmodmap-configuration))
+   (description "Run the @code{xmodmap} utility to modify keymaps and pointer
+buttons under the Xorg display server via user-defined expressions.")))
-- 
2.39.1



-- 
Best regards,
conses




Information forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Thu, 16 Mar 2023 13:16:01 GMT) Full text and rfc822 format available.

Message #14 received at 62101 <at> debbugs.gnu.org (full text, mbox):

From: conses <contact <at> conses.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: contact <at> conses.eu, 62101 <at> debbugs.gnu.org
Subject: Re: bug#62101: [PATCH] home: services: Add xmodmap.
Date: Thu, 16 Mar 2023 14:15:32 +0100
Ludovic Courtès <ludo <at> gnu.org> writes:

> It’d be great if you could provide a ChangeLog-style commit log (you can
> check the manual and ‘git log’ to see what it’s like); if you can’t, we
> can help with that.
>

Apologies for missing this, I added it in v2.

> More importantly, could you add documentation to guix.texi, similar to
> what is done for the other Home services?  That is: a few introductory
> lines, an example, and the reference (data types, variables,
> procedures).
>

Likewise.

>> +   (alist '())
>> +   "Association list of key and value pairs for the
>> + @code{xmodmap} configuration file.  Its syntax can take something like
>> +the following:
>> +
>> +@example
>> +'((#(add mod4) . Print)
>> +    (clear lock)
>> +    (clear control)
>> +    (#(keycode 66) . Control_L)
>> +    (#(add control) . #(Control_L Control_R)))
>> +@end example"))
>
> I don’t quite get the syntax.
>
> Use of vectors is unusual in this context, I’d recommend against it.
>
> Regarding pairs: in some cases, the cdr is a symbol/vector, in other
> cases it’s a one-element list (as in ‘(clear lock)’).  That also makes
> it a bit confusing to me.
>
> Perhaps we should try to make it look more consistent?  WDYT?

I've amended the type of config to be of list instead.  As I've hinted
in the manual, the motivation for including vectors and lists is to
provide a more Lisp-like configuration syntax for those that want it, it
can simply take strings too.  IMO there's no point in making it
consistent since the original syntax isn't consistent in the first
place, you can check out some examples here
<https://wiki.archlinux.org/title/xmodmap>.

>
>> +(define (home-xmodmap-shepherd-service config)
>> +  (list
>> +   (shepherd-service
>> +    (provision '(xmodmap))
>> +    (start #~(make-system-constructor
>> +              (string-join
>> +               (list #$(file-append
>> +                        (home-xmodmap-configuration-xmodmap config)
>> +                        "/bin/xmodmap")
>> +                     #$(home-xmodmap-file config)))))
>> +    (one-shot? #t))))
>
> Perhaps it’d be useful to have a ‘stop’ procedure that undoes that
> changes?  In which case it wouldn’t be one-shot anymore.
>

I found here <https://askubuntu.com/a/1155211> that xmodmap settings can
be simply reversed by calling setxkbmap, so I've added a stop procedure
for this.

>> +(define home-xmodmap-service-type
>> +  (service-type
>> +   (name 'home-xmodmap)
>> +   (extensions
>> +    (list
>> +     (service-extension
>> +      home-profile-service-type
>> +      home-xmodmap-profile-service)
>> +     (service-extension
>> +      home-xdg-configuration-files-service-type
>> +      home-xmodmap-files-service)
>> +     (service-extension
>> +      home-shepherd-service-type
>> +      home-xmodmap-shepherd-service)))
>> +   (description "Configure @code{xmodmap} bindings and rules.")
>
> Please expand the description a bit.
>

Done.

-- 
Best regards,
conses




Information forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Thu, 16 Mar 2023 21:45:01 GMT) Full text and rfc822 format available.

Message #17 received at 62101 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: conses <contact <at> conses.eu>
Cc: 62101 <at> debbugs.gnu.org
Subject: Re: bug#62101: [PATCH] home: services: Add xmodmap.
Date: Thu, 16 Mar 2023 22:43:52 +0100
Hi,

conses <contact <at> conses.eu> skribis:

> * gnu/home/services/desktop.scm (home-xmodmap-service-type)
> (home-xmodmap-configuration): New variables;
> (xmodmap-shepherd-service)
> (get-xmodmap-configuration)
> (get-xmodmap-file)
> (add-xmodmap-config-file)
> (add-xmodmap-package): New procedures;
> * doc/guix.texi (Desktop Services): Document it.

Overall LGTM, with minor issues:

> +The syntax for the expression grammar is quite straightforward.  You can
> +either provide a list of cons cells and strings like this:

I’d suggest avoiding the first sentence, because what looks
straightforward to someone might be intimidating to another.  We also
avoid jargon like “cons cell” in the manual.

What about something like this:

  The @code{key-map} field takes a list of objects, each of which is
  either a @dfn{statement} (a string) or an @dfn{assignment} (a pair of
  strings).  As an example, the snippet below configures the @kbd{mod4}
  key (???) such that it does XYZ, FIXME: finish sentence :-)

… where ‘key-map’ is IMO a better name for ‘config’.

> +Alternatively, there is a more Lisp-like configuration syntax via Scheme
> +symbols, lists, and vectors, that you can use like this:
> +
> +@lisp
> +(service home-xmodmap-service-type
> +         (home-xmodmap-configuration
> +          (config '((#(add mod4) . Print)
> +                    (clear lock)

I don’t find it very useful; I’d rather support only one syntax, but
clearly explained.  So my suggestion would be to drop this.

> +@item @code{config} (default: @code{config}) (type: list)

So this would be renamed to @code{key-map} maybe.

> +(define (get-xmodmap-configuration field-name val)

As a rule of thumb, you can drop ‘get-’ from procedure names; procedures
like this one are rarely called ‘get-SOMETHING’.

> +     (service-extension home-profile-service-type
> +                        add-xmodmap-package)

I believe this extension is unnecessary.

Could you send an updated patch?

Thank you!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#62101; Package guix-patches. (Fri, 17 Mar 2023 12:07:02 GMT) Full text and rfc822 format available.

Message #20 received at 62101 <at> debbugs.gnu.org (full text, mbox):

From: conses <contact <at> conses.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: contact <at> conses.eu, 62101 <at> debbugs.gnu.org
Subject: [PATCH v3] home: services: Add home-xmodmap-service-type.
Date: Fri, 17 Mar 2023 13:06:35 +0100
* gnu/home/services/desktop.scm (home-xmodmap-service-type)
(home-xmodmap-configuration): New variables;
(serialize-xmodmap-configuration)
(xmodmap-shepherd-service): New procedures;
* doc/guix.texi (Desktop Services): Document it.
---
- Tweak manual as per latest comments.
- Remove profile and xdg-configuration-file service extensions.
- config -> key-map in home-xmodmap-configuration.
 doc/guix.texi                 | 41 +++++++++++++++++++++++++
 gnu/home/services/desktop.scm | 57 +++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index aa98d7df4b..baa5fb5ea5 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -42587,6 +42587,47 @@ Desktop Home Services
 
 @end deftp
 
+@defvar home-xmodmap-service-type
+This is the service type for the
+@uref{https://gitlab.freedesktop.org/xorg/app/xmodmap,xmodmap} utility
+to modify keymaps and pointer button mappings under the Xorg display
+server.  Its associated value must be a
+@code{home-xmodmap-configuration} record, as shown below.
+
+The @code{key-map} field takes a list of objects, each of which is
+either a @dfn{statement} (a string) or an @dfn{assignment} (a pair of
+strings).  As an example, the snippet below swaps around the
+@kbd{Caps_Lock} and the @kbd{Control_L} keys, by first removing the
+keysyms (on the right-hand side) from the corresponding modifier maps
+(on the left-hand side), re-assigning them by swapping each other out,
+and finally adding back the keysyms to the modifier maps.
+
+@lisp
+(service home-xmodmap-service-type
+         (home-xmodmap-configuration
+          (key-map '(("remove Lock" . "Caps_Lock")
+                     ("remove Control" . "Control_L")
+                     ("keysym Control_L" . "Caps_Lock")
+                     ("keysym Caps_Lock" . "Control_L")
+                     ("add Lock" . "Caps_Lock")
+                     ("add Control" . "Control_L")))))
+@end lisp
+@end defvar
+
+@deftp {Data Type} home-xmodmap-configuration
+The configuration record for @code{home-xmodmap-service-type}.  Its
+available fields are:
+
+@table @asis
+@item @code{xmodmap} (default: @code{xmodmap}) (type: file-like)
+The @code{xmodmap} package to use.
+
+@item @code{key-map} (default: @code{'()}) (type: list)
+The list of expressions to be read by @code{xmodmap} on service startup.
+
+@end table
+@end deftp
+
 @node Guix Home Services
 @subsection Guix Home Services
 
diff --git a/gnu/home/services/desktop.scm b/gnu/home/services/desktop.scm
index ab2b871539..fb1cd44060 100644
--- a/gnu/home/services/desktop.scm
+++ b/gnu/home/services/desktop.scm
@@ -24,6 +24,7 @@ (define-module (gnu home services desktop)
   #:use-module (gnu services configuration)
   #:autoload   (gnu packages glib)    (dbus)
   #:autoload   (gnu packages xdisorg) (redshift unclutter)
+  #:autoload   (gnu packages xorg) (setxkbmap xmodmap)
   #:use-module (guix records)
   #:use-module (guix gexp)
   #:use-module (srfi srfi-1)
@@ -275,3 +276,59 @@ (define home-unclutter-service-type
    (description "Run the @code{unclutter} daemon, which, on systems using the
 Xorg graphical display server, automatically hides the cursor after a
 user-defined timeout has expired.")))
+
+
+;;;
+;;; Xmodmap.
+;;;
+
+(define-configuration/no-serialization home-xmodmap-configuration
+  (xmodmap
+   (file-like xmodmap)
+   "The @code{xmodmap} package to use.")
+  (key-map
+   (list '())
+   "List of expressions to be read by @code{xmodmap} on service startup."))
+
+(define (serialize-xmodmap-configuration field-name val)
+  (define serialize-field
+    (match-lambda
+      ((key . value)
+       (format #f "~a = ~a" key value))
+      (e e)))
+
+  #~(string-append
+     #$@(interpose (map serialize-field val) "\n" 'suffix)))
+
+(define (xmodmap-shepherd-service config)
+  (define config-file
+    (mixed-text-file
+     "config"
+     (serialize-xmodmap-configuration
+      #f (home-xmodmap-configuration-key-map config))))
+
+  (list
+   (shepherd-service
+    (provision '(xmodmap))
+    (start #~(make-system-constructor
+              (string-join
+               (list #$(file-append
+                        (home-xmodmap-configuration-xmodmap config)
+                        "/bin/xmodmap")
+                     #$config-file))))
+    (stop #~(make-system-constructor
+             #$(file-append setxkbmap "/bin/setxkbmap")))
+    (documentation "On startup, run @code{xmodmap} and read the expressions in
+the configuration file.  On stop, reset all the mappings back to the
+defaults."))))
+
+(define home-xmodmap-service-type
+  (service-type
+   (name 'home-xmodmap)
+   (extensions
+    (list
+     (service-extension home-shepherd-service-type
+                        xmodmap-shepherd-service)))
+   (default-value (home-xmodmap-configuration))
+   (description "Run the @code{xmodmap} utility to modify keymaps and pointer
+buttons under the Xorg display server via user-defined expressions.")))
-- 
2.39.1



-- 
Best regards,
conses




Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Fri, 17 Mar 2023 21:51:02 GMT) Full text and rfc822 format available.

Notification sent to conses <contact <at> conses.eu>:
bug acknowledged by developer. (Fri, 17 Mar 2023 21:51:02 GMT) Full text and rfc822 format available.

Message #25 received at 62101-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: conses <contact <at> conses.eu>
Cc: 62101-done <at> debbugs.gnu.org
Subject: Re: [PATCH v3] home: services: Add home-xmodmap-service-type.
Date: Fri, 17 Mar 2023 22:50:39 +0100
Hi,

conses <contact <at> conses.eu> skribis:

> * gnu/home/services/desktop.scm (home-xmodmap-service-type)
> (home-xmodmap-configuration): New variables;
> (serialize-xmodmap-configuration)
> (xmodmap-shepherd-service): New procedures;
> * doc/guix.texi (Desktop Services): Document it.

Applied, thank you!

Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 15 Apr 2023 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 12 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.