From b458d5ac30afed348df4788721bb48be94e97c60 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Wed, 16 Sep 2015 21:32:38 +0800 Subject: [PATCH] Allow showing buffers on other workspaces and moving an X window by switching to its buffer * exwm-workspace.el (exwm-workspace-show-all-buffers, exwm-workspace-switch) (exwm-workspace-move-window, exwm-workspace-switch-to-buffer): Show buffers on other workspaces if `exwm-workspace-show-all-buffers' is non-nil. * exwm-layout.el (exwm-layout-show-all-buffers, exwm-layout--refresh): Allow moving an X window by switch to its corresponding buffer from another workspace when `exwm-layout-show-all-buffers' is non-nil. * exwm.el (exwm--ido-buffer-window-other-frame): Handle the case when `exwm-layout-show-all-buffers' is non-nil. * exwm-floating.el (exwm-floating--set-floating): Handle the case when *scratch* buffer is killed. * exwm-workspace.el (exwm-workspace-switch-to-buffer): Renamed from `exwm-workspace-switch-to-window' to better reflect its role. --- exwm-floating.el | 5 ++++- exwm-layout.el | 31 ++++++++++++++++++---------- exwm-workspace.el | 51 ++++++++++++++++++++++++++++------------------- exwm.el | 4 +++- 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/exwm-floating.el b/exwm-floating.el index 0449376..12390b0 100644 --- a/exwm-floating.el +++ b/exwm-floating.el @@ -67,7 +67,10 @@ exwm-workspace--current))) (original-id (frame-parameter original-frame 'exwm-window-id)) ;; Create new frame - (frame (with-current-buffer "*scratch*" + (frame (with-current-buffer + (or (get-buffer "*scratch*") + (prog1 (get-buffer-create "*scratch*") + (set-buffer-major-mode "*scratch*"))) (prog2 (exwm--lock) (make-frame diff --git a/exwm-layout.el b/exwm-layout.el index 27533a5..2c9ab75 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -194,10 +194,15 @@ :height height)) (xcb:flush exwm--connection)))) +(defvar exwm-layout-show-all-buffers nil + "Non-nil to allow switching to buffers on other workspaces.") + (defun exwm-layout--refresh () "Refresh layout." (let ((frame (selected-frame)) - (placeholder (get-buffer "*scratch*")) + (placeholder (or (get-buffer "*scratch*") + (prog1 (get-buffer-create "*scratch*") + (set-buffer-major-mode "*scratch*")))) windows) (if (not (memq frame exwm-workspace--list)) (if (frame-parameter frame 'exwm-window-id) @@ -221,19 +226,25 @@ ;; Refresh the whole workspace ;; Workspaces other than the active one can also be refreshed (RandR) (exwm--log "Refresh workspace %s" frame) - (unless placeholder ;create the *scratch* buffer if it's killed - (setq placeholder (get-buffer-create "*scratch*")) - (set-buffer-major-mode placeholder)) (dolist (pair exwm--id-buffer-alist) (with-current-buffer (cdr pair) - ;; Exclude windows on other workspaces and floating frames - (when (and (eq frame exwm--frame) (not exwm--floating-frame)) + (when (and (not exwm--floating-frame) ;exclude floating X windows + (or exwm-layout-show-all-buffers + ;; Exclude X windows on other workspaces + (eq frame exwm--frame))) (setq windows (get-buffer-window-list (current-buffer) 0)) (if (not windows) - (exwm-layout--hide exwm--id) - (exwm-layout--show exwm--id (car windows)) - (dolist (i (cdr windows)) - (set-window-buffer i placeholder)))))) + (when (eq frame exwm--frame) ;for exwm-layout-show-all-buffers + (exwm-layout--hide exwm--id)) + (if (eq frame exwm--frame) + (exwm-layout--show exwm--id (car windows)) + (exwm-workspace-move-window + (cl-position frame exwm-workspace--list) exwm--id)) + (let ((window (car windows))) + ;; Make sure this buffer is not displayed elsewhere + (dolist (i (get-buffer-window-list (current-buffer) 0 t)) + (unless (eq i window) + (set-window-buffer i placeholder)))))))) ;; Make sure windows floating / on other workspaces are excluded (dolist (window (window-list frame 0)) (with-current-buffer (window-buffer window) diff --git a/exwm-workspace.el b/exwm-workspace.el index 40dd57c..fcc42e2 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -93,6 +93,8 @@ (defvar exwm-workspace--current nil "Current active workspace.") (defvar exwm-workspace-current-index 0 "Index of current active workspace.") +(defvar exwm-workspace-show-all-buffers nil + "Non-nil to show buffers on other workspaces.") (defun exwm-workspace-switch (index &optional force) "Switch to workspace INDEX. Query for INDEX if it's not specified. @@ -131,12 +133,14 @@ The optional FORCE option is for internal use only." (set-mouse-pixel-position frame x y))) (setq default-minibuffer-frame frame) ;; Hide windows in other workspaces by preprending a space - (dolist (i exwm--id-buffer-alist) - (with-current-buffer (cdr i) - (let ((name (replace-regexp-in-string "^\\s-*" "" (buffer-name)))) - (exwm-workspace-rename-buffer (if (eq frame exwm--frame) - name - (concat " " name)))))) + (unless exwm-workspace-show-all-buffers + (dolist (i exwm--id-buffer-alist) + (with-current-buffer (cdr i) + (let ((name (replace-regexp-in-string "^\\s-*" "" + (buffer-name)))) + (exwm-workspace-rename-buffer (if (eq frame exwm--frame) + name + (concat " " name))))))) ;; Update demands attention flag (set-frame-parameter frame 'exwm--urgency nil) ;; Update switch workspace history @@ -175,9 +179,12 @@ The optional FORCE option is for internal use only." (with-current-buffer (exwm--id->buffer id) (let ((frame (elt exwm-workspace--list index))) (unless (eq exwm--frame frame) - (let ((name (replace-regexp-in-string "^\\s-*" "" (buffer-name)))) - (exwm-workspace-rename-buffer - (if (= index exwm-workspace-current-index) name (concat " " name)))) + (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) + name + (concat " " name))))) (setq exwm--frame frame) (if exwm--floating-frame ;; Move the floating frame is enough @@ -208,15 +215,16 @@ The optional FORCE option is for internal use only." (exwm--id->buffer id))))) (exwm-workspace--update-switch-history))) -(defun exwm-workspace-switch-to-window () - "Make the current Emacs window display another X window." +(defun exwm-workspace-switch-to-buffer () + "Make the current Emacs window display another buffer." (interactive) ;; Show all buffers - (dolist (pair exwm--id-buffer-alist) - (with-current-buffer (cdr pair) - (when (= ?\s (aref (buffer-name) 0)) - (rename-buffer (substring (buffer-name) 1))))) - (let ((buffer (read-buffer "Switch to window: " nil t))) + (unless exwm-workspace-show-all-buffers + (dolist (pair exwm--id-buffer-alist) + (with-current-buffer (cdr pair) + (when (= ?\s (aref (buffer-name) 0)) + (rename-buffer (substring (buffer-name) 1)))))) + (let ((buffer (read-buffer "Switch to buffer: " nil t))) (when buffer (with-current-buffer buffer (if (and (eq major-mode 'exwm-mode) @@ -225,11 +233,12 @@ The optional FORCE option is for internal use only." exwm--id) (switch-to-buffer buffer))))) ;; Hide buffers on other workspaces - (dolist (pair exwm--id-buffer-alist) - (with-current-buffer (cdr pair) - (unless (or (eq exwm--frame exwm-workspace--current) - (= ?\s (aref (buffer-name) 0))) - (rename-buffer (concat " " (buffer-name))))))) + (unless exwm-workspace-show-all-buffers + (dolist (pair exwm--id-buffer-alist) + (with-current-buffer (cdr pair) + (unless (or (eq exwm--frame exwm-workspace--current) + (= ?\s (aref (buffer-name) 0))) + (rename-buffer (concat " " (buffer-name)))))))) (defun exwm-workspace-rename-buffer (newname) "Rename a buffer." diff --git a/exwm.el b/exwm.el index bf45e40..9311af1 100644 --- a/exwm.el +++ b/exwm.el @@ -538,7 +538,9 @@ (defun exwm--ido-buffer-window-other-frame (orig-fun buffer) "Wrapper for `ido-buffer-window-other-frame' to exclude invisible windows." (with-current-buffer buffer - (if (eq major-mode 'exwm-mode) + (if (and (eq major-mode 'exwm-mode) + (or exwm--floating-frame + (not exwm-layout-show-all-buffers))) ;; `ido-mode' works well with `exwm-mode' buffers (funcall orig-fun buffer) ;; Other buffers should be selected within the same workspace