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