[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 0c114d9 3/5: Fix workspace creation and deletion
From: |
Chris Feng |
Subject: |
[elpa] externals/exwm 0c114d9 3/5: Fix workspace creation and deletion |
Date: |
Thu, 21 Jul 2016 05:06:45 +0000 (UTC) |
branch: externals/exwm
commit 0c114d97b78f806ebe2904c8f55f573fd7c879e7
Author: Chris Feng <address@hidden>
Commit: Chris Feng <address@hidden>
Fix workspace creation and deletion
* exwm-workspace.el (exwm-workspace-switch)
(exwm-workspace-switch-create): Move support for creating missing
workspaces from the former to the latter..
(exwm-workspace-switch-create-limit): New variable limiting the number
of new workspaces allowed to create each time.
* exwm-workspace.el (exwm-workspace--prompt-add)
(exwm-workspace--prompt-delete): New commands for adding and deleting
workspaces from the `read-from-minibuffer' prompt.
(exwm-workspace--prompt-add-allowed)
(exwm-workspace--prompt-delete-allowed): New variables telling whether
the above two commands are allowed to run.
(exwm-workspace--switch-map): Change "+" / "-" to use the new commands.
* exwm-workspace.el (exwm-workspace-switch, exwm-workspace-swap)
(exwm-workspace-move-window): Use this new feature.
* exwm-workspace.el (exwm-workspace-add, exwm-workspace-delete): Since
they are not used by the keymap any more, drop the use of idle timer.
* exwm-workspace.el (exwm-workspace--create-silently): New variable
indicating whether new workspaces should be created in the background.
(exwm-workspace--add-frame-as-workspace): Support creating new
workspaces in the background.
* exwm-workspace.el (exwm-workspace--on-ConfigureNotify):
Update workareas if it's not up to date.
* exwm-randr.el (exwm-randr--refresh): Raise the standalone minibuffer
when refreshed.
* exwm-config.el (exwm-config-default): Add `exwm-workspace-number' and
`exwm-workspace-switch-create'.
---
exwm-config.el | 6 ++-
exwm-randr.el | 5 +++
exwm-workspace.el | 128 +++++++++++++++++++++++++++++++++++------------------
3 files changed, 96 insertions(+), 43 deletions(-)
diff --git a/exwm-config.el b/exwm-config.el
index e1e5010..8c54607 100644
--- a/exwm-config.el
+++ b/exwm-config.el
@@ -30,6 +30,8 @@
(defun exwm-config-default ()
"Default configuration of EXWM."
+ ;; Set the initial workspace number.
+ (setq exwm-workspace-number 4)
;; Make class name the buffer name
(add-hook 'exwm-update-class-hook
(lambda ()
@@ -41,7 +43,9 @@
;; 's-N': Switch to certain workspace
(dotimes (i 10)
(exwm-input-set-key (kbd (format "s-%d" i))
- `(lambda () (interactive) (exwm-workspace-switch ,i))))
+ `(lambda ()
+ (interactive)
+ (exwm-workspace-switch-create ,i))))
;; 's-&': Launch application
(exwm-input-set-key (kbd "s-&")
(lambda (command)
diff --git a/exwm-randr.el b/exwm-randr.el
index 709469a..4ce1752 100644
--- a/exwm-randr.el
+++ b/exwm-randr.el
@@ -60,6 +60,7 @@
(declare-function exwm-workspace--count "exwm-workspace.el")
(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame))
(declare-function exwm-workspace--update-workareas "exwm-workspace.el" ())
+(declare-function exwm-workspace--show-minibuffer "exwm-workspace.el" ())
(declare-function exwm-workspace--set-desktop-geometry "exwm-workspace.el" ())
(defun exwm-randr--refresh ()
@@ -111,6 +112,10 @@
;; Resize workspace.
(dolist (f exwm-workspace--list)
(exwm-workspace--set-fullscreen f))
+ ;; Raise the minibuffer if it's active.
+ (when (and (active-minibuffer-window)
+ (exwm-workspace--minibuffer-own-frame-p))
+ (exwm-workspace--show-minibuffer))
;; Set _NET_DESKTOP_GEOMETRY.
(exwm-workspace--set-desktop-geometry)
(xcb:flush exwm--connection)
diff --git a/exwm-workspace.el b/exwm-workspace.el
index e33144e..0d63639 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -63,8 +63,8 @@ NIL if FRAME is not a workspace"
(defvar exwm-workspace--switch-map
(let ((map (make-sparse-keymap)))
(define-key map [t] (lambda () (interactive)))
- (define-key map "+" #'exwm-workspace-add)
- (define-key map "-" #'exwm-workspace-delete)
+ (define-key map "+" #'exwm-workspace--prompt-add)
+ (define-key map "-" #'exwm-workspace--prompt-delete)
(dotimes (i 10)
(define-key map (int-to-string i)
#'exwm-workspace--switch-map-nth-prefix))
@@ -105,6 +105,38 @@ NIL if FRAME is not a workspace"
:test #'equal)))
(elt exwm-workspace--list workspace-idx)))
+(defvar exwm-workspace--prompt-add-allowed nil
+ "Non-nil to allow adding workspace from the prompt.")
+(defvar exwm-workspace--prompt-delete-allowed nil
+ "Non-nil to allow deleting workspace from the prompt")
+(defvar exwm-workspace--create-silently nil
+ "When non-nil workspaces are created in the background (not switched to).")
+
+(defun exwm-workspace--prompt-add ()
+ "Add workspace from the prompt."
+ (interactive)
+ (when exwm-workspace--prompt-add-allowed
+ (let ((exwm-workspace--create-silently t))
+ (make-frame))
+ (exwm-workspace--update-switch-history)
+ (goto-history-element minibuffer-history-position)))
+
+(defun exwm-workspace--prompt-delete ()
+ "Delete workspace from the prompt."
+ (interactive)
+ (when (and exwm-workspace--prompt-delete-allowed
+ (< 1 (exwm-workspace--count)))
+ (let ((frame (elt exwm-workspace--list (1- minibuffer-history-position))))
+ (if (eq frame exwm-workspace--current)
+ ;; Abort the recursive minibuffer if deleting the current workspace.
+ (progn
+ (run-with-idle-timer 0 nil #'delete-frame frame)
+ (abort-recursive-edit))
+ (delete-frame frame)
+ (exwm-workspace--update-switch-history)
+ (goto-history-element (min minibuffer-history-position
+ (exwm-workspace--count)))))))
+
(defun exwm-workspace--update-switch-history ()
"Update the history for switching workspace to reflect the latest status."
(when exwm-workspace--switch-history-outdated
@@ -390,25 +422,16 @@ PREFIX-DIGITS is a list of the digits introduced so far."
"Normal hook run after switching workspace.")
;;;###autoload
-(cl-defun exwm-workspace-switch (frame-or-index &optional force)
+(defun exwm-workspace-switch (frame-or-index &optional force)
"Switch to workspace INDEX. Query for FRAME-OR-INDEX if it's not specified.
The optional FORCE option is for internal use only."
(interactive
(list
(unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible
- (exwm-workspace--prompt-for-workspace "Workspace [+/-]: "))))
- ;; Try to create workspace(s) when INDEX is out-of-range.
- (when (and (integerp frame-or-index)
- (>= frame-or-index (exwm-workspace--count)))
- (run-with-idle-timer 0 nil
- (lambda (times)
- (dotimes (_ times)
- (make-frame)))
- ;; Create no more than 9 workspaces.
- (min 9
- (1+ (- frame-or-index (exwm-workspace--count)))))
- (cl-return-from exwm-workspace-switch))
+ (let ((exwm-workspace--prompt-add-allowed t)
+ (exwm-workspace--prompt-delete-allowed t))
+ (exwm-workspace--prompt-for-workspace "Switch to [+/-]: ")))))
(let* ((frame (exwm-workspace--workspace-from-frame-or-index frame-or-index))
(index (exwm-workspace--position frame))
(workspace (frame-parameter frame 'exwm-workspace))
@@ -469,6 +492,23 @@ The optional FORCE option is for internal use only."
(xcb:flush exwm--connection))
(run-hooks 'exwm-workspace-switch-hook)))
+(defvar exwm-workspace-switch-create-limit 10
+ "Number of workspaces `exwm-workspace-switch-create' allowed to create
+each time.")
+
+(defun exwm-workspace-switch-create (frame-or-index)
+ "Switch to workspace FRAME-OR-INDEX, creating it if it does not exist yet."
+ (interactive)
+ (if (or (framep frame-or-index)
+ (< frame-or-index (exwm-workspace--count)))
+ (exwm-workspace-switch frame-or-index)
+ (let ((exwm-workspace--create-silently t))
+ (dotimes (_ (min exwm-workspace-switch-create-limit
+ (1+ (- frame-or-index
+ (exwm-workspace--count)))))
+ (make-frame)))
+ (exwm-workspace-switch (car (last exwm-workspace--list)))))
+
(defvar exwm-workspace-list-change-hook nil
"Normal hook run when the workspace list is changed (workspace added,
deleted, moved, etc).")
@@ -478,10 +518,14 @@ deleted, moved, etc).")
"Interchange position of WORKSPACE1 with that of WORKSPACE2."
(interactive
(unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible
- (let* ((w1 (exwm-workspace--prompt-for-workspace "Pick a workspace: "))
- (w2 (exwm-workspace--prompt-for-workspace
+ (let (w1 w2)
+ (let ((exwm-workspace--prompt-add-allowed t)
+ (exwm-workspace--prompt-delete-allowed t))
+ (setq w1 (exwm-workspace--prompt-for-workspace
+ "Pick a workspace [+/-]: ")))
+ (setq w2 (exwm-workspace--prompt-for-workspace
(format "Swap workspace %d with: "
- (exwm-workspace--position w1)))))
+ (exwm-workspace--position w1))))
(list w1 w2))))
(let ((pos1 (exwm-workspace--position workspace1))
(pos2 (exwm-workspace--position workspace2)))
@@ -544,31 +588,20 @@ before it."
INDEX must not exceed the current number of workspaces."
(interactive)
- (run-with-idle-timer
- 0 nil
- (lambda (index)
- (if (and index
- ;; No need to move if it's the last one.
- (< index (exwm-workspace--count)))
- (exwm-workspace-move (make-frame) index)
- (make-frame)))
- index)
- (when (active-minibuffer-window)
- (abort-recursive-edit)))
+ (if (and index
+ ;; No need to move if it's the last one.
+ (< index (exwm-workspace--count)))
+ (exwm-workspace-move (make-frame) index)
+ (make-frame)))
;;;###autoload
(defun exwm-workspace-delete (&optional frame-or-index)
"Delete the workspace FRAME-OR-INDEX."
(interactive)
- (run-with-idle-timer 0 nil #'delete-frame
- ;; We should not simply delete the selected frame
- ;; since it can be e.g. a floating frame.
- (if frame-or-index
- (exwm-workspace--workspace-from-frame-or-index
- frame-or-index)
- exwm-workspace--current))
- (when (active-minibuffer-window)
- (abort-recursive-edit)))
+ (delete-frame
+ (if frame-or-index
+ (exwm-workspace--workspace-from-frame-or-index frame-or-index)
+ exwm-workspace--current)))
(defun exwm-workspace--on-focus-in ()
"Handle unexpected frame switch."
@@ -601,7 +634,9 @@ INDEX must not exceed the current number of workspaces."
(defun exwm-workspace-move-window (frame-or-index &optional id)
"Move window ID to workspace FRAME-OR-INDEX."
(interactive (list
- (exwm-workspace--prompt-for-workspace "Move to: ")))
+ (let ((exwm-workspace--prompt-add-allowed t)
+ (exwm-workspace--prompt-delete-allowed t))
+ (exwm-workspace--prompt-for-workspace "Move to [+/-]: "))))
(let ((frame (exwm-workspace--workspace-from-frame-or-index frame-or-index)))
(unless id (setq id (exwm--buffer->id (window-buffer))))
(with-current-buffer (exwm--id->buffer id)
@@ -874,6 +909,9 @@ Please check `exwm-workspace--minibuffer-own-frame-p'
first."
:window window
:value-mask xcb:ConfigWindow:Height
:height height)))
+ (when (/= (exwm-workspace--count) (length exwm-workspace--workareas))
+ ;; There is a chance the workareas are not updated timely.
+ (exwm-workspace--update-workareas))
(setq workarea (elt exwm-workspace--workareas
exwm-workspace-current-index)
y (if (eq exwm-workspace-minibuffer-position 'top)
@@ -1064,8 +1102,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p'
first."
(exwm--log "Frame `%s' is floating" frame))
(t
(exwm--log "Adding frame `%s' as workspace" frame)
- (setq exwm-workspace--list (nconc exwm-workspace--list (list frame))
- exwm-workspace--current frame)
+ (setq exwm-workspace--list (nconc exwm-workspace--list (list frame)))
(let ((outer-id (string-to-number (frame-parameter frame
'outer-window-id)))
(container (xcb:generate-id exwm--connection))
@@ -1094,6 +1131,11 @@ Please check `exwm-workspace--minibuffer-own-frame-p'
first."
:override-redirect 1
:event-mask xcb:EventMask:SubstructureRedirect))
(xcb:+request exwm--connection
+ (make-instance 'xcb:ConfigureWindow
+ :window workspace
+ :value-mask xcb:ConfigWindow:StackMode
+ :stack-mode xcb:StackMode:Below))
+ (xcb:+request exwm--connection
(make-instance 'xcb:CreateWindow
:depth 0 :wid container :parent workspace
:x 0 :y 0
@@ -1129,7 +1171,9 @@ Please check `exwm-workspace--minibuffer-own-frame-p'
first."
frame 'fullscreen 'fullboth)
;; Update EWMH properties.
(exwm-workspace--update-ewmh-props)
- (exwm-workspace-switch frame t)
+ (if exwm-workspace--create-silently
+ (setq exwm-workspace--switch-history-outdated t)
+ (exwm-workspace-switch frame t))
(run-hooks 'exwm-workspace-list-change-hook))))
(defun exwm-workspace--remove-frame-as-workspace (frame)