From ac236f968cff321012826d4e45b394994ede336a Mon Sep 17 00:00:00 2001 From: Thomas Ulmer Date: Tue, 3 Jun 2025 14:39:49 -0700 Subject: exwm cleanup and multi-monitor fix --- emacs/init.el | 108 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 52 deletions(-) (limited to 'emacs') diff --git a/emacs/init.el b/emacs/init.el index 30d7d54..3a8a874 100644 --- a/emacs/init.el +++ b/emacs/init.el @@ -638,31 +638,37 @@ the cyclic ordering. Don't involve windows that are dedicated." (use-package exwm-modeline) ;;(exwm-xim-mode 1) - ;; auto-populate workspace-monitor-plist - (let ((buf (generate-new-buffer "*xrandr-output*")) - (out-plist nil)) - (call-process-shell-command "xrandr --listmonitors -q" nil buf nil) - (with-current-buffer buf - (keep-lines "[^[:word:]]connected" (point-min) (point-max) nil) - ;; (message (buffer-substring (point-min) (point-max))) - (let ((num-monitors (count-lines (point-min) (point-max))) - (i 0)) - (setq exwm-workspace-number num-monitors) - (goto-char (point-min)) - (while (< i num-monitors) - (message "iter") - (move-beginning-of-line 1) - (push-mark) - (search-forward-regexp " ") - (backward-char) - (message (buffer-substring (mark) (point))) - (push (buffer-substring (mark) (point)) out-plist) - (push i out-plist) - (setq i (+ i 1)) - (pop-mark) - (next-line)))) - (kill-buffer buf) - (setq exwm-randr-workspace-monitor-plist out-plist)) + (defun my/exwm-auto-workspace-montior () + "Autopopulate exwm-randr-workspace-monitor-plist and attempt to +have a workspace on each monitor. Try to keep up with xrandr +changes." + (let ((buf (generate-new-buffer "*xrandr-output*")) + (out-plist nil)) + (call-process-shell-command "xrandr --listmonitors -q" nil buf nil) + (with-current-buffer buf + (keep-lines "[^[:word:]]connected" (point-min) (point-max) nil) + ;; (message (buffer-substring (point-min) (point-max))) + (let ((num-monitors (count-lines (point-min) (point-max))) + (i 0)) + (setq exwm-workspace-number num-monitors) + (goto-char (point-min)) + (while (< i num-monitors) + (message "iter") + (move-beginning-of-line 1) + (push-mark) + (search-forward-regexp " ") + (backward-char) + (message (buffer-substring (mark) (point))) + (push (buffer-substring (mark) (point)) out-plist) + (push i out-plist) + (setq i (+ i 1)) + (pop-mark) + (next-line)))) + (kill-buffer buf) + (setq exwm-randr-workspace-monitor-plist out-plist)) + (while (> exwm-workspace-number (length exwm-workspace--list)) + (exwm-workspace-add))) + (add-hook 'exwm-randr-screen-change-hook #'my/exwm-auto-workspace-montior) (defun my/exwm-set-buffer-name () (if exwm-title @@ -678,33 +684,30 @@ the cyclic ordering. Don't involve windows that are dedicated." (setq-local exwm-title class-and-title) (exwm-workspace-rename-buffer exwm-title)))) - (defun my/exwm-assign-workspace (index) - "switch to workspace without changing monitor" + (defun my/exwm-other-workspace (arg) + "Focus other monitor's workspace." (interactive "p") - (let* ((current-index exwm-workspace-current-index) - (current-monitor (plist-get exwm-randr-workspace-monitor-plist current-index)) - (displaced-monitor (plist-get exwm-randr-workspace-monitor-plist index))) - ;; if not associated, copy current association - (unless displaced-monitor (setq displaced-monitor current-monitor)) - ;; swapping prevents a monitor losing all of its associations - (plist-put exwm-randr-workspace-monitor-plist current-index displaced-monitor) - (plist-put exwm-randr-workspace-monitor-plist index current-monitor) - (exwm-workspace-switch-create index) - (exwm-randr-refresh))) - - (defun my/exwm-other-assigned-workspace () - "focus other monitor's workspace. Assumes 2 monitors" - (interactive) - ;; super hacky, assumes that there are only two active workspaces - (exwm-workspace-switch-create (exwm-workspace--workspace-from-frame-or-index - (let* ((workspace-list (seq-filter 'exwm-workspace--active-p exwm-workspace--list)) - (active-workspaces workspace-list)) - (while (not (eq (car active-workspaces) (selected-frame))) - (setq active-workspaces (cdr active-workspaces))) - (setq active-workspaces (cdr active-workspaces)) - (if (eq active-workspaces nil) - (car workspace-list) - (car active-workspaces)))))) + ;; based on other-frame + (let ((filter-f (function (lambda (f) + (and (exwm-workspace--active-p f) + (not (eq (selected-frame) f)))))) + (sframe (selected-frame)) + (frame (selected-frame))) + (while (> arg 0) + (setq frame (next-frame frame)) + (while (and (not (eq frame sframe)) + (not (eq (frame-visible-p frame) t)) + (filter-f frame)) + (setq frame (next-frame frame))) + (setq arg (1- arg))) + (while (< arg 0) + (setq frame (previous-frame frame)) + (while (and (not (eq frame sframe)) + (not (eq (frame-visible-p frame) t)) + (filter-f frame)) + (setq frame (previous-frame frame))) + (setq arg (1+ arg))) + (exwm-workspace-switch frame))) (defun my/dmenu (command) (interactive (list (read-shell-command "$ "))) @@ -718,6 +721,7 @@ the cyclic ordering. Don't involve windows that are dedicated." (exwm-systemtray-mode) (push ?\C-\\ exwm-input-prefix-keys) ;;C-\ to switch input method (push ?\C-u exwm-input-prefix-keys) ;; send C-u to all windows too + (push ?\M-L exwm-input-prefix-keys) (setq exwm-marked-buffer "*scratch*") ;; store the buffer we were at before a jump (when (equal window-system 'x) (exwm-enable)) @@ -741,7 +745,7 @@ the cyclic ordering. Don't involve windows that are dedicated." ;; Bind "s-w" to window switcher ([?\M-W] . consult-buffer) ([?\M-o] . other-window) - ([?\M-O] . my/exwm-other-assigned-workspace) + ([?\M-O] . my/exwm-other-workspace) ([?\M-D] . my/dmenu) ([?\M-E] . my/browser) -- cgit v1.2.3