aboutsummaryrefslogtreecommitdiff
path: root/modules/auto-dim-config.el
diff options
context:
space:
mode:
Diffstat (limited to 'modules/auto-dim-config.el')
-rw-r--r--modules/auto-dim-config.el186
1 files changed, 7 insertions, 179 deletions
diff --git a/modules/auto-dim-config.el b/modules/auto-dim-config.el
index ebda92c2..c0e6e7a1 100644
--- a/modules/auto-dim-config.el
+++ b/modules/auto-dim-config.el
@@ -18,179 +18,16 @@
;; debounce). The dimmed faces (auto-dim-other-buffers and
;; auto-dim-other-buffers-hide) live in the active theme
;; (themes/dupre-faces.el) so they track theme switches.
+;;
+;; Terminal buffers (ghostel) do not participate in window dimming: ghostel
+;; bakes its color palette into the native module per-terminal, not per-window,
+;; so there is no per-window color hook to dim through (the vterm engine had
+;; one via `vterm--get-color', which this module used to advise). See the
+;; terminal-migration follow-up task in todo.org for revisiting this.
;;; Code:
-(require 'cl-lib)
-(require 'color)
-
(declare-function auto-dim-other-buffers-mode "auto-dim-other-buffers")
-(declare-function adob--update "auto-dim-other-buffers")
-(declare-function vterm--get-color "vterm")
-(declare-function vterm--invalidate "vterm")
-(declare-function vterm--set-size "vterm")
-(declare-function vterm--get-margin-width "vterm")
-(defvar vterm-min-window-width)
-(defvar vterm--term)
-
-(defvar cj/auto-dim--last-selected-window nil
- "Most recent selected window seen by `cj/auto-dim--refresh-vterm-on-command'.")
-
-(defvar cj/auto-dim--vterm-refresh-timer nil
- "Timer used to defer vterm redraws until after auto-dim updates.")
-
-(defcustom cj/auto-dim-vterm-foreground-blend 0.45
- "Blend amount for dimmed vterm foreground colors.
-
-0 keeps the original vterm color; 1 uses the
-`auto-dim-other-buffers' foreground color."
- :type 'number
- :group 'auto-dim-other-buffers)
-
-(defcustom cj/auto-dim-vterm-background-blend 0.7
- "Blend amount for dimmed vterm background colors.
-
-0 keeps the original vterm color; 1 uses the
-`auto-dim-other-buffers' background color."
- :type 'number
- :group 'auto-dim-other-buffers)
-
-(defun cj/auto-dim--vterm-buffer-dimmed-p ()
- "Return non-nil when the current vterm buffer should render dimmed.
-
-Vterm resolves terminal colors to concrete color strings while redrawing the
-buffer, so this integration is buffer-level. If the same vterm buffer is shown
-in multiple windows and any one of those windows is selected/undimmed, keep the
-buffer bright."
- (and (eq major-mode 'vterm-mode)
- (let ((windows (get-buffer-window-list (current-buffer) nil 'visible)))
- (and windows
- (not (catch 'undimmed
- (dolist (window windows)
- (unless (window-parameter window 'adob--dim)
- (throw 'undimmed t)))))))))
-
-(defun cj/auto-dim--face-color (face attribute fallback-face)
- "Return FACE ATTRIBUTE, falling back to FALLBACK-FACE."
- (let ((color (face-attribute face attribute nil 'default)))
- (if (or (null color) (eq color 'unspecified))
- (face-attribute fallback-face attribute nil 'default)
- color)))
-
-(defun cj/auto-dim--color-rgb (color)
- "Return COLOR as a list of RGB floats, or nil if COLOR is unknown."
- (cond
- ((and (stringp color)
- (string-match
- "\\`#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\'"
- color))
- (mapcar (lambda (index)
- (/ (string-to-number (match-string index color) 16) 255.0))
- '(1 2 3)))
- ((and (stringp color)
- (string-match
- "\\`#\\([[:xdigit:]]\\)\\([[:xdigit:]]\\)\\([[:xdigit:]]\\)\\'"
- color))
- (mapcar (lambda (index)
- (/ (* 17 (string-to-number (match-string index color) 16)) 255.0))
- '(1 2 3)))
- (t
- (ignore-errors
- (mapcar (lambda (component) (/ component 65535.0))
- (color-values color))))))
-
-(defun cj/auto-dim--blend-color (color target amount)
- "Blend COLOR toward TARGET by AMOUNT and return a hex color string."
- (if-let* ((rgb (cj/auto-dim--color-rgb color))
- (target-rgb (cj/auto-dim--color-rgb target)))
- (apply #'color-rgb-to-hex
- (append
- (cl-mapcar
- (lambda (source dest)
- (+ (* source (- 1 amount)) (* dest amount)))
- rgb target-rgb)
- '(2)))
- color))
-
-(defun cj/auto-dim--vterm-dim-color (color foreground-p)
- "Return dimmed vterm COLOR.
-
-When FOREGROUND-P is non-nil, blend toward the dimmed foreground face; otherwise
-blend toward the dimmed background face."
- (let* ((attribute (if foreground-p :foreground :background))
- (target (cj/auto-dim--face-color 'auto-dim-other-buffers attribute 'default))
- (amount (if foreground-p
- cj/auto-dim-vterm-foreground-blend
- cj/auto-dim-vterm-background-blend)))
- (cj/auto-dim--blend-color color target amount)))
-
-(defun cj/auto-dim--vterm-get-color (orig-fun index &rest args)
- "Advise vterm color lookup ORIG-FUN for dimmed windows.
-
-INDEX and ARGS are passed through to `vterm--get-color'."
- (let ((color (apply orig-fun index args)))
- (if (and color (cj/auto-dim--vterm-buffer-dimmed-p))
- (cj/auto-dim--vterm-dim-color color (memq :foreground args))
- color)))
-
-(defun cj/auto-dim--refresh-vterm-windows (&optional frame)
- "Refresh visible vterm buffers in FRAME after dim state changes."
- (when (or (fboundp 'vterm--set-size) (fboundp 'vterm--invalidate))
- (dolist (window (window-list frame 'no-minibuf))
- (with-current-buffer (window-buffer window)
- (when (eq major-mode 'vterm-mode)
- (let ((inhibit-read-only t))
- (if (and (bound-and-true-p vterm--term)
- (window-live-p window)
- (fboundp 'vterm--get-margin-width))
- (let* ((height (max 2 (window-body-height window)))
- (min-width (if (boundp 'vterm-min-window-width)
- vterm-min-window-width
- 80))
- (width (max min-width
- (- (window-body-width window)
- (vterm--get-margin-width)))))
- ;; `vterm--redraw' only repaints rows libvterm marked dirty.
- ;; A resize marks the whole terminal grid dirty, so briefly
- ;; nudge height and restore it to force a full repaint after
- ;; dim-state changes.
- (vterm--set-size vterm--term (1+ height) width)
- (vterm--set-size vterm--term height width))
- (when (fboundp 'vterm--invalidate)
- (vterm--invalidate)))))))))
-
-(defun cj/auto-dim--refresh-vterm-after-auto-dim (&optional frame)
- "Update auto-dim state, then refresh visible vterm buffers in FRAME."
- (setq cj/auto-dim--vterm-refresh-timer nil)
- (when (fboundp 'adob--update)
- (adob--update))
- (cj/auto-dim--refresh-vterm-windows frame))
-
-(defun cj/auto-dim--schedule-vterm-refresh (&optional frame)
- "Schedule a deferred vterm refresh for FRAME.
-
-The delay lets selection-changing commands finish before we recompute
-auto-dim state and invalidate vterm."
- (when cj/auto-dim--vterm-refresh-timer
- (cancel-timer cj/auto-dim--vterm-refresh-timer))
- (setq cj/auto-dim--vterm-refresh-timer
- (run-with-timer 0 nil #'cj/auto-dim--refresh-vterm-after-auto-dim frame)))
-
-(defun cj/auto-dim--refresh-vterm-on-command ()
- "Refresh visible vterm buffers when selected window changes.
-
-`window-selection-change-functions' does not catch every selection path used by
-windmove/Shift-arrow focus changes in this config, so this post-command hook is
-the fallback that makes vterm repaint after auto-dim changes window state."
- (let ((window (selected-window)))
- (unless (eq window cj/auto-dim--last-selected-window)
- (setq cj/auto-dim--last-selected-window window)
- (cj/auto-dim--schedule-vterm-refresh))))
-
-(defun cj/auto-dim--after-select-window (&rest _)
- "Schedule vterm refresh after `select-window'."
- (setq cj/auto-dim--last-selected-window (selected-window))
- (cj/auto-dim--schedule-vterm-refresh))
(defun cj/auto-dim--never-dim-dashboard-p (buffer)
"Return non-nil when BUFFER is the dashboard, so it stays lit.
@@ -212,7 +49,7 @@ focus cue on a split-displayed dashboard, accepted as a fair trade."
:custom
;; Dim only non-selected windows within Emacs, not the whole frame when
;; Emacs loses focus -- on Hyprland focus moves to other apps constantly,
- ;; and the ai-vterm agents live in their own windows.
+ ;; and the ai-term agents live in their own windows.
(auto-dim-other-buffers-dim-on-focus-out nil)
(auto-dim-other-buffers-dim-on-switch-to-minibuffer t)
:config
@@ -259,14 +96,5 @@ focus cue on a split-displayed dashboard, accepted as a fair trade."
#'cj/auto-dim--never-dim-dashboard-p)
(auto-dim-other-buffers-mode 1))
-(with-eval-after-load 'vterm
- (unless (advice-member-p #'cj/auto-dim--vterm-get-color #'vterm--get-color)
- (advice-add #'vterm--get-color :around #'cj/auto-dim--vterm-get-color))
- (unless (advice-member-p #'cj/auto-dim--after-select-window #'select-window)
- (advice-add #'select-window :after #'cj/auto-dim--after-select-window))
- (add-hook 'window-selection-change-functions
- #'cj/auto-dim--schedule-vterm-refresh)
- (add-hook 'post-command-hook #'cj/auto-dim--refresh-vterm-on-command))
-
(provide 'auto-dim-config)
;;; auto-dim-config.el ends here