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-toggle-mode-line "exwm-layout.el")
(declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id))
(frame-or-index &optional id))
(defvar exwm-mode-map
(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-workspace--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace-switch "exwm-workspace.el"
(index &optional force))
(frame-or-index &optional force))
(defun exwm-input--update-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)
(force-mode-line-update)
;; 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-input--set-focus exwm--id)
(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)
(if (exwm-workspace--workspace-p frame)
;; The X window is on another workspace
(exwm-workspace-switch
(exwm-workspace--position frame))
(exwm-workspace-switch frame)
(with-current-buffer (window-buffer window)
(when (and (eq major-mode 'exwm-mode)
(not (eq exwm--frame
exwm-workspace--current)))
;; The floating X window is on another workspace
(exwm-workspace-switch
(exwm-workspace--position exwm--frame))))))
(exwm-workspace-switch exwm--frame)))))
;; It has been reported that the `window' may have be deleted
(if (window-live-p window)
(select-window window)

View file

@ -160,10 +160,9 @@
(declare-function exwm-workspace--current-width "exwm-workspace.el")
(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--position "exwm-workspace.el" (frame))
(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame))
(declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id))
(frame-or-index &optional id))
;;;###autoload
(defun exwm-layout-set-fullscreen (&optional id)
@ -347,8 +346,7 @@ selected by `other-buffer'."
(let ((window (car windows)))
(if (eq frame exwm--frame)
(exwm-layout--show exwm--id window)
(exwm-workspace-move-window
(exwm-workspace--position frame) exwm--id))
(exwm-workspace-move-window frame exwm--id))
;; Make sure this buffer is not displayed elsewhere. Note down
;; windows displaying an EXWM-buffer now displayed elsewhere; we
;; 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--set-desktop "exwm-workspace.el" (id))
(declare-function exwm-workspace-move-window "exwm-workspace.el"
(index &optional id))
(frame-or-index &optional id))
(defun exwm-manage--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."
(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
(let ((map (make-sparse-keymap)))
(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.")
;;;###autoload
(defun exwm-workspace-switch (index &optional force)
"Switch to workspace INDEX. Query for INDEX if it's not specified.
(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--update-switch-history)
(let* ((history-add-new-input nil) ;prevent modifying history
(idx (read-from-minibuffer
"Workspace: " (elt exwm-workspace--switch-history
exwm-workspace-current-index)
(let* ((current-idx (exwm-workspace--position exwm-workspace--current))
(history-add-new-input nil) ;prevent modifying history
(history-idx (read-from-minibuffer
"Workspace: " (elt exwm-workspace--switch-history current-idx)
exwm-workspace--switch-map nil
`(exwm-workspace--switch-history
. ,(1+ exwm-workspace-current-index)))))
(cl-position idx exwm-workspace--switch-history :test #'equal)))))
(when index
(unless (and (<= 0 index) (< index (exwm-workspace--count)))
(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))
`(exwm-workspace--switch-history . ,(1+ current-idx))))
(workspace-idx (cl-position history-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))
(index (exwm-workspace--position frame))
(workspace (frame-parameter frame 'exwm-workspace))
(window (frame-parameter frame 'exwm-selected-window)))
(when (or force (not (eq frame exwm-workspace--current)))
(unless (window-live-p window)
(setq window (frame-selected-window frame)))
;; Raise the workspace container.
@ -372,12 +383,12 @@ The optional FORCE option is for internal use only."
(set-frame-parameter frame 'exwm--urgency nil)
;; Update switch workspace history
(setq exwm-workspace--switch-history-outdated t)
;; Set _NET_CURRENT_DESKTOP.
;; Set _NET_CURRENT_DESKTOP
(xcb:+request exwm--connection
(make-instance 'xcb:ewmh:set-_NET_CURRENT_DESKTOP
:window exwm--root :data index))
(xcb:flush exwm--connection))
(run-hooks 'exwm-workspace-switch-hook))))
(run-hooks 'exwm-workspace-switch-hook)))
(defun exwm-workspace--on-focus-in ()
"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))
;;;###autoload
(defun exwm-workspace-move-window (index &optional id)
"Move window ID to workspace INDEX."
(defun exwm-workspace-move-window (frame-or-index &optional id)
"Move window ID to workspace FRAME-OR-INDEX."
(interactive
(list
(progn
(exwm-workspace--update-switch-history)
(let* ((history-add-new-input nil) ;prevent modifying history
(idx (read-from-minibuffer
"Workspace: " (elt exwm-workspace--switch-history
exwm-workspace-current-index)
(let* ((current-idx (exwm-workspace--position exwm-workspace--current))
(history-add-new-input nil) ;prevent modifying history
(history-idx (read-from-minibuffer
"Workspace: " (elt exwm-workspace--switch-history current-idx)
exwm-workspace--switch-map nil
`(exwm-workspace--switch-history
. ,(1+ exwm-workspace-current-index)))))
(cl-position idx exwm-workspace--switch-history :test #'equal)))))
`(exwm-workspace--switch-history . ,(1+ current-idx))))
(workspace-idx (cl-position history-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 (and (<= 0 index) (< index (exwm-workspace--count)))
(user-error "[EXWM] Workspace index out of range: %d" index))
(with-current-buffer (exwm--id->buffer id)
(let ((frame (elt exwm-workspace--list index)))
(unless (eq exwm--frame frame)
(unless exwm-workspace-show-all-buffers
(let ((name (replace-regexp-in-string "^\\s-*" "" (buffer-name))))
(exwm-workspace-rename-buffer
(if (= index exwm-workspace-current-index)
(if (eq frame exwm-workspace--current)
name
(concat " " name)))))
(setq exwm--frame frame)
@ -446,7 +455,7 @@ The optional FORCE option is for internal use only."
:x x :y y))
(xcb:flush exwm--connection)
(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)
(exwm-layout--refresh))
;; 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)
(set-window-dedicated-p window t)
(exwm-layout--show id window))
(if (/= index exwm-workspace-current-index)
(if (not (eq frame exwm-workspace--current))
(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)
(when (not (eq frame exwm-workspace--current))
(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)
(if (eq frame exwm-workspace--current)
(set-window-buffer (get-buffer-window (current-buffer) t)
(other-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-window (frame-root-window exwm--floating-frame)))
;; On another workspace.
(exwm-workspace-move-window exwm-workspace-current-index
(exwm-workspace-move-window exwm-workspace--current
exwm--id))
;; Ordinary buffer.
(switch-to-buffer buffer-or-name)))))

View file

@ -438,10 +438,9 @@
;; FIXME: check (may require other properties set)
(when (memq xcb:Atom:_NET_WM_STATE_DEMANDS_ATTENTION props)
(when (= action xcb:ewmh:_NET_WM_STATE_ADD)
(let ((idx (exwm-workspace--position exwm--frame)))
(unless (= idx exwm-workspace-current-index)
(unless (eq exwm--frame exwm-workspace--current)
(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_TOGGLE?
)