GNU bug report logs - #35118
[PATCH 0/4] Add localed, fixing keyboard layout in GDM

Previous Next

Package: guix-patches;

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

Date: Wed, 3 Apr 2019 09:43:01 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 35118 in the body.
You can then email your comments to 35118 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#35118; Package guix-patches. (Wed, 03 Apr 2019 09:43:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ludovic Courtès <ludo <at> gnu.org>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Wed, 03 Apr 2019 09:43:02 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: guix-patches <at> gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 0/4] Add localed, fixing keyboard layout in GDM
Date: Wed,  3 Apr 2019 11:41:54 +0200
Hello Guix!

This patch adds localed, a D-Bus service for keyboard layout
and “locales” (not quite actually):

  https://www.freedesktop.org/wiki/Software/systemd/localed/

The only motivation was to fix keyboard layout in GDM: until
now, GDM would always install a US English layout, regardless
of how we configured Xorg.  It did that because it tried to
ask localed about the current keyboard layout, but since that
daemon was unavailable, it would assume that the current layout
is US English and tell XKB to install it.

You would think that it would simply ask X to know what the
current layout is—after all, X knows that first-hand.  But no!
Instead, there’s this localed daemon that normally goes ahead
and greps /etc/X11/xorg.d/00-keyboard.conf in search of
“XkbLayout” and similar options.

This patch modifies localed so that it gets this information
directly from environment variables set by our ‘localed’ service;
their values is inherited from the ‘xorg-configuration’ field of
<gdm-configuration>.

This is all pretty ugly.  Regarding localed itself, I think we
should maintain our own fork since we really just need a couple
of files from systemd.  That would require disentangling the code
from systemd’s own support functions (like its D-Bus API wrapper).
That should be easy for someone who’s ever played with D-Bus in
C, but that’s not me.  :-)

Another option, of course, is to write a D-Bus implementation in
Guile and do the whole thing in Guile.  Shave a yak!

Anyway, in the meantime, this thing does the job.

Thoughts?

Ludo’.

Ludovic Courtès (4):
  services: dbus: Add 'wrapped-dbus-service'.
  gnu: Add localed, extracted from systemd.
  services: dbus: 'wrapped-dbus-service' accepts a list of variables.
  services: Add 'localed' service type and have GDM extend it.

 gnu/local.mk                                  |   1 +
 gnu/packages/freedesktop.scm                  | 148 +++++++-
 .../patches/localed-xorg-keyboard.patch       | 322 ++++++++++++++++++
 gnu/services/dbus.scm                         |  48 +++
 gnu/services/desktop.scm                      |  52 +--
 gnu/services/xorg.scm                         |  89 ++++-
 6 files changed, 612 insertions(+), 48 deletions(-)
 create mode 100644 gnu/packages/patches/localed-xorg-keyboard.patch

-- 
2.21.0





Information forwarded to guix-patches <at> gnu.org:
bug#35118; Package guix-patches. (Wed, 03 Apr 2019 09:45:01 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: 35118 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 1/4] services: dbus: Add 'wrapped-dbus-service'.
Date: Wed,  3 Apr 2019 11:44:16 +0200
* gnu/services/desktop.scm (wrapped-dbus-service): Move to...
* gnu/services/dbus.scm (wrapped-dbus-service): ... here.  New
procedure.
---
 gnu/services/dbus.scm    | 42 ++++++++++++++++++++++++++++++++++++++++
 gnu/services/desktop.scm | 40 --------------------------------------
 2 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/gnu/services/dbus.scm b/gnu/services/dbus.scm
index 606ee0c2f5..3d2dbb903c 100644
--- a/gnu/services/dbus.scm
+++ b/gnu/services/dbus.scm
@@ -26,6 +26,7 @@
   #:use-module (gnu packages polkit)
   #:use-module (gnu packages admin)
   #:use-module (guix gexp)
+  #:use-module ((guix packages) #:select (package-name))
   #:use-module (guix records)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
@@ -33,6 +34,7 @@
             dbus-configuration?
             dbus-root-service-type
             dbus-service
+            wrapped-dbus-service
 
             polkit-service-type
             polkit-service))
@@ -229,6 +231,46 @@ and policy files.  For example, to allow avahi-daemon to use the system bus,
            (dbus-configuration (dbus dbus)
                                (services services))))
 
