Fix issues with moving X windows between workspaces

* exwm-workspace.el (exwm-workspace-move-window): Select the moved floating
X window.  Update the 'exwm-selected-window' frame parameter.
(exwm-workspace-switch): Check 'exwm-selected-window' for dead windows.
(exwm-workspace-switch-to-buffer): Allow non-interactive call.
This commit is contained in:
Chris Feng 2016-02-24 20:55:01 +08:00
parent 4838f2b7fa
commit 84bdc1378a

View file

@ -178,7 +178,8 @@ The optional FORCE option is for internal use only."
(user-error "[EXWM] Workspace index out of range: %d" index)) (user-error "[EXWM] Workspace index out of range: %d" index))
(when (or force (/= exwm-workspace-current-index index)) (when (or force (/= exwm-workspace-current-index index))
(let* ((frame (elt exwm-workspace--list index)) (let* ((frame (elt exwm-workspace--list index))
(workspace (frame-parameter frame 'exwm-workspace))) (workspace (frame-parameter frame 'exwm-workspace))
(window (frame-parameter frame 'exwm-selected-window)))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window workspace :window workspace
@ -191,7 +192,7 @@ The optional FORCE option is for internal use only."
(set-frame-parameter (with-current-buffer (window-buffer) (set-frame-parameter (with-current-buffer (window-buffer)
exwm--frame) exwm--frame)
'exwm-selected-window (selected-window))) 'exwm-selected-window (selected-window)))
(select-window (or (frame-parameter frame 'exwm-selected-window) (select-window (or (when (window-live-p window) window)
(frame-selected-window frame))) (frame-selected-window frame)))
(set-frame-parameter frame 'exwm-selected-window nil) (set-frame-parameter frame 'exwm-selected-window nil)
;; Close the (possible) active minibuffer ;; Close the (possible) active minibuffer
@ -231,6 +232,7 @@ The optional FORCE option is for internal use only."
(defvar exwm-floating-border-width) (defvar exwm-floating-border-width)
(defvar exwm-floating-border-color) (defvar exwm-floating-border-color)
(declare-function exwm-layout--show "exwm-layout.el" (id))
(declare-function exwm-layout--hide "exwm-layout.el" (id)) (declare-function exwm-layout--hide "exwm-layout.el" (id))
(declare-function exwm-layout--refresh "exwm-layout.el") (declare-function exwm-layout--refresh "exwm-layout.el")
@ -274,7 +276,10 @@ The optional FORCE option is for internal use only."
(frame-parameter frame 'exwm-workspace) (frame-parameter frame 'exwm-workspace)
:x x :y y)) :x x :y y))
(xcb:flush exwm--connection) (xcb:flush exwm--connection)
(unless (exwm-workspace--minibuffer-own-frame-p) (if (exwm-workspace--minibuffer-own-frame-p)
(when (= index exwm-workspace-current-index)
(select-frame-set-input-focus exwm--floating-frame)
(exwm-layout--refresh))
;; The frame needs to be recreated since it won't use the ;; The frame needs to be recreated since it won't use the
;; minibuffer on the new workspace. ;; minibuffer on the new workspace.
(let* ((old-frame exwm--floating-frame) (let* ((old-frame exwm--floating-frame)
@ -326,19 +331,29 @@ The optional FORCE option is for internal use only."
(add-hook 'window-configuration-change-hook (add-hook 'window-configuration-change-hook
#'exwm-layout--refresh) #'exwm-layout--refresh)
(delete-frame old-frame) (delete-frame old-frame)
(set-window-dedicated-p window t)) (set-window-dedicated-p window t)
(make-frame-visible new-frame) (exwm-layout--show id window))
(with-selected-frame new-frame
(exwm-layout--refresh)))))
;; Move the X window container.
(if (/= index exwm-workspace-current-index) (if (/= index exwm-workspace-current-index)
(bury-buffer) (make-frame-visible new-frame)
(select-frame-set-input-focus new-frame)
(redisplay))))
;; Update the 'exwm-selected-window' frame parameter.
(when (/= index exwm-workspace-current-index)
(with-current-buffer (exwm--id->buffer id)
(set-frame-parameter frame 'exwm-selected-window
(frame-root-window
exwm--floating-frame)))))
;; Move the X window container.
(if (= index exwm-workspace-current-index)
(set-window-buffer (get-buffer-window (current-buffer) t) (set-window-buffer (get-buffer-window (current-buffer) t)
(or (get-buffer "*scratch*") (or (get-buffer "*scratch*")
(progn (progn
(set-buffer-major-mode (set-buffer-major-mode
(get-buffer-create "*scratch*")) (get-buffer-create "*scratch*"))
(get-buffer "*scratch*"))))) (get-buffer "*scratch*"))))
(bury-buffer)
;; Clear the 'exwm-selected-window' frame parameter.
(set-frame-parameter frame 'exwm-selected-window nil))
(exwm-layout--hide id) (exwm-layout--hide id)
;; (current-buffer) is changed. ;; (current-buffer) is changed.
(with-current-buffer (exwm--id->buffer id) (with-current-buffer (exwm--id->buffer id)
@ -362,30 +377,33 @@ The optional FORCE option is for internal use only."
(setq exwm-workspace--switch-history-outdated t))) (setq exwm-workspace--switch-history-outdated t)))
;;;###autoload ;;;###autoload
(defun exwm-workspace-switch-to-buffer () (defun exwm-workspace-switch-to-buffer (buffer-or-name)
"Make the current Emacs window display another buffer." "Make the current Emacs window display another buffer."
(interactive) (interactive
(let ((inhibit-quit t))
;; Show all buffers ;; Show all buffers
(unless exwm-workspace-show-all-buffers (unless exwm-workspace-show-all-buffers
(dolist (pair exwm--id-buffer-alist) (dolist (pair exwm--id-buffer-alist)
(with-current-buffer (cdr pair) (with-current-buffer (cdr pair)
(when (= ?\s (aref (buffer-name) 0)) (when (= ?\s (aref (buffer-name) 0))
(rename-buffer (substring (buffer-name) 1)))))) (rename-buffer (substring (buffer-name) 1))))))
(let ((buffer (read-buffer "Switch to buffer: " nil t))) (prog1
(when buffer (with-local-quit
(with-current-buffer buffer (list (get-buffer (read-buffer "Switch to buffer: " nil t))))
(if (and (eq major-mode 'exwm-mode)
(not (eq exwm--frame exwm-workspace--current)))
(exwm-workspace-move-window exwm-workspace-current-index
exwm--id)
(switch-to-buffer buffer)))))
;; Hide buffers on other workspaces ;; Hide buffers on other workspaces
(unless exwm-workspace-show-all-buffers (unless exwm-workspace-show-all-buffers
(dolist (pair exwm--id-buffer-alist) (dolist (pair exwm--id-buffer-alist)
(with-current-buffer (cdr pair) (with-current-buffer (cdr pair)
(unless (or (eq exwm--frame exwm-workspace--current) (unless (or (eq exwm--frame exwm-workspace--current)
(= ?\s (aref (buffer-name) 0))) (= ?\s (aref (buffer-name) 0)))
(rename-buffer (concat " " (buffer-name)))))))) (rename-buffer (concat " " (buffer-name))))))))))
(when buffer-or-name
(with-current-buffer buffer-or-name
(if (and (eq major-mode 'exwm-mode)
(not (eq exwm--frame exwm-workspace--current)))
(exwm-workspace-move-window exwm-workspace-current-index
exwm--id)
(switch-to-buffer buffer-or-name)))))
(defun exwm-workspace-rename-buffer (newname) (defun exwm-workspace-rename-buffer (newname)
"Rename a buffer." "Rename a buffer."