From: Stefan Kangas <stefankangas@gmail.com>
To: Felix <felix.dick@web.de>
Cc: 57781@debbugs.gnu.org, Sean Whitton <spwhitton@spwhitton.name>
Subject: bug#57781: missing wallpaper command
Date: Tue, 4 Oct 2022 07:58:48 +0200 [thread overview]
Message-ID: <CADwFkmmdjiPkvBON3Fwb1paw66UVypb-EjJuy6Tg5QqtOM9Stg@mail.gmail.com> (raw)
In-Reply-To: <87a671h861.fsf@web.de>
[-- Attachment #1: Type: text/plain, Size: 529 bytes --]
Felix <felix.dick@web.de> writes:
> I'm switching back and forth from Xorg to wayland and I'm
> tinkering with different desktops/WMs anyways.
> I would be happy to help!
> I will try wallpaper.el with gnome tomorrow.
> If there are any things you want me
> to test, just let me know.
I believe the attached patch will fix setting the wallpaper using
swaybg/wbg. It will prompt to kill any existing swaybg/wbg processes,
and start a new process that should survive exiting Emacs.
I would appreciate any help with testing it.
[-- Attachment #2: 0001-Fix-setting-the-wallpaper-with-swaybg-and-wbg.patch --]
[-- Type: text/x-diff, Size: 12251 bytes --]
From 26c0f54dd23ed1f76f7807ef6d59cc9a026b24ee Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefankangas@gmail.com>
Date: Tue, 4 Oct 2022 02:45:53 +0200
Subject: [PATCH] Fix setting the wallpaper with "swaybg" and "wbg"
* lisp/image/wallpaper.el (wallpaper-setter): Add 'init-action'
and 'detach' fields to structure.
(wallpaper--init-action-kill): New helper function.
(wallpaper--default-setters): Use above new fields for "swaybg" and
"wbg", to start/restart the corresponding processes as needed.
(wallpaper-default-set-function): Call 'init-action' function if
there is one. If 'detach', use 'call-process' instead of
'start-process'.
* test/lisp/image/wallpaper-tests.el (wallpaper--find-setter)
(wallpaper--find-setter/call-predicate)
(wallpaper--find-setter/set-current-setter)
(wallpaper-set/runs-command, wallpaper-set/runs-command/detach)
(wallpaper-set/calls-init-action)
(wallpaper-set/calls-wallpaper-set-function): New tests.
---
lisp/image/wallpaper.el | 100 ++++++++++++++++++++---------
test/lisp/image/wallpaper-tests.el | 95 +++++++++++++++++++++++++++
2 files changed, 166 insertions(+), 29 deletions(-)
diff --git a/lisp/image/wallpaper.el b/lisp/image/wallpaper.el
index e23b65d616..2912576561 100644
--- a/lisp/image/wallpaper.el
+++ b/lisp/image/wallpaper.el
@@ -26,7 +26,8 @@
;; desktop background.
;;
;; On GNU/Linux and other Unix-like systems, it uses an external
-;; command to set the desktop background.
+;; command to set the desktop background. This should work seamlessly
+;; on both X and Wayland.
;;
;; Finding an external command to use is obviously a bit tricky to get
;; right, as there is no lack of platforms, window managers, desktop
@@ -94,9 +95,11 @@ wallpaper--use-default-set-function-p
(args (if (or (listp args-raw) (symbolp args-raw))
args-raw
(string-split args-raw)))
- (predicate (plist-get rest-plist :predicate))))
+ (predicate (plist-get rest-plist :predicate))
+ (init-action (plist-get rest-plist :init-action))
+ (detach (plist-get rest-plist :detach))))
(:copier wallpaper-setter-copy))
- "Structure containing a command to set the wallpaper.
+ "Structure containing a method to set the wallpaper.
NAME is a description of the setter (e.g. the name of the Desktop
Environment).
@@ -106,15 +109,41 @@ wallpaper--use-default-set-function-p
ARGS is the default list of command line arguments for COMMAND.
PREDICATE is a function that will be called without any arguments
-and returns non-nil if this setter should be used."
+and returns non-nil if this setter should be used.
+
+INIT-ACTION is a function that will be called without any
+arguments before trying to set the wallpaper.
+
+DETACH, if non-nil, means that the wallpaper process should
+continue running even after exiting Emacs."
name
command
args
- (predicate #'always))
+ (predicate #'always)
+ init-action
+ detach)
;;;###autoload
(put 'wallpaper-setter-create 'lisp-indent-function 1)
+(defun wallpaper--init-action-kill (process-name)
+ "Return kill function for `init-action' of a `wallpaper-setter' structure.
+The returned function kills any process named PROCESS-NAME owned
+by the current effective user id."
+ (lambda ()
+ (when-let ((procs
+ (seq-filter (lambda (p) (let-alist p
+ (and (= .euid (user-uid))
+ (equal .comm process-name))))
+ (mapcar (lambda (pid)
+ (cons (cons 'pid pid)
+ (process-attributes pid)))
+ (list-system-processes)))))
+ (dolist (proc procs)
+ (let-alist proc
+ (when (y-or-n-p (format "Kill \"%s\" process with PID %d?" .comm .pid))
+ (signal-process .pid 'TERM)))))))
+
(defmacro wallpaper--default-methods-create (&rest items)
"Helper macro for defining `wallpaper--default-setters'."
(cons 'list
@@ -198,12 +227,16 @@ wallpaper--default-setters
"swaybg" "-o * -i %f -m fill"
:predicate (lambda ()
(and (getenv "WAYLAND_DISPLAY")
- (getenv "SWAYSOCK"))))
+ (getenv "SWAYSOCK")))
+ :init-action (wallpaper--init-action-kill "swaybg")
+ :detach t)
("wbg"
"wbg" "%f"
:predicate (lambda ()
- (getenv "WAYLAND_DISPLAY")))
+ (getenv "WAYLAND_DISPLAY"))
+ :init-action (wallpaper--init-action-kill "wbg")
+ :detach t)
;; X general.
("GraphicsMagick"
@@ -257,7 +290,8 @@ wallpaper--current-setter
(defun wallpaper--find-setter ()
(when (wallpaper--use-default-set-function-p)
- (or wallpaper--current-setter
+ (or (and (wallpaper-setter-p wallpaper--current-setter)
+ wallpaper--current-setter)
(setq wallpaper--current-setter
(catch 'found
(dolist (setter wallpaper--default-setters)
@@ -482,28 +516,36 @@ wallpaper-default-set-function
(real-args (mapcar (lambda (arg) (wallpaper--format-arg arg file))
args))
(bufname (format " *wallpaper-%s*" (random)))
- (process
- (and wallpaper-command
- (apply #'start-process "set-wallpaper" bufname
- wallpaper-command real-args))))
- (unless wallpaper-command
- (error "Couldn't find a suitable command for setting the wallpaper"))
+ (setter (and (wallpaper-setter-p wallpaper--current-setter)
+ (equal (wallpaper-setter-command wallpaper--current-setter)
+ wallpaper-command)
+ wallpaper--current-setter))
+ (init-action (and setter (wallpaper-setter-init-action setter)))
+ (detach (and setter (wallpaper-setter-detach setter)))
+ process)
+ (when init-action
+ (funcall init-action))
(wallpaper-debug "Using command: \"%s %s\""
- wallpaper-command (string-join real-args " "))
- (setf (process-sentinel process)
- (lambda (process status)
- (unwind-protect
- (if (and (eq (process-status process) 'exit)
- (zerop (process-exit-status process)))
- (message "Desktop wallpaper changed to %s"
- (abbreviate-file-name file))
- (message "command \"%s %s\": %S"
- (string-join (process-command process) " ")
- (string-replace "\n" "" status)
- (with-current-buffer (process-buffer process)
- (string-clean-whitespace (buffer-string)))))
- (ignore-errors
- (kill-buffer (process-buffer process))))))
+ wallpaper-command (string-join real-args " "))
+ (if detach
+ (apply #'call-process wallpaper-command nil 0 nil real-args)
+ (setq process
+ (apply #'start-process "set-wallpaper" bufname
+ wallpaper-command real-args))
+ (setf (process-sentinel process)
+ (lambda (process status)
+ (unwind-protect
+ (if (and (eq (process-status process) 'exit)
+ (zerop (process-exit-status process)))
+ (message "Desktop wallpaper changed to %s"
+ (abbreviate-file-name file))
+ (message "command \"%s %s\": %S"
+ (string-join (process-command process) " ")
+ (string-replace "\n" "" status)
+ (with-current-buffer (process-buffer process)
+ (string-clean-whitespace (buffer-string)))))
+ (ignore-errors
+ (kill-buffer (process-buffer process)))))))
process))
;;;###autoload
diff --git a/test/lisp/image/wallpaper-tests.el b/test/lisp/image/wallpaper-tests.el
index 52011fe797..cb6818f8c1 100644
--- a/test/lisp/image/wallpaper-tests.el
+++ b/test/lisp/image/wallpaper-tests.el
@@ -23,6 +23,101 @@
(require 'ert-x)
(require 'wallpaper)
+(ert-deftest wallpaper--find-setter ()
+ (skip-unless (executable-find "touch"))
+ (let (wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"))))
+ (should (wallpaper--find-setter))))
+
+(ert-deftest wallpaper--find-setter/call-predicate ()
+ (skip-unless (executable-find "touch"))
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"
+ :predicate (lambda () (setq called t))))))
+ (should-not called)
+ (wallpaper--find-setter)
+ (should called)))
+
+(ert-deftest wallpaper--find-setter/set-current-setter ()
+ (skip-unless (executable-find "touch"))
+ (let (wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"))))
+ (wallpaper--find-setter)
+ (should wallpaper--current-setter)))
+
+(ert-deftest wallpaper-set/runs-command ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil)))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (delete-file fil)
+ (let ((process (wallpaper-set fil-jpg)))
+ (while (process-live-p process)
+ (sit-for 0.001))
+ ;; Touch has recreated the file:
+ (should (file-exists-p fil)))))))
+
+(ert-deftest wallpaper-set/runs-command/detach ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil
+ :detach t)))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (delete-file fil)
+ (wallpaper-set fil-jpg)
+ (while (not (file-exists-p fil))
+ (sit-for 0.001))
+ ;; Touch has recreated the file:
+ (should (file-exists-p fil))))))
+
+(ert-deftest wallpaper-set/calls-init-action ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil
+ :init-action (lambda () (setq called t)))))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (should (functionp (wallpaper-setter-init-action wallpaper--current-setter)))
+ (wallpaper-set fil-jpg)
+ (should called)))))
+
+(ert-deftest wallpaper-set/calls-wallpaper-set-function ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "foo")))
+ (wallpaper-set-function
+ (lambda (file) (setq called file))))
+ (wallpaper--find-setter)
+ (wallpaper-set fil-jpg)
+ (should (equal called fil-jpg)))))
+
(ert-deftest wallpaper--find-command/return-string ()
(should (or (not (wallpaper--find-command))
(stringp (wallpaper--find-command)))))
--
2.30.2
next prev parent reply other threads:[~2022-10-04 5:58 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-13 20:20 bug#57781: missing wallpaper command Felix
2022-09-14 5:41 ` Stefan Kangas
2022-09-14 17:00 ` Sean Whitton
2022-09-14 22:51 ` Stefan Kangas
2022-09-14 22:51 ` Felix
2022-09-14 23:22 ` Stefan Kangas
2022-09-15 9:47 ` Felix
2022-09-16 21:09 ` Stefan Kangas
2022-09-17 12:00 ` Felix
2022-09-17 17:48 ` Stefan Kangas
2022-09-18 11:16 ` Felix
2022-09-19 9:40 ` Stefan Kangas
2022-09-18 22:19 ` Felix
2022-09-19 9:40 ` Stefan Kangas
2022-09-19 17:19 ` Felix
2022-09-19 19:16 ` Stefan Kangas
2022-09-19 19:26 ` Felix
2022-09-19 20:07 ` Stefan Kangas
2022-09-19 21:04 ` Felix
2022-09-15 10:37 ` Felix
2022-09-16 21:09 ` Stefan Kangas
2022-09-16 15:50 ` Thierry Volpiatto
2022-09-16 20:52 ` Stefan Kangas
2022-09-17 6:14 ` Thierry Volpiatto
2022-09-17 18:34 ` Stefan Kangas
2022-09-18 3:33 ` Thierry Volpiatto
2022-10-04 5:58 ` Stefan Kangas [this message]
[not found] ` <87v8owv8lc.fsf@web.de>
2022-10-07 9:08 ` Stefan Kangas
2022-10-07 19:55 ` Felix
2022-10-07 20:16 ` Stefan Kangas
2022-09-14 23:25 ` Sean Whitton
2022-09-14 13:50 ` bug#57781: wbg " Felix
2022-09-14 16:27 ` Stefan Kangas
2022-09-14 20:01 ` Felix
2022-09-14 23:06 ` Stefan Kangas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CADwFkmmdjiPkvBON3Fwb1paw66UVypb-EjJuy6Tg5QqtOM9Stg@mail.gmail.com \
--to=stefankangas@gmail.com \
--cc=57781@debbugs.gnu.org \
--cc=felix.dick@web.de \
--cc=spwhitton@spwhitton.name \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).