+(define (wrapped-dbus-service service program variable value)
+  "Return a wrapper for @var{service}, a package containing a D-Bus service,
+where @var{program} is wrapped such that environment variable @var{variable}
+is set to @var{value} when the bus daemon launches it."
+  (define wrapper
+    (program-file (string-append (package-name service) "-program-wrapper")
+                  #~(begin
+                      (setenv #$variable #$value)
+                      (apply execl (string-append #$service "/" #$program)
+                             (string-append #$service "/" #$program)
+                             (cdr (command-line))))))
+
+  (define build
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils))
+
+          (define service-directory
+            "/share/dbus-1/system-services")
+
+          (mkdir-p (dirname (string-append #$output
+                                           service-directory)))
+          (copy-recursively (string-append #$service
+                                           service-directory)
+                            (string-append #$output
+                                           service-directory))
+          (symlink (string-append #$service "/etc") ;for etc/dbus-1
+                   (string-append #$output "/etc"))
+
+          (for-each (lambda (file)
+                      (substitute* file
+                        (("Exec[[:blank:]]*=[[:blank:]]*([[:graph:]]+)(.*)$"
+                          _ original-program arguments)
+                         (string-append "Exec=" #$wrapper arguments
+                                        "\n"))))
+                    (find-files #$output "\\.service$")))))
+
+  (computed-file (string-append (package-name service) "-wrapper")
+                 build))
+
 
 ;;;
 ;;; Polkit privilege management service.
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index dcab950822..230aeb324c 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -150,46 +150,6 @@
       ((package . _) package))))
 
 
-(define (wrapped-dbus-service service program variable value)
-  "Return a wrapper for @var{service}, a package containing a D-Bus service,
-where @var{program} is wrapped such that environment variable @var{variable}
-is set to @var{value} when the bus daemon launches it."
-  (define wrapper
-    (program-file (string-append (package-name service) "-program-wrapper")
-                  #~(begin
-                      (setenv #$variable #$value)
-                      (apply execl (string-append #$service "/" #$program)
-                             (string-append #$service "/" #$program)
-                             (cdr (command-line))))))
-
-  (define build
-    (with-imported-modules '((guix build utils))
-      #~(begin
-          (use-modules (guix build utils))
-
-          (define service-directory
-            "/share/dbus-1/system-services")
-
-          (mkdir-p (dirname (string-append #$output
-                                           service-directory)))
-          (copy-recursively (string-append #$service
-                                           service-directory)
-                            (string-append #$output
-                                           service-directory))
-          (symlink (string-append #$service "/etc") ;for etc/dbus-1
-                   (string-append #$output "/etc"))
-
-          (for-each (lambda (file)
-                      (substitute* file
-                        (("Exec[[:blank:]]*=[[:blank:]]*([[:graph:]]+)(.*)$"
-                          _ original-program arguments)
-                         (string-append "Exec=" #$wrapper arguments
-                                        "\n"))))
-                    (find-files #$output "\\.service$")))))
-
-  (computed-file (string-append (package-name service) "-wrapper")
-                 build))
-
 
 ;;;
 ;;; Upower D-Bus service.
-- 
2.21.0





Information forwarded to guix-patches <at> gnu.org:
bug#35118; Package guix-patches. (Wed, 03 Apr 2019 09:45:02 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: 35118 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 2/4] gnu: Add localed, extracted from systemd.
Date: Wed,  3 Apr 2019 11:44:17 +0200
* gnu/packages/freedesktop.scm (localed): New variable.
* gnu/packages/patches/localed-xorg-keyboard.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                  |   1 +
 gnu/packages/freedesktop.scm                  | 148 +++++++-
 .../patches/localed-xorg-keyboard.patch       | 322 ++++++++++++++++++
 3 files changed, 470 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/localed-xorg-keyboard.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 45598d4e14..5c86ee0809 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -929,6 +929,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/kdbusaddons-kinit-file-name.patch	\
   %D%/packages/patches/khmer-use-libraries.patch                \
   %D%/packages/patches/libziparchive-add-includes.patch		\
+  %D%/packages/patches/localed-xorg-keyboard.patch		\
   %D%/packages/patches/kiki-level-selection-crash.patch		\
   %D%/packages/patches/kiki-makefile.patch			\
   %D%/packages/patches/kiki-missing-includes.patch		\
diff --git a/gnu/packages/freedesktop.scm b/gnu/packages/freedesktop.scm
index 56aeca0478..ec8688d2d4 100644
--- a/gnu/packages/freedesktop.scm
+++ b/gnu/packages/freedesktop.scm
@@ -2,7 +2,7 @@
 ;;; Copyright © 2015 Andreas Enge <andreas <at> enge.fr>
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong <at> gmail.com>
 ;;; Copyright © 2015, 2017 Andy Wingo <wingo <at> pobox.com>
-;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo <at> gnu.org>
+;;; Copyright © 2015, 2016, 2017, 2019 Ludovic Courtès <ludo <at> gnu.org>
 ;;; Copyright © 2015, 2017, 2018, 2019 Ricardo Wurmus <rekado <at> elephly.net>
 ;;; Copyright © 2015 David Hashe <david.hashe <at> dhashe.com>
 ;;; Copyright © 2016, 2017 Efraim Flashner <efraim <at> flashner.co.il>
@@ -307,6 +307,152 @@ the org.freedesktop.login1 interface over the system bus, allowing other parts
 of a the system to know what users are logged in, and where.")
     (license license:lgpl2.1+)))
 
+(define-public localed
+  ;; XXX: This package is extracted from systemd but we retain so little of it
+  ;; that it would make more sense to maintain of fork of the bits we need.
+  (package
+    (name "localed")
+    (version "241")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    (url "https://github.com/systemd/systemd")
+                    (commit (string-append "v" version))))
+              (sha256
+               (base32
+                "0sy91flzbhpq58k7v0294pa2gxpr0bk27rcnxlbhk2fi6nc51d28"))
+              (file-name (git-file-name name version))
+              (modules '((guix build utils)))
+              (snippet
+               '(begin
+                  ;; Connect to the right location for our D-Bus daemon.
+                  (substitute* '("src/basic/def.h"
+                                 "src/libsystemd/sd-bus/sd-bus.c"
+                                 "src/stdio-bridge/stdio-bridge.c")
+                    (("/run/dbus/system_bus_socket")
+                     "/var/run/dbus/system_bus_socket"))
+
+                  ;; Don't insist on having systemd as PID 1 (otherwise
+                  ;; 'localectl' would exit without doing anything.)
+                  (substitute* "src/shared/bus-util.c"
+                    (("sd_booted\\(\\)")
+                     "(1)"))
+                  #t))
+              (patches (search-patches "localed-xorg-keyboard.patch"))))
+    (build-system meson-build-system)
+    (arguments
+     ;; Try to build as little as possible (list of components taken from the
+     ;; top-level 'meson.build' file.)
+     (let ((components '("utmp"
+                         "hibernate"
+                         "environment-d"
+                         "binfmt"
+                         "coredump"
+                         "resolve"
+                         "logind"
+                         "hostnamed"
+                         "localed"
+                         "machined"
+                         "portabled"
+                         "networkd"
+                         "timedated"
+                         "timesyncd"
+                         "firstboot"
+                         "randomseed"
+                         "backlight"
+                         "vconsole"
+                         "quotacheck"
+                         "sysusers"
+                         "tmpfiles"
+                         "hwdb"
+                         "rfkill"
+                         "ldconfig"
+                         "efi"
+                         "tpm"
+                         "ima"
+                         "smack"
+                         "gshadow"
+                         "idn"
+                         "nss-myhostname"
+                         "nss-systemd")))
+       `(#:configure-flags ',(map (lambda (component)
+                                    (string-append "-D" component "=false"))
+                                  (delete "localed" components))
+
+         ;; It doesn't make sense to test all of systemd.
+         #:tests? #f
+
+         #:phases (modify-phases %standard-phases
+                    (add-after 'unpack 'set-xkeyboard-config-file-name
+                      (lambda* (#:key inputs #:allow-other-keys)
+                        ;; Set the file name to xkeyboard-config and kbd.
+                        ;; This is used by 'localectl list-x11-keymap-layouts'
+                        ;; and similar functions.
+                        (let ((xkb (assoc-ref inputs "xkeyboard-config"))
+                              (kbd (assoc-ref inputs "kbd")))
+                          (substitute* "src/locale/localectl.c"
+                            (("/usr/share/X11/xkb/rules")
+                             (string-append xkb "/share/X11/xkb/rules")))
+                          (substitute* "src/basic/def.h"
+                            (("/usr/share/keymaps")
+                             (string-append kbd "/share/keymaps")))
+                          #t)))
+                    (replace 'install
+                      (lambda* (#:key outputs #:allow-other-keys)
+                        ;; Install 'localed', the D-Bus and polkit files, and
+                        ;; 'localectl'.
+                        (let* ((out (assoc-ref outputs "out"))
+                               (libexec (string-append out "/libexec/localed"))
+                               (bin     (string-append out "/bin"))
+                               (lib     (string-append out "/lib"))
+                               (dbus    (string-append out
+                                                       "/share/dbus-1/system-services"))
+                               (conf    (string-append out
+                                                       "/etc/dbus-1/system.d/"))
+                               (polkit  (string-append out
+                                                       "/share/polkit-1/actions"))
+                               (data    (string-append out "/share/systemd")))
+                          (define (source-file regexp)
+                            (car (find-files ".." regexp)))
+
+                          (mkdir-p libexec)
+                          (copy-file "systemd-localed"
+                                     (string-append libexec "/localed"))
+                          (install-file "localectl" bin)
+
+                          (let ((service-file (source-file
+                                               "\\.locale1\\.service$")))
+                            (substitute* service-file
+                              (("^Exec=.*$")
+                               (string-append "Exec=" libexec "/localed\n")))
+                            (install-file service-file dbus))
+                          (install-file (source-file "\\.locale1\\.policy$")
+                                        polkit)
+                          (install-file (source-file "\\.locale1\\.conf$")
+                                        conf)
+                          (for-each (lambda (file)
+                                      (install-file file lib))
+                                    (find-files "src/shared"
+                                                "libsystemd-shared.*\\.so"))
+
+                          (for-each (lambda (map)
+                                      (install-file map data))
+                                    (find-files ".." "^(kbd-model-map|language-fallback-map)$"))
+                          #t)))))))
+    (native-inputs (package-native-inputs elogind))
+    (inputs `(("libmount" ,util-linux)
+              ("xkeyboard-config" ,xkeyboard-config)
+              ("kbd" ,kbd)
+              ,@(package-inputs elogind)))
+    (home-page "https://www.freedesktop.org/wiki/Software/systemd/localed/")
+    (synopsis "Control the system locale and keyboard layout")
+    (description
+     "Localed is a tiny daemon that can be used to control the system locale
+and keyboard mapping from user programs.  It is used among other things by the
+GNOME Shell.  The @command{localectl} command-line tool allows you to interact
+with localed.  This package is extracted from the broader systemd package.")
+    (license license:lgpl2.1+)))
+
 (define-public packagekit
   (package
     (name "packagekit")
diff --git a/gnu/packages/patches/localed-xorg-keyboard.patch b/gnu/packages/patches/localed-xorg-keyboard.patch
new file mode 100644
index 0000000000..9a9071ba0a
--- /dev/null
+++ b/gnu/packages/patches/localed-xorg-keyboard.patch
@@ -0,0 +1,322 @@
+Normally localed would do an approximate parsing of the Xorg config file
+to determine the XKB keyboard layout.  This doesn't make sense on Guix
+where there's no such file in /etc, and where the keyboard layout is
+known statically at configuration time.
+
+This patch removes the XOrg configuration parsing and expects to read the
+configuration from environment variables instead.  It also removes the
+stateful bits that would write configuration to /etc/vconsole.conf
+and /etc/X11, which are unused in Guix anyway.
+
+Patch by Ludovic Courtès <ludo <at> gnu.org>.
+
+diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
+index 6b6b32a591..46aab472b0 100644
+--- a/src/locale/keymap-util.c
++++ b/src/locale/keymap-util.c
+@@ -174,32 +174,16 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
+                 c->vc_cache = sd_bus_message_ref(m);
+         }
+ 
+-        if (stat("/etc/vconsole.conf", &st) < 0) {
+-                if (errno != ENOENT)
+-                        return -errno;
+-
+-                c->vc_mtime = USEC_INFINITY;
+-                context_free_vconsole(c);
+-                return 0;
+-        }
+-
+-        /* If mtime is not changed, then we do not need to re-read */
+-        t = timespec_load(&st.st_mtim);
+-        if (c->vc_mtime != USEC_INFINITY && t == c->vc_mtime)
+-                return 0;
+-
+-        c->vc_mtime = t;
++        c->vc_mtime = USEC_INFINITY;
+         context_free_vconsole(c);
+-
+-        r = parse_env_file(NULL, "/etc/vconsole.conf",
+-                           "KEYMAP",        &c->vc_keymap,
+-                           "KEYMAP_TOGGLE", &c->vc_keymap_toggle);
+-        if (r < 0)
+-                return r;
+-
+         return 0;
+ }
+ 
++static char *getenv_strdup(const char *variable) {
++        const char *value = getenv(variable);
++        return value == NULL ? NULL : strdup(value);
++}
++
+ int x11_read_data(Context *c, sd_bus_message *m) {
+         _cleanup_fclose_ FILE *f = NULL;
+         bool in_section = false;
+@@ -216,258 +200,27 @@ int x11_read_data(Context *c, sd_bus_message *m) {
+                 c->x11_cache = sd_bus_message_ref(m);
+         }
+ 
+-        if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) < 0) {
+-                if (errno != ENOENT)
+-                        return -errno;
+-
+-                c->x11_mtime = USEC_INFINITY;
+-                context_free_x11(c);
+-                return 0;
+-        }
+-
+-        /* If mtime is not changed, then we do not need to re-read */
+-        t = timespec_load(&st.st_mtim);
+-        if (c->x11_mtime != USEC_INFINITY && t == c->x11_mtime)
+-                return 0;
+-
+-        c->x11_mtime = t;
++        c->x11_mtime = 0;
+         context_free_x11(c);
+ 
+-        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
+-        if (!f)
+-                return -errno;
+-
+-        for (;;) {
+-                _cleanup_free_ char *line = NULL;
+-                char *l;
+-
+-                r = read_line(f, LONG_LINE_MAX, &line);
+-                if (r < 0)
+-                        return r;
+-                if (r == 0)
+-                        break;
+-
+-                l = strstrip(line);
+-                if (IN_SET(l[0], 0, '#'))
+-                        continue;
+-
+-                if (in_section && first_word(l, "Option")) {
+-                        _cleanup_strv_free_ char **a = NULL;
+-
+-                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
+-                        if (r < 0)
+-                                return r;
+-
+-                        if (strv_length(a) == 3) {
+-                                char **p = NULL;
+-
+-                                if (streq(a[1], "XkbLayout"))
+-                                        p = &c->x11_layout;
+-                                else if (streq(a[1], "XkbModel"))
+-                                        p = &c->x11_model;
+-                                else if (streq(a[1], "XkbVariant"))
+-                                        p = &c->x11_variant;
+-                                else if (streq(a[1], "XkbOptions"))
+-                                        p = &c->x11_options;
+-
+-                                if (p) {
+-                                        free_and_replace(*p, a[2]);
+-                                }
+-                        }
+-
+-                } else if (!in_section && first_word(l, "Section")) {
+-                        _cleanup_strv_free_ char **a = NULL;
+-
+-                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
+-                        if (r < 0)
+-                                return -ENOMEM;
+-
+-                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
+-                                in_section = true;
+-
+-                } else if (in_section && first_word(l, "EndSection"))
+-                        in_section = false;
+-        }
++        c->x11_layout = getenv_strdup("GUIX_XKB_LAYOUT");
++        c->x11_model = getenv_strdup("GUIX_XKB_MODEL");
++        c->x11_variant = getenv_strdup("GUIX_XKB_VARIANT");
++        c->x11_options = getenv_strdup("GUIX_XKB_OPTIONS");
+ 
+         return 0;
+ }
+ 
+ int locale_write_data(Context *c, char ***settings) {
+-        _cleanup_strv_free_ char **l = NULL;
+-        struct stat st;
+-        int r, p;
+-
+-        /* Set values will be returned as strv in *settings on success. */
+-
+-        for (p = 0; p < _VARIABLE_LC_MAX; p++) {
+-                _cleanup_free_ char *t = NULL;
+-                char **u;
+-                const char *name;
+-
+-                name = locale_variable_to_string(p);
+-                assert(name);
+-
+-                if (isempty(c->locale[p]))
+-                        continue;
+-
+-                if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0)
+-                        return -ENOMEM;
+-
+-                u = strv_env_set(l, t);
+-                if (!u)
+-                        return -ENOMEM;
+-
+-                strv_free_and_replace(l, u);
+-        }
+-
+-        if (strv_isempty(l)) {
+-                if (unlink("/etc/locale.conf") < 0)
+-                        return errno == ENOENT ? 0 : -errno;
+-
+-                c->locale_mtime = USEC_INFINITY;
+-                return 0;
+-        }
+-
+-        r = write_env_file_label("/etc/locale.conf", l);
+-        if (r < 0)
+-                return r;
+-
+-        *settings = TAKE_PTR(l);
+-
+-        if (stat("/etc/locale.conf", &st) >= 0)
+-                c->locale_mtime = timespec_load(&st.st_mtim);
+-
+-        return 0;
++        return -ENOSYS;
+ }
+ 
+ int vconsole_write_data(Context *c) {
+-        _cleanup_strv_free_ char **l = NULL;
+-        struct stat st;
+-        int r;
+-
+-        r = load_env_file(NULL, "/etc/vconsole.conf", &l);
+-        if (r < 0 && r != -ENOENT)
+-                return r;
+-
+-        if (isempty(c->vc_keymap))
+-                l = strv_env_unset(l, "KEYMAP");
+-        else {
+-                _cleanup_free_ char *s = NULL;
+-                char **u;
+-
+-                s = strappend("KEYMAP=", c->vc_keymap);
+-                if (!s)
+-                        return -ENOMEM;
+-
+-                u = strv_env_set(l, s);
+-                if (!u)
+-                        return -ENOMEM;
+-
+-                strv_free_and_replace(l, u);
+-        }
+-
+-        if (isempty(c->vc_keymap_toggle))
+-                l = strv_env_unset(l, "KEYMAP_TOGGLE");
+-        else  {
+-                _cleanup_free_ char *s = NULL;
+-                char **u;
+-
+-                s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
+-                if (!s)
+-                        return -ENOMEM;
+-
+-                u = strv_env_set(l, s);
+-                if (!u)
+-                        return -ENOMEM;
+-
+-                strv_free_and_replace(l, u);
+-        }
+-
+-        if (strv_isempty(l)) {
+-                if (unlink("/etc/vconsole.conf") < 0)
+-                        return errno == ENOENT ? 0 : -errno;
+-
+-                c->vc_mtime = USEC_INFINITY;
+-                return 0;
+-        }
+-
+-        r = write_env_file_label("/etc/vconsole.conf", l);
+-        if (r < 0)
+-                return r;
+-
+-        if (stat("/etc/vconsole.conf", &st) >= 0)
+-                c->vc_mtime = timespec_load(&st.st_mtim);
+-
+-        return 0;
++        return -ENOSYS;
+ }
+ 
+ int x11_write_data(Context *c) {
+-        _cleanup_fclose_ FILE *f = NULL;
+-        _cleanup_free_ char *temp_path = NULL;
+-        struct stat st;
+-        int r;
+-
+-        if (isempty(c->x11_layout) &&
+-            isempty(c->x11_model) &&
+-            isempty(c->x11_variant) &&
+-            isempty(c->x11_options)) {
+-
+-                if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
+-                        return errno == ENOENT ? 0 : -errno;
+-
+-                c->vc_mtime = USEC_INFINITY;
+-                return 0;
+-        }
+-
+-        mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
+-
+-        r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
+-        if (r < 0)
+-                return r;
+-
+-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+-        (void) fchmod(fileno(f), 0644);
+-
+-        fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n"
+-              "# probably wise not to edit this file manually. Use localectl(1) to\n"
+-              "# instruct systemd-localed to update it.\n"
+-              "Section \"InputClass\"\n"
+-              "        Identifier \"system-keyboard\"\n"
+-              "        MatchIsKeyboard \"on\"\n", f);
+-
+-        if (!isempty(c->x11_layout))
+-                fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
+-
+-        if (!isempty(c->x11_model))
+-                fprintf(f, "        Option \"XkbModel\" \"%s\"\n", c->x11_model);
+-
+-        if (!isempty(c->x11_variant))
+-                fprintf(f, "        Option \"XkbVariant\" \"%s\"\n", c->x11_variant);
+-
+-        if (!isempty(c->x11_options))
+-                fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", c->x11_options);
+-
+-        fputs("EndSection\n", f);
+-
+-        r = fflush_sync_and_check(f);
+-        if (r < 0)
+-                goto fail;
+-
+-        if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
+-                r = -errno;
+-                goto fail;
+-        }
+-
+-        if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) >= 0)
+-                c->x11_mtime = timespec_load(&st.st_mtim);
+-
+-        return 0;
+-
+-fail:
+-        if (temp_path)
+-                (void) unlink(temp_path);
+-
+-        return r;
++        return -ENOSYS;
+ }
+ 
+ static int read_next_mapping(const char* filename,
-- 
2.21.0





Information forwarded to guix-patches <at> gnu.org:
bug#35118; Package guix-patches. (Wed, 03 Apr 2019 09:45:02 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: 35118 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 3/4] services: dbus: 'wrapped-dbus-service' accepts a list of
 variables.
Date: Wed,  3 Apr 2019 11:44:18 +0200
* gnu/services/dbus.scm (wrapped-dbus-service): Replace 'variable' and
'value' by 'variables', and adjust code accordingly.
* gnu/services/desktop.scm (upower-dbus-service):
(geoclue-dbus-service, elogind-dbus-service): Adjust accordingly.
---
 gnu/services/dbus.scm    | 14 ++++++++++----
 gnu/services/desktop.scm | 12 ++++++------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/gnu/services/dbus.scm b/gnu/services/dbus.scm
index 3d2dbb903c..35d7ff3c9c 100644
--- a/gnu/services/dbus.scm
+++ b/gnu/services/dbus.scm
@@ -231,14 +231,20 @@ and policy files.  For example, to allow avahi-daemon to use the system bus,
            (dbus-configuration (dbus dbus)
                                (services services))))
 
