From 683c8bade3be20c7451fbbdce9f5a6cae8a40cfd Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 25 Nov 2023 16:01:31 +0300 Subject: feat(tazjin/emacs): dynamically assign EXWM workspaces to monitors Adds an `exwm-assign-workspaces` function that automatically creates and assigns workspaces to each currently connected monitor. The first workspace (index 0) is always on the primary monitor. This function should be idempotent and can be called at any point to synchronise X outputs and what EXWM is displaying on them. This works because tabs are disconnected from workspaces completely, so I don't have to care about what's going on on other workspaces anymore. Still missing: * functions to connect/disconnect outputs * switching to other outputs from within emacs commands (i.e. without the mouse) Change-Id: I7c24aa1b45218fe35de6939e799852b5d11d1272 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10119 Reviewed-by: tazjin Autosubmit: tazjin Tested-by: BuildkiteCI --- users/tazjin/emacs/config/desktop.el | 39 ++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'users/tazjin/emacs/config') diff --git a/users/tazjin/emacs/config/desktop.el b/users/tazjin/emacs/config/desktop.el index 4c64e7e70d..28f0b59088 100644 --- a/users/tazjin/emacs/config/desktop.el +++ b/users/tazjin/emacs/config/desktop.el @@ -4,7 +4,6 @@ ;; window-management (EXWM) as well as additional system-wide ;; commands. -(require 'dash) (require 'exwm) (require 'exwm-config) (require 'exwm-randr) @@ -13,6 +12,7 @@ (require 'f) (require 'ring) (require 's) +(require 'seq) (defcustom tazjin--screen-lock-command "tazjin-screen-lock" "Command to execute for locking the screen." @@ -109,6 +109,7 @@ (fringe-mode 3) (exwm-enable) +(exwm-randr-enable) ;; Create 10 EXWM workspaces (setq exwm-workspace-number 10) @@ -251,7 +252,41 @@ ring." ;; enable display of X11 system tray within Emacs (exwm-systemtray-enable) -;; Configure xrandr (multi-monitor setup). +;; Multi-monitor configuration. +;; +;; With tab-bar-mode, each monitor only displays at most one +;; workspace. Workspaces are only created, never deleted, meaning that +;; the number of workspaces will be equivalent to the maximum number +;; of displays that were connected during a session. +;; +;; The first workspace is special: It is kept on the primary monitor. + +(defun exwm-assign-workspaces () + "Assigns workspaces to the currently existing monitors, putting +the first one on the primary display and allocating the others +dynamically if needed in no particular order." + (interactive) + (let* ((randr-monitors (exwm-randr--get-monitors)) + (primary (car randr-monitors)) + (all-monitors (seq-map #'car (cadr randr-monitors))) + (sorted-primary-first (seq-sort (lambda (a b) + (or (equal a primary) + (< a b))) + all-monitors)) + ;; assign workspace numbers to each monitor ... + (workspace-assignments + (flatten-list (seq-map-indexed (lambda (monitor idx) + (list idx monitor)) + sorted-primary-first)))) + ;; ensure that the required workspaces exist + (exwm-workspace-switch-create (- (seq-length all-monitors) 1)) + + ;; update randr config + (setq exwm-randr-workspace-monitor-plist workspace-assignments) + (exwm-randr-refresh) + + ;; leave focus on primary workspace + (exwm-workspace-switch 0))) (defun set-randr-config (screens) (setq exwm-randr-workspace-monitor-plist -- cgit 1.4.1