Subject: [bug#54434] [PATCH 0/6] XFCE Updates

From: Feng Shu <[email-masked]>
Date: Mon, 04 Apr 2022 12:59:56 +0800

Brendan Tildesley <[email-masked]> writes:

> On 4/4/22 12:56 pm, Feng Shu wrote:
>> Brendan Tildesley <[email-masked]> writes:
>>
>>> On 3/4/22 8:33 pm, Ludovic Courtès wrote:
>>>> [...]
>>>> One problem is that this won’t work for those using Guix Home, where the
>>>> default profile is ~/.guix-home/profile.
>>>>
>>>> Can this extra variable be avoided?  Or could it be handled by a search
>>>> path specification?
>>> It's xfce4-panel that needs the search path to load .so files for
>>> panel plugins.
>>> xfce4-panel already has the search-path set to load them, but since
>>> its installed
>>> to the system profile,it does not load the user installed plugins. If
>>> xfce4-panel
>>> was a user installed package it may work but userswould have to
>>> manually install it.
>>> So I'm not sure how else to solve it.
>> What happen when version of xfce4-panel installed in system profile is
>> different from installed in home profile?
> I think xfce4-panel will be run from $PATH so the system version will
> be picked first and the user installed one will be ignored. The search
> path will be set but will not work until the user logs out and back in
> again, which is not ideal. I'd like a user to be able to install a plugin
> and have it appear in the settings menu immediately.
>

Maybe it will first find xfce.desktop in <user-profile>/share/xsessions,
then in <system-profile>/share/xsessions.

(define* (xinitrc #:key fallback-session)
  "Return a system-wide xinitrc script that starts the specified X session,
which should be passed to this script as the first argument.  If not, the
@var{fallback-session} will be used or, if @var{fallback-session} is false, a
desktop session from the system or user profile will be used."
  (define builder
    #~(begin
        (use-modules (ice-9 match)
                     (ice-9 regex)
                     (ice-9 ftw)
                     (ice-9 rdelim)
                     (srfi srfi-1)
                     (srfi srfi-26))

        (define (close-all-fdes)
          ;; Close all the open file descriptors except 0 to 2.
          (let loop ((fd 3))
            (when (< fd 4096)               ;FIXME: use sysconf + _SC_OPEN_MAX
              (false-if-exception (close-fdes fd))
              (loop (+ 1 fd)))))

        (define (exec-from-login-shell command . args)
          ;; Run COMMAND from a login shell so that it gets to see the same
          ;; environment variables that one gets when logging in on a tty, for
          ;; instance.
          (let* ((pw    (getpw (getuid)))
                 (shell (passwd:shell pw)))
            ;; Close any open file descriptors.  This is all the more
            ;; important that SLiM itself exec's us directly without closing
            ;; its own file descriptors!
            (close-all-fdes)

            ;; The '--login' option is supported at least by Bash and zsh.
            (execl shell shell "--login" "-c"
                   (string-join (cons command args)))))

        (define system-profile
          "/run/current-system/profile")

        (define user-profile
          (and=> (getpw (getuid))
                 (lambda (pw)
                   (string-append (passwd:dir pw) "/.guix-profile"))))

        (define (xsession-command desktop-file)
          ;; Read from DESKTOP-FILE its X session command and return it as a
          ;; list.
          (define exec-regexp
            (make-regexp "^[[:blank:]]*Exec=(.*)$"))

          (call-with-input-file desktop-file
            (lambda (port)
              (let loop ()
                (match (read-line port)
                  ((? eof-object?) #f)
                  ((= (cut regexp-exec exec-regexp <>) result)
                   (if result
                       (string-tokenize (match:substring result 1))
                       (loop))))))))

        (define (find-session profile)
          ;; Return an X session command from PROFILE or #f if none was found.
          (let ((directory (string-append profile "/share/xsessions")))
            (match (scandir directory
                            (cut string-suffix? ".desktop" <>))
              ((or () #f)
               #f)
              ((sessions ...)
               (any xsession-command
                    (map (cut string-append directory "/" <>)
                         sessions))))))

        (let* ((home          (getenv "HOME"))
               (xsession-file (string-append home "/.xsession"))
               (session       (match (command-line)
                                ((_)
                                 #$(if fallback-session
                                       #~(list #$fallback-session)
                                       #f))
                                ((_ x ..1)
                                 x))))
          (if (file-exists? xsession-file)
              ;; Run ~/.xsession when it exists.
              (apply exec-from-login-shell xsession-file
                     (or session '()))
              ;; Otherwise, start the specified session or a fallback.
              (apply exec-from-login-shell
                     (or session
                         (find-session user-profile)
                         (find-session system-profile)))))))

  (program-file "xinitrc" builder))

--