mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-30 16:07:59 +01:00
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:
parent
35e1655dc5
commit
07120a0562
6 changed files with 114 additions and 110 deletions
|
@ -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)))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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."
|
||||||
|
|
|
@ -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)))))
|
||||||
|
|
5
exwm.el
5
exwm.el
|
@ -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?
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue