branch: externals/lin
commit ca9bbd2b513ceea6f09602e8446b3938d3e0b31a
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>

    Add DBUS integration to sync lin-face with GNOME accent
---
 README.org |  31 +++++++++++++++++--
 lin.el     | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/README.org b/README.org
index 62513b7a23..5bb974f866 100644
--- a/README.org
+++ b/README.org
@@ -84,9 +84,9 @@ more of a reminder of the point's location on the vertical 
axis.
 #+vindex: lin-mode-hooks
 #+vindex: lin-face
 ~lin-mode~ enables ~hl-line-mode~ in the current buffer and remaps the
-appropriate face to the ~lin-face~.  The ~lin-global-mode~ follows the
-same principle, though it applies to all hooks specified in the user
-option ~lin-mode-hooks~.
+appropriate face to the ~lin-face~ 
([[#h:2e28af52-8302-4071-a53e-f282f54a862e][Integration with the GNOME accent 
color picker]]).
+The ~lin-global-mode~ follows the same principle, though it applies to
+all hooks specified in the user option ~lin-mode-hooks~.
 
 #+vindex: lin-blue
 #+vindex: lin-red
@@ -119,6 +119,31 @@ The user option ~lin-remap-current-line-number~ controls 
whether to
 apply the Lin style also to the currently highlighted line number.
 Line numbers come from the built-in ~display-line-numbers-mode~.
 
+* Integration with the GNOME accent color picker
+:PROPERTIES:
+:CUSTOM_ID: h:2e28af52-8302-4071-a53e-f282f54a862e
+:END:
+#+cindex: Match the Lin face to the GNOME accent color
+
+#+findex: lin-gnome-accent-color-mode
+The GNOME desktop environment provides a setting to pick an accent
+color. This is then applied by applications to add a personal touch to
+the user's experience. Lin can now read this color and automatically
+update all the buffers it is enabled in via the minor mode 
~lin-gnome-accent-color-mode~.
+
+When ~lin-gnome-accent-color-mode~ is enabled, Lin reads the accent
+color of GNOME and sets the corresponding Lin face. For example, if
+the user picks red in the GNOME settings, the ~lin-face~ will be set
+to ~lin-red~.
+
+#+vindex: lin-gnome-accent-color-override-foreground
+The user option ~lin-gnome-accent-color-override-foreground~ controls
+whether the faces that correspond to GNOME accent colors should
+override the underlying text color or not. This is useful for improved
+color contrast. The default is to not override the foreground. Setting
+~lin-gnome-accent-color-override-foreground~ to non-~nil~ changes that
+so, for example, the ~lin-face~ will be set to ~lin-red-override-fg~.
+
 * Installation
 :PROPERTIES:
 :CUSTOM_ID: h:7b68abd3-a854-4b72-b704-05ca013dfa7f
diff --git a/lin.el b/lin.el
index 5d5a9b859d..2a8c64b15d 100644
--- a/lin.el
+++ b/lin.el
@@ -154,6 +154,16 @@ Line numbers come from the `display-line-numbers-mode'."
   :package-version '(lin . "1.1.0")
   :group 'lin)
 
+(defcustom lin-gnome-accent-color-override-foreground nil
+  "When non-nil override the text color in `lin-gnome-accent-color-mode'.
+This means that the Lin face that is used to match the GNOME accent
+color will use a :foreground attribute of its own.
+
+When nil (the default), allow the underlying text to retain its color."
+  :type 'boolean
+  :package-version '(lin . "2.0.0")
+  :group 'lin)
+
 ;;;; Faces
 
 (defgroup lin-faces ()
@@ -467,6 +477,96 @@ is a member of `lin-mode-hooks'."
   "Disable `lin-mode' in `lin--non-hidden-buffers'."
   (mapc #'lin--mode-disable (lin--non-hidden-buffers)))
 
-(provide 'lin)
+;;;; Dbus integration with GNOME
+
+(defun lin-gnome--get-gsettings-accent-color ()
+  "Return accent color value using the gsettings program."
+  (unless (executable-find "gsettings")
+    (error "The `gsettings' program is not available"))
+  (shell-command-to-string "gsettings get org.gnome.desktop.interface 
accent-color"))
+
+(defconst lin-gnome-accent-colors
+  ;; NOTE 2026-02-12: This is in the order they appear in the Gnome settings 
under "Appearance".
+  '("blue" "teal" "green" "yellow" "orange" "red" "pink" "purple" "slate")
+  "Names of accent colors used by the GNOME desktop environment.")
+
+(defun lin-gnome--get-accent-color-string (accent)
+  "Return the string that corresponds to GNOME's ACCENT color."
+  (seq-find
+   (lambda (color)
+     (string-match-p color accent))
+   lin-gnome-accent-colors))
+
+(defun lin--get-face-for-accent-color (accent)
+  "Return face matching ACCENT color among `lin-gnome-accent-colors'."
+  (let ((color (lin-gnome--get-accent-color-string accent)))
+    (if lin-gnome-accent-color-override-foreground
+        (pcase color
+          ("blue" 'lin-blue-override-fg)
+          ("teal" 'lin-cyan-override-fg)
+          ("green" 'lin-green-override-fg)
+          ("yellow" 'lin-yellow-override-fg)
+          ("orange" 'lin-orange-override-fg)
+          ("red" 'lin-red-override-fg)
+          ("pink" 'lin-magenta-override-fg)
+          ("purple" 'lin-purple-override-fg)
+          ("slate" 'lin-slate-override-fg))
+      (pcase color
+        ("blue" 'lin-blue)
+        ("teal" 'lin-cyan)
+        ("green" 'lin-green)
+        ("yellow" 'lin-yellow)
+        ("orange" 'lin-orange)
+        ("red" 'lin-red)
+        ("pink" 'lin-magenta)
+        ("purple" 'lin-purple)
+        ("slate" 'lin-slate)))))
+
+(defvar lin--dbus-object nil
+  "DBus object for GNOME accent color changes.")
+
+(defun lin-gnome-accent-color-changed-handler (namespace key value)
+  "Handle D-Bus signal for accent color change.
+NAMESPACE is the gsettings path as a string.  KEY is the specific domain
+as a string.  VALUE is what corresponds to KEY, as a list of strings."
+  (when (and (string= namespace "org.gnome.desktop.interface")
+             (string= key "accent-color"))
+    (let* ((accent-color (car value))
+           (face (lin--get-face-for-accent-color accent-color)))
+      (when face
+        (setq lin-face face)
+        (lin-enable-mode-in-buffers)
+        (message "Update Lin to use GNOME's `%s' color"
+                 (propertize accent-color 'face face))))))
+
+(declare-function dbus-unregister-object "dbus" (object))
 
+;;;###autoload
+(define-minor-mode lin-gnome-accent-color-mode
+  "Toggle syncing of `lin-face' with the GNOME accent color picker."
+  :global t
+  :init-value nil
+  (require 'dbus)
+  (if lin-gnome-accent-color-mode
+      (progn
+        (when (and (executable-find "gsettings")
+                   (fboundp 'dbus-register-signal)
+                   (null lin--dbus-object))
+          (setq lin--dbus-object
+                (dbus-register-signal
+                 :session
+                 "org.freedesktop.portal.Desktop"
+                 "/org/freedesktop/portal/desktop"
+                 "org.freedesktop.portal.Settings"
+                 "SettingChanged"
+                 #'lin-gnome-accent-color-changed-handler))
+          (when-let* ((current-accent (lin-gnome--get-gsettings-accent-color))
+                      (face (lin--get-face-for-accent-color current-accent)))
+            (setq lin-face face)
+            (lin-enable-mode-in-buffers))))
+    (when lin--dbus-object
+      (dbus-unregister-object lin--dbus-object)
+      (setq lin--dbus-object nil))))
+
+(provide 'lin)
 ;;; lin.el ends here

Reply via email to