branch: externals/exwm
commit 5c89ff82dbc6e839908e8f4042c29ec1d2d7a3ec
Author: Steven Allen <[email protected]>
Commit: Steven Allen <[email protected]>
Refuse to delete active workspaces when there all are active
Deleting a workspace in this case will attempt to "steal" a workspace
from another monitor. This will fail and we'll end up re-creating a
workspace, causing us to juggle workspaces around.
An alternative would be to ALLOW ourselves to delete the workspace in
this case, but refuse to steal an active workspace to replace it AND
refuse to re-create it. But, IMO, the user likely wants one workspace
per monitor and would rather not delete the last workspace on a monitor
when there are none available to replace it.
* exwm-workspace.el (exwm-workspace-delete): Refuse to delete thej
current workspace if we don't have any to replace it.
(exwm-workspace--get-next-workspace): Make it possible to get the next
workspace, including active workspaces.
---
exwm-workspace.el | 41 +++++++++++++++++++++++------------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/exwm-workspace.el b/exwm-workspace.el
index 953d68c482..cc9c0625ee 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -797,17 +797,20 @@ INDEX must not exceed the current number of workspaces."
"Delete the workspace FRAME-OR-INDEX."
(interactive)
(exwm--log "%s" frame-or-index)
- (when (< 1 (exwm-workspace--count))
- (let ((frame (if frame-or-index
- (exwm-workspace--workspace-from-frame-or-index
- frame-or-index)
- exwm-workspace--current)))
- ;; Transfer over any surrogate minibuffers before trying to delete the
workspace.
- (let ((minibuf (minibuffer-window frame))
- (newminibuf (minibuffer-window (exwm-workspace--get-next-workspace
frame))))
- (dolist (f (filtered-frame-list (lambda (f) (eq (frame-parameter f
'minibuffer) minibuf))))
- (set-frame-parameter f 'minibuffer newminibuf)))
- (delete-frame frame))))
+ (if-let* ((frame (if frame-or-index
+ (exwm-workspace--workspace-from-frame-or-index
+ frame-or-index)
+ exwm-workspace--current))
+ (next-frame (exwm-workspace--get-next-workspace
+ frame (not (exwm-workspace--active-p frame)))))
+ (progn
+ ;; Transfer over any surrogate minibuffers before trying to delete the
workspace.
+ (let ((minibuf (minibuffer-window frame))
+ (newminibuf (minibuffer-window next-frame)))
+ (dolist (f (filtered-frame-list (lambda (f) (eq (frame-parameter f
'minibuffer) minibuf))))
+ (set-frame-parameter f 'minibuffer newminibuf)))
+ (delete-frame frame))
+ (error "All other workspaces are active")))
(defun exwm-workspace--set-desktop (id)
"Set _NET_WM_DESKTOP for X window ID."
@@ -1375,22 +1378,24 @@ ALIST is an action alist, as accepted by function
`display-buffer'."
frame exwm-workspace-current-index original-index))
(run-hooks 'exwm-workspace-list-change-hook)))
-(defun exwm-workspace--get-next-workspace (frame)
+(defun exwm-workspace--get-next-workspace (frame &optional allow-active)
"Return the next workspace if workspace FRAME were removed.
-Return nil there are no other worksapces and/or all other workspaces
-are currently visible on other monitors."
+Return nil there are no other worksapces or ALLOW-ACTIVE is non-nil and
+all other workspaces are currently visible on other monitors."
(let* ((index (exwm-workspace--position frame))
(count (exwm-workspace--count)))
(or
(cl-loop for i from (1+ index) below count
for nextw = (elt exwm-workspace--list i)
- unless (or (eq frame nextw)
- (exwm-workspace--active-p nextw))
+ when (and (not (eq frame nextw))
+ (or allow-active
+ (exwm-workspace--active-p nextw)))
return nextw)
(cl-loop for i from (1- index) downto 0
for nextw = (elt exwm-workspace--list i)
- unless (or (eq frame nextw)
- (exwm-workspace--active-p nextw))
+ when (and (not (eq frame nextw))
+ (or allow-active
+ (exwm-workspace--active-p nextw)))
return nextw))))
(defun exwm-workspace--remove-frame-as-workspace (frame &optional quit)