From f70c35af6d57c8b29fd2ecf3e674f89f9a48877f Mon Sep 17 00:00:00 2001 From: Ian Keane Date: Sun, 9 Aug 2026 15:28:47 -0400 Subject: [PATCH] Compositing, transparency --- config/stumpwm/config.lisp | 94 +++++++++++++++++++++++++++++++++++++- config/xinitrc | 3 ++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/config/stumpwm/config.lisp b/config/stumpwm/config.lisp index dd1dcd4..7cf2fa7 100644 --- a/config/stumpwm/config.lisp +++ b/config/stumpwm/config.lisp @@ -238,6 +238,21 @@ If PERSISTENT is t, smart-kill will hide the window instead of killing it." (height (nth 5 rule))) (stumpwm::float-window-move-resize win :x x :y y :width width :height height)))))) +;; StumpWM keeps non-focused windows within the same frame mapped (stacked +;; behind the current one) rather than unmapping them like most tiling WMs. +;; This causes other windows to bleed through when transparency is used. +;; This hook hides all frame siblings when focus changes so only the +;; focused window and the wallpaper are visible through any transparency. +(add-hook *focus-window-hook* + (lambda (new old) + (declare (ignore old)) + (when new + (let* ((group (window-group new)) + (frame (window-frame new)) + (siblings (remove new (frame-windows group frame)))) + (mapc #'hide-window siblings) + (unhide-window new))))) + (defun spawn-or-focus (class command) "Unhide or focus existing window with CLASS, or spawn COMMAND if none exists." (let ((win (find-if (lambda (w) (string= (window-class w) class)) @@ -272,8 +287,85 @@ If PERSISTENT is t, smart-kill will hide the window instead of killing it." "Open ncmpcpp in a persistent floating wezterm window." (spawn-or-focus "ncmpcpp-scratch" "wezterm start --class ncmpcpp-scratch -- ncmpcpp")) ;;; Config keymap -(defvar *config-map* (make-sparse-keymap)) +;;; Appearance sub-map (s-W t / s-W T) +(defvar *appearance-map* (make-sparse-keymap)) +(defvar *appearance-all-map* (make-sparse-keymap)) + +;; Global opacity — stored so new windows can inherit it via *new-window-hook* +(defvar *global-opacity* nil) + +;; Per-window opacity via picom-trans -c (current focused window) +(defmacro make-opacity-command (name opacity) + `(defcommand ,name () () + ,(format nil "Set current window opacity to ~a%." opacity) + (run-shell-command (format nil "picom-trans -c ~a" ,opacity)))) + +;; Global opacity — sets all existing windows and stores value for new ones +(defmacro make-global-opacity-command (name opacity) + `(defcommand ,name () () + ,(format nil "Set ALL windows opacity to ~a%." opacity) + (setf *global-opacity* ,opacity) + (dolist (w (screen-windows (current-screen))) + (run-shell-command + (format nil "picom-trans -w ~a ~a" + (xlib:window-id (window-xwin w)) ,opacity))))) + +;; Apply global opacity to new windows as they appear +(add-hook *new-window-hook* + (lambda (win) + (when *global-opacity* + (run-shell-command + (format nil "picom-trans -w ~a ~a" + (xlib:window-id (window-xwin win)) *global-opacity*))))) + +(make-opacity-command opacity-10 10) +(make-opacity-command opacity-20 20) +(make-opacity-command opacity-30 30) +(make-opacity-command opacity-40 40) +(make-opacity-command opacity-50 50) +(make-opacity-command opacity-60 60) +(make-opacity-command opacity-70 70) +(make-opacity-command opacity-80 80) +(make-opacity-command opacity-90 90) +(make-opacity-command opacity-100 100) + +(make-global-opacity-command global-opacity-10 10) +(make-global-opacity-command global-opacity-20 20) +(make-global-opacity-command global-opacity-30 30) +(make-global-opacity-command global-opacity-40 40) +(make-global-opacity-command global-opacity-50 50) +(make-global-opacity-command global-opacity-60 60) +(make-global-opacity-command global-opacity-70 70) +(make-global-opacity-command global-opacity-80 80) +(make-global-opacity-command global-opacity-90 90) +(make-global-opacity-command global-opacity-100 100) + +(define-key *appearance-map* (kbd "1") "opacity-10") +(define-key *appearance-map* (kbd "2") "opacity-20") +(define-key *appearance-map* (kbd "3") "opacity-30") +(define-key *appearance-map* (kbd "4") "opacity-40") +(define-key *appearance-map* (kbd "5") "opacity-50") +(define-key *appearance-map* (kbd "6") "opacity-60") +(define-key *appearance-map* (kbd "7") "opacity-70") +(define-key *appearance-map* (kbd "8") "opacity-80") +(define-key *appearance-map* (kbd "9") "opacity-90") +(define-key *appearance-map* (kbd "0") "opacity-100") + +(define-key *appearance-all-map* (kbd "1") "global-opacity-10") +(define-key *appearance-all-map* (kbd "2") "global-opacity-20") +(define-key *appearance-all-map* (kbd "3") "global-opacity-30") +(define-key *appearance-all-map* (kbd "4") "global-opacity-40") +(define-key *appearance-all-map* (kbd "5") "global-opacity-50") +(define-key *appearance-all-map* (kbd "6") "global-opacity-60") +(define-key *appearance-all-map* (kbd "7") "global-opacity-70") +(define-key *appearance-all-map* (kbd "8") "global-opacity-80") +(define-key *appearance-all-map* (kbd "9") "global-opacity-90") +(define-key *appearance-all-map* (kbd "0") "global-opacity-100") + (define-key *config-map* (kbd "a") "alsamixer-float") + +(define-key *window-map* (kbd "t") *appearance-map*) +(define-key *window-map* (kbd "T") *appearance-all-map*) (defvar *brightness-map* (make-sparse-keymap)) (define-key *brightness-map* (kbd "1") "brightness-10") (define-key *brightness-map* (kbd "2") "brightness-20") diff --git a/config/xinitrc b/config/xinitrc index c8a7b8a..217549c 100644 --- a/config/xinitrc +++ b/config/xinitrc @@ -11,4 +11,7 @@ pipewire & pipewire-pulse & wireplumber & +# Compositor - eliminates screen tearing +picom --backend glx --vsync & + exec stumpwm