about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2015-09-16T13·32+0800
committerChris Feng <chris.w.feng@gmail.com>2015-09-16T13·36+0800
commitb458d5ac30afed348df4788721bb48be94e97c60 (patch)
tree47a95d918c88d328fef4b67224abeb9b727d69ed
parent576a676f1f0895bd473d54c2713ee9e2423023e6 (diff)
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.
-rw-r--r--exwm-floating.el5
-rw-r--r--exwm-layout.el31
-rw-r--r--exwm-workspace.el51
-rw-r--r--exwm.el4
4 files changed, 58 insertions, 33 deletions
diff --git a/exwm-floating.el b/exwm-floating.el
index 04493764bd0f..12390b0ea2e1 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 27533a5ebd8a..2c9ab750b434 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 40dd57ca69ee..fcc42e273396 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 bf45e40c8b5d..9311af1c8d13 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