-(define (wrapped-dbus-service service program variable value)
+(define (wrapped-dbus-service service program variables)
   "Return a wrapper for @var{service}, a package containing a D-Bus service,
-where @var{program} is wrapped such that environment variable @var{variable}
-is set to @var{value} when the bus daemon launches it."
+where @var{program} is wrapped such that @var{variables}, a list of name/value
+tuples, are all set as environment variables when the bus daemon launches it."
   (define wrapper
     (program-file (string-append (package-name service) "-program-wrapper")
                   #~(begin
-                      (setenv #$variable #$value)
+                      (use-modules (ice-9 match))
+
+                      (for-each (match-lambda
+                                  ((variable value)
+                                   (setenv variable value)))
+                                '#$variables)
+
                       (apply execl (string-append #$service "/" #$program)
                              (string-append #$service "/" #$program)
                              (cdr (command-line))))))
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index 230aeb324c..578095b146 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -217,8 +217,8 @@
 (define (upower-dbus-service config)
   (list (wrapped-dbus-service (upower-configuration-upower config)
                               "libexec/upowerd"
-                              "UPOWER_CONF_FILE_NAME"
-                              (upower-configuration-file config))))
+                              `(("UPOWER_CONF_FILE_NAME"
+                                 ,(upower-configuration-file config))))))
 
 (define (upower-shepherd-service config)
   "Return a shepherd service for UPower with CONFIG."
@@ -349,8 +349,8 @@ users are allowed."
 (define (geoclue-dbus-service config)
   (list (wrapped-dbus-service (geoclue-configuration-geoclue config)
                               "libexec/geoclue"
-                              "GEOCLUE_CONFIG_FILE"
-                              (geoclue-configuration-file config))))
+                              `(("GEOCLUE_CONFIG_FILE"
+                                 ,(geoclue-configuration-file config))))))
 
 (define %geoclue-accounts
   (list (user-group (name "geoclue") (system? #t))
@@ -702,8 +702,8 @@ include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
 (define (elogind-dbus-service config)
   (list (wrapped-dbus-service (elogind-package config)
                               "libexec/elogind/elogind"
-                              "ELOGIND_CONF_FILE"
-                              (elogind-configuration-file config))))
+                              `(("ELOGIND_CONF_FILE"
+                                 ,(elogind-configuration-file config))))))
 
 (define (pam-extension-procedure config)
   "Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM
-- 
2.21.0





Information forwarded to guix-patches <at> gnu.org:
bug#35118; Package guix-patches. (Wed, 03 Apr 2019 09:45:03 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: 35118 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 4/4] services: Add 'localed' service type and have GDM extend
 it.
Date: Wed,  3 Apr 2019 11:44:19 +0200
This fixes a bug whereby GDM would always switch to US English keyboard
layout regardless to the configured Xorg keyboard layout.

* gnu/services/xorg.scm (<localed-configuration>): New record type.
(localed-dbus-service): New procedure.
(localed-service-type): New variable.
(gdm-service-type): Extend LOCALED-SERVICE-TYPE.
---
 gnu/services/xorg.scm | 89 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/gnu/services/xorg.scm b/gnu/services/xorg.scm
index 29c7f30013..7745f9a3cc 100644
--- a/gnu/services/xorg.scm
+++ b/gnu/services/xorg.scm
@@ -27,6 +27,7 @@
   #:use-module (gnu services shepherd)
   #:use-module (gnu system pam)
   #:use-module (gnu system keyboard)
+  #:use-module (gnu services base)
   #:use-module (gnu services dbus)
   #:use-module ((gnu packages base) #:select (canonical-package))
   #:use-module (gnu packages guile)
@@ -35,6 +36,7 @@
   #:use-module (gnu packages gl)
   #:use-module (gnu packages glib)
   #:use-module (gnu packages display-managers)
+  #:use-module (gnu packages freedesktop)
   #:use-module (gnu packages gnustep)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages admin)
@@ -91,6 +93,10 @@
             screen-locker-service-type
             screen-locker-service
 
+            localed-configuration
+            localed-configuration?
+            localed-service-type
+
             gdm-configuration
             gdm-service-type
             gdm-service))
@@ -653,6 +659,82 @@ makes the good ol' XlockMore usable."
                           (file-append package "/bin/" program)
                           allow-empty-passwords?)))
 
+
+;;;
+;;; Locale service.
+;;;
+
+(define-record-type* <localed-configuration>
+  localed-configuration make-localed-configuration
+  localed-configuration?
+  (localed         localed-configuration-localed
+                   (default localed))
+  (keyboard-layout localed-configuration-keyboard-layout
+                   (default #f)))
+
+(define (localed-dbus-service config)
+  "Return the 'localed' D-Bus service for @var{config}, a
+@code{<localed-configuration>} record."
+  (define keyboard-layout
+    (localed-configuration-keyboard-layout config))
+
+  ;; The primary purpose of 'localed' is to tell GDM what the "current" Xorg
+  ;; keyboard layout is.  If 'localed' is missing, or if it's unable to
+  ;; determine the current XKB layout, then GDM forcefully installs its
+  ;; default XKB config (US English).  Here we communicate the configured
+  ;; layout through environment variables.
+
+  (if keyboard-layout
+      (let* ((layout  (keyboard-layout-name keyboard-layout))
+             (variant (keyboard-layout-variant keyboard-layout))
+             (model   (keyboard-layout-model keyboard-layout))
+             (options (keyboard-layout-options keyboard-layout)))
+        (list (wrapped-dbus-service
+               (localed-configuration-localed config)
+               "libexec/localed/localed"
+               `(("GUIX_XKB_LAYOUT" ,layout)
+                 ,@(if variant
+                       `(("GUIX_XKB_VARIANT" ,variant))
+                       '())
+                 ,@(if model
+                       `(("GUIX_XKB_MODEL" ,model))
+                       '())
+                 ,@(if (null? options)
+                       '()
+                       `(("GUIX_XKB_OPTIONS"
+                          ,(string-join options ","))))))))
+      (localed-configuration-localed config)))
+
+(define localed-service-type
+  (let ((package (compose list localed-configuration-localed)))
+    (service-type (name 'localed)
+                  (extensions
+                   (list (service-extension dbus-root-service-type
+                                            localed-dbus-service)
+                         (service-extension udev-service-type package)
+                         (service-extension polkit-service-type package)
+
+                         ;; Add 'localectl' to the profile.
+                         (service-extension profile-service-type package)))
+
+                  ;; This service can be extended, typically by the X login
+                  ;; manager, to communicate the chosen Xorg keyboard layout.
+                  (compose first)
+                  (extend (lambda (config keyboard-layout)
+                            (localed-configuration
+                             (inherit config)
+                             (keyboard-layout keyboard-layout))))
+                  (description
+                   "Run the locale daemon, @command{localed}, which can be used
+to control the system locale and keyboard mapping from user programs such as
+the GNOME desktop environment.")
+                  (default-value (localed-configuration)))))
+
+
+;;;
+;;; GNOME Desktop Manager.
+;;;
+
 (define %gdm-accounts
   (list (user-group (name "gdm") (system? #t))
         (user-account
@@ -787,7 +869,12 @@ makes the good ol' XlockMore usable."
                                           gdm-configuration-gnome-shell-assets)
                        (service-extension dbus-root-service-type
                                           (compose list
-                                                   gdm-configuration-gdm))))
+                                                   gdm-configuration-gdm))
+                       (service-extension localed-service-type
+                                          (compose
+                                           xorg-configuration-keyboard-layout
+                                           gdm-configuration-xorg))))
+
                 (default-value (gdm-configuration))
                 (description
                  "Run the GNOME Desktop Manager (GDM), a program that allows
-- 
2.21.0





Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Fri, 05 Apr 2019 13:48:02 GMT) Full text and rfc822 format available.

Notification sent to Ludovic Courtès <ludo <at> gnu.org>:
bug acknowledged by developer. (Fri, 05 Apr 2019 13:48:02 GMT) Full text and rfc822 format available.

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

From: Ludovic Courtès <ludo <at> gnu.org>
To: 35118-done <at> debbugs.gnu.org
Subject: Re: [bug#35118] [PATCH 0/4] Add localed, fixing keyboard layout in GDM
Date: Fri, 05 Apr 2019 15:47:36 +0200
Hello,

Pushed!

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

> This is all pretty ugly.  Regarding localed itself, I think we
> should maintain our own fork since we really just need a couple
> of files from systemd.  That would require disentangling the code
> from systemd’s own support functions (like its D-Bus API wrapper).
> That should be easy for someone who’s ever played with D-Bus in
> C, but that’s not me.  :-)

As discussed on IRC with Julien and others, I tried to actually fork
systemd and strip everything but src/locale.  Unfortunately that turned
out to be pretty tricky because of all the systemd-internal utilities
being used (allocation, string manipulation, etc.)

If someone is willing to give it a try, I can share what I have so far!

Ludo’.




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

This bug report was last modified 4 years and 359 days ago.

Previous Next


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