Work with workspace frames instead of indices

* exwm.el (exwm--on-ClientMessage):
	* exwm-workspace.el (exwm-workspace-switch)
	(exwm-workspace-move-window, exwm-workspace-switch-to-buffer):
	* exwm-layout.el (exwm-layout--refresh):
	* exwm-input.el (exwm-input--update-focus)
	(exwm-input--on-ButtonPress): Accept frame as well as workspace
	index as argument.
	* exwm-workspace.el
	(exwm-workspace--workspace-from-frame-or-index): New function.
This commit is contained in:
Adrián Medraño Calvo 2016-07-17 12:00:00 +00:00
parent 35e1655dc5
commit 07120a0562
6 changed files with 114 additions and 110 deletions

View file

@ -126,7 +126,7 @@
(declare-function exwm-layout-set-fullscreen "exwm-layout.el" (&optional id)) (declare-function exwm-layout-set-fullscreen "exwm-layout.el" (&optional id))
(declare-function exwm-layout-toggle-mode-line "exwm-layout.el") (declare-function exwm-layout-toggle-mode-line "exwm-layout.el")
(declare-function exwm-workspace-move-window "exwm-workspace.el" (declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id)) (frame-or-index &optional id))
(defvar exwm-mode-map (defvar exwm-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))

View file

@ -104,7 +104,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(declare-function exwm-layout--set-state "exwm-layout.el" (id state)) (declare-function exwm-layout--set-state "exwm-layout.el" (id state))
(declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el") (declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace-switch "exwm-workspace.el" (declare-function exwm-workspace-switch "exwm-workspace.el"
(index &optional force)) (frame-or-index &optional force))
(defun exwm-input--update-focus () (defun exwm-input--update-focus ()
"Update input focus." "Update input focus."
@ -120,7 +120,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(setq exwm-workspace--switch-history-outdated t) (setq exwm-workspace--switch-history-outdated t)
(force-mode-line-update) (force-mode-line-update)
;; The application may have changed its input focus ;; The application may have changed its input focus
(exwm-workspace-switch exwm-workspace-current-index t)) (exwm-workspace-switch exwm-workspace--current t))
(exwm--log "Set focus on #x%x" exwm--id) (exwm--log "Set focus on #x%x" exwm--id)
(exwm-input--set-focus exwm--id) (exwm-input--set-focus exwm--id)
(when exwm--floating-frame (when exwm--floating-frame
@ -209,15 +209,13 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(unless (eq frame exwm-workspace--current) (unless (eq frame exwm-workspace--current)
(if (exwm-workspace--workspace-p frame) (if (exwm-workspace--workspace-p frame)
;; The X window is on another workspace ;; The X window is on another workspace
(exwm-workspace-switch (exwm-workspace-switch frame)
(exwm-workspace--position frame))
(with-current-buffer (window-buffer window) (with-current-buffer (window-buffer window)
(when (and (eq major-mode 'exwm-mode) (when (and (eq major-mode 'exwm-mode)
(not (eq exwm--frame (not (eq exwm--frame
exwm-workspace--current))) exwm-workspace--current)))
;; The floating X window is on another workspace ;; The floating X window is on another workspace
(exwm-workspace-switch (exwm-workspace-switch exwm--frame)))))
(exwm-workspace--position exwm--frame))))))
;; It has been reported that the `window' may have be deleted ;; It has been reported that the `window' may have be deleted
(if (window-live-p window) (if (window-live-p window)
(select-window window) (select-window window)

View file

@ -160,10 +160,9 @@
(declare-function exwm-workspace--current-width "exwm-workspace.el") (declare-function exwm-workspace--current-width "exwm-workspace.el")
(declare-function exwm-workspace--get-geometry "exwm-workspace.el" (frame)) (declare-function exwm-workspace--get-geometry "exwm-workspace.el" (frame))
(declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el") (declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace--position "exwm-workspace.el" (frame))
(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame)) (declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame))
(declare-function exwm-workspace-move-window "exwm-workspace.el" (declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id)) (frame-or-index &optional id))
;;;###autoload ;;;###autoload
(defun exwm-layout-set-fullscreen (&optional id) (defun exwm-layout-set-fullscreen (&optional id)
@ -347,8 +346,7 @@ selected by `other-buffer'."
(let ((window (car windows))) (let ((window (car windows)))
(if (eq frame exwm--frame) (if (eq frame exwm--frame)
(exwm-layout--show exwm--id window) (exwm-layout--show exwm--id window)
(exwm-workspace-move-window (exwm-workspace-move-window frame exwm--id))
(exwm-workspace--position frame) exwm--id))
;; Make sure this buffer is not displayed elsewhere. Note down ;; Make sure this buffer is not displayed elsewhere. Note down
;; windows displaying an EXWM-buffer now displayed elsewhere; we ;; windows displaying an EXWM-buffer now displayed elsewhere; we
;; need to display with some other buffer there. ;; need to display with some other buffer there.

View file

@ -94,7 +94,7 @@ corresponding buffer.")
(declare-function exwm-workspace--current-width "exwm-workspace.el") (declare-function exwm-workspace--current-width "exwm-workspace.el")
(declare-function exwm-workspace--set-desktop "exwm-workspace.el" (id)) (declare-function exwm-workspace--set-desktop "exwm-workspace.el" (id))
(declare-function exwm-workspace-move-window "exwm-workspace.el" (declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id)) (frame-or-index &optional id))
(defun exwm-manage--manage-window (id) (defun exwm-manage--manage-window (id)
"Manage window ID." "Manage window ID."

View file

@ -46,6 +46,19 @@ NIL if FRAME is not a workspace"
"Return t if FRAME is a workspace." "Return t if FRAME is a workspace."
(memq frame exwm-workspace--list)) (memq frame exwm-workspace--list))
(defun exwm-workspace--workspace-from-frame-or-index (frame-or-index)
"Retrieve the workspace frame from FRAME-OR-INDEX."
(cond
((framep frame-or-index)
(unless (exwm-workspace--position frame-or-index)
(user-error "[EXWM] Frame is not a workspace %S" frame-or-index))
frame-or-index)
((integerp frame-or-index)
(unless (and (<= 0 frame-or-index) (< frame-or-index (exwm-workspace--count)))
(user-error "[EXWM] Workspace index out of range: %d" frame-or-index))
(elt exwm-workspace--list frame-or-index))
(t (user-error "[EXWM] Invalid workspace: %s" frame-or-index))))
(defvar exwm-workspace--switch-map (defvar exwm-workspace--switch-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [t] (lambda () (interactive))) (define-key map [t] (lambda () (interactive)))
@ -297,29 +310,27 @@ Value nil means to use the default position which is fixed at bottom, while
"Normal hook run after switching workspace.") "Normal hook run after switching workspace.")
;;;###autoload ;;;###autoload
(defun exwm-workspace-switch (index &optional force) (defun exwm-workspace-switch (frame-or-index &optional force)
"Switch to workspace INDEX. Query for INDEX if it's not specified. "Switch to workspace INDEX. Query for FRAME-OR-INDEX if it's not specified.
The optional FORCE option is for internal use only." The optional FORCE option is for internal use only."
(interactive (interactive
(list (list
(unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible
(exwm-workspace--update-switch-history) (exwm-workspace--update-switch-history)
(let* ((history-add-new-input nil) ;prevent modifying history (let* ((current-idx (exwm-workspace--position exwm-workspace--current))
(idx (read-from-minibuffer (history-add-new-input nil) ;prevent modifying history
"Workspace: " (elt exwm-workspace--switch-history (history-idx (read-from-minibuffer
exwm-workspace-current-index) "Workspace: " (elt exwm-workspace--switch-history current-idx)
exwm-workspace--switch-map nil exwm-workspace--switch-map nil
`(exwm-workspace--switch-history `(exwm-workspace--switch-history . ,(1+ current-idx))))
. ,(1+ exwm-workspace-current-index))))) (workspace-idx (cl-position history-idx exwm-workspace--switch-history :test #'equal)))
(cl-position idx exwm-workspace--switch-history :test #'equal))))) (elt exwm-workspace--list workspace-idx)))))
(when index (let* ((frame (exwm-workspace--workspace-from-frame-or-index frame-or-index))
(unless (and (<= 0 index) (< index (exwm-workspace--count))) (index (exwm-workspace--position frame))
(user-error "[EXWM] Workspace index out of range: %d" index))
(when (or force (/= exwm-workspace-current-index 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))) (window (frame-parameter frame 'exwm-selected-window)))
(when (or force (not (eq frame exwm-workspace--current)))
(unless (window-live-p window) (unless (window-live-p window)
(setq window (frame-selected-window frame))) (setq window (frame-selected-window frame)))
;; Raise the workspace container. ;; Raise the workspace container.
@ -372,12 +383,12 @@ The optional FORCE option is for internal use only."
(set-frame-parameter frame 'exwm--urgency nil) (set-frame-parameter frame 'exwm--urgency nil)
;; Update switch workspace history ;; Update switch workspace history
(setq exwm-workspace--switch-history-outdated t) (setq exwm-workspace--switch-history-outdated t)
;; Set _NET_CURRENT_DESKTOP. ;; Set _NET_CURRENT_DESKTOP
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ewmh:set-_NET_CURRENT_DESKTOP (make-instance 'xcb:ewmh:set-_NET_CURRENT_DESKTOP
:window exwm--root :data index)) :window exwm--root :data index))
(xcb:flush exwm--connection)) (xcb:flush exwm--connection))
(run-hooks 'exwm-workspace-switch-hook)))) (run-hooks 'exwm-workspace-switch-hook)))
(defun exwm-workspace--on-focus-in () (defun exwm-workspace--on-focus-in ()
"Handle unexpected frame switch." "Handle unexpected frame switch."
@ -406,30 +417,28 @@ The optional FORCE option is for internal use only."
(declare-function exwm-layout--other-buffer-predicate "exwm-layout.el" (buffer)) (declare-function exwm-layout--other-buffer-predicate "exwm-layout.el" (buffer))
;;;###autoload ;;;###autoload
(defun exwm-workspace-move-window (index &optional id) (defun exwm-workspace-move-window (frame-or-index &optional id)
"Move window ID to workspace INDEX." "Move window ID to workspace FRAME-OR-INDEX."
(interactive (interactive
(list (list
(progn (progn
(exwm-workspace--update-switch-history) (exwm-workspace--update-switch-history)
(let* ((history-add-new-input nil) ;prevent modifying history (let* ((current-idx (exwm-workspace--position exwm-workspace--current))
(idx (read-from-minibuffer (history-add-new-input nil) ;prevent modifying history
"Workspace: " (elt exwm-workspace--switch-history (history-idx (read-from-minibuffer
exwm-workspace-current-index) "Workspace: " (elt exwm-workspace--switch-history current-idx)
exwm-workspace--switch-map nil exwm-workspace--switch-map nil
`(exwm-workspace--switch-history `(exwm-workspace--switch-history . ,(1+ current-idx))))
. ,(1+ exwm-workspace-current-index))))) (workspace-idx (cl-position history-idx exwm-workspace--switch-history :test #'equal)))
(cl-position idx exwm-workspace--switch-history :test #'equal))))) (elt exwm-workspace--list workspace-idx)))))
(let ((frame (exwm-workspace--workspace-from-frame-or-index frame-or-index)))
(unless id (setq id (exwm--buffer->id (window-buffer)))) (unless id (setq id (exwm--buffer->id (window-buffer))))
(unless (and (<= 0 index) (< index (exwm-workspace--count)))
(user-error "[EXWM] Workspace index out of range: %d" index))
(with-current-buffer (exwm--id->buffer id) (with-current-buffer (exwm--id->buffer id)
(let ((frame (elt exwm-workspace--list index)))
(unless (eq exwm--frame frame) (unless (eq exwm--frame frame)
(unless exwm-workspace-show-all-buffers (unless exwm-workspace-show-all-buffers
(let ((name (replace-regexp-in-string "^\\s-*" "" (buffer-name)))) (let ((name (replace-regexp-in-string "^\\s-*" "" (buffer-name))))
(exwm-workspace-rename-buffer (exwm-workspace-rename-buffer
(if (= index exwm-workspace-current-index) (if (eq frame exwm-workspace--current)
name name
(concat " " name))))) (concat " " name)))))
(setq exwm--frame frame) (setq exwm--frame frame)
@ -446,7 +455,7 @@ The optional FORCE option is for internal use only."
:x x :y y)) :x x :y y))
(xcb:flush exwm--connection) (xcb:flush exwm--connection)
(if (exwm-workspace--minibuffer-own-frame-p) (if (exwm-workspace--minibuffer-own-frame-p)
(when (= index exwm-workspace-current-index) (when (eq frame exwm-workspace--current)
(select-frame-set-input-focus exwm--floating-frame) (select-frame-set-input-focus exwm--floating-frame)
(exwm-layout--refresh)) (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
@ -502,18 +511,18 @@ The optional FORCE option is for internal use only."
(delete-frame old-frame) (delete-frame old-frame)
(set-window-dedicated-p window t) (set-window-dedicated-p window t)
(exwm-layout--show id window)) (exwm-layout--show id window))
(if (/= index exwm-workspace-current-index) (if (not (eq frame exwm-workspace--current))
(make-frame-visible new-frame) (make-frame-visible new-frame)
(select-frame-set-input-focus new-frame) (select-frame-set-input-focus new-frame)
(redisplay)))) (redisplay))))
;; Update the 'exwm-selected-window' frame parameter. ;; Update the 'exwm-selected-window' frame parameter.
(when (/= index exwm-workspace-current-index) (when (not (eq frame exwm-workspace--current))
(with-current-buffer (exwm--id->buffer id) (with-current-buffer (exwm--id->buffer id)
(set-frame-parameter frame 'exwm-selected-window (set-frame-parameter frame 'exwm-selected-window
(frame-root-window (frame-root-window
exwm--floating-frame))))) exwm--floating-frame)))))
;; Move the X window container. ;; Move the X window container.
(if (= index exwm-workspace-current-index) (if (eq frame exwm-workspace--current)
(set-window-buffer (get-buffer-window (current-buffer) t) (set-window-buffer (get-buffer-window (current-buffer) t)
(other-buffer)) (other-buffer))
(bury-buffer) (bury-buffer)
@ -577,7 +586,7 @@ The optional FORCE option is for internal use only."
(select-frame-set-input-focus exwm--floating-frame) (select-frame-set-input-focus exwm--floating-frame)
(select-window (frame-root-window exwm--floating-frame))) (select-window (frame-root-window exwm--floating-frame)))
;; On another workspace. ;; On another workspace.
(exwm-workspace-move-window exwm-workspace-current-index (exwm-workspace-move-window exwm-workspace--current
exwm--id)) exwm--id))
;; Ordinary buffer. ;; Ordinary buffer.
(switch-to-buffer buffer-or-name))))) (switch-to-buffer buffer-or-name)))))

View file

@ -438,10 +438,9 @@
;; FIXME: check (may require other properties set) ;; FIXME: check (may require other properties set)
(when (memq xcb:Atom:_NET_WM_STATE_DEMANDS_ATTENTION props) (when (memq xcb:Atom:_NET_WM_STATE_DEMANDS_ATTENTION props)
(when (= action xcb:ewmh:_NET_WM_STATE_ADD) (when (= action xcb:ewmh:_NET_WM_STATE_ADD)
(let ((idx (exwm-workspace--position exwm--frame))) (unless (eq exwm--frame exwm-workspace--current)
(unless (= idx exwm-workspace-current-index)
(set-frame-parameter exwm--frame 'exwm--urgency t) (set-frame-parameter exwm--frame 'exwm--urgency t)
(setq exwm-workspace--switch-history-outdated t)))) (setq exwm-workspace--switch-history-outdated t)))
;; xcb:ewmh:_NET_WM_STATE_REMOVE? ;; xcb:ewmh:_NET_WM_STATE_REMOVE?
;; xcb:ewmh:_NET_WM_STATE_TOGGLE? ;; xcb:ewmh:_NET_WM_STATE_TOGGLE?
) )