Merge branch 'drop-client-p' into externals/exwm
This commit is contained in:
		
						commit
						1c706daeb0
					
				
					 5 changed files with 143 additions and 150 deletions
				
			
		|  | @ -85,9 +85,6 @@ each time." | |||
| 
 | ||||
| If the minibuffer is detached, this value is 0.") | ||||
| 
 | ||||
| (defvar exwm-workspace--client nil | ||||
|   "The 'client' frame parameter of emacsclient frames.") | ||||
| 
 | ||||
| (defvar exwm-workspace--create-silently nil | ||||
|   "When non-nil workspaces are created in the background (not switched to). | ||||
| 
 | ||||
|  | @ -165,22 +162,6 @@ NIL if FRAME is not a workspace" | |||
|   "Return t if FRAME is a workspace." | ||||
|   (memq frame exwm-workspace--list)) | ||||
| 
 | ||||
| (defvar exwm-workspace--client-p-hash-table | ||||
|   (make-hash-table :test 'eq :weakness 'key) | ||||
|   "Used to cache the results of calling ‘exwm-workspace--client-p’.") | ||||
| 
 | ||||
| (defsubst exwm-workspace--client-p (&optional frame) | ||||
|   "Return non-nil if FRAME is an emacsclient frame." | ||||
|   (let* ((frame (or frame (selected-frame))) | ||||
|          (cached-value | ||||
|           (gethash frame exwm-workspace--client-p-hash-table 'absent))) | ||||
|     (if (eq cached-value 'absent) | ||||
|         (puthash frame | ||||
|                  (or (frame-parameter frame 'client) | ||||
|                      (not (display-graphic-p frame))) | ||||
|                  exwm-workspace--client-p-hash-table) | ||||
|         cached-value))) | ||||
| 
 | ||||
| (defvar exwm-workspace--switch-map nil | ||||
|   "Keymap used for interactively selecting workspace.") | ||||
| 
 | ||||
|  | @ -264,7 +245,6 @@ NIL if FRAME is not a workspace" | |||
|   (when (and exwm-workspace--prompt-delete-allowed | ||||
|              (< 1 (exwm-workspace--count))) | ||||
|     (let ((frame (elt exwm-workspace--list (1- minibuffer-history-position)))) | ||||
|       (exwm-workspace--get-remove-frame-next-workspace frame) | ||||
|       (if (eq frame exwm-workspace--current) | ||||
|           ;; Abort the recursive minibuffer if deleting the current workspace. | ||||
|           (progn | ||||
|  | @ -830,7 +810,6 @@ INDEX must not exceed the current number of workspaces." | |||
|                      (exwm-workspace--workspace-from-frame-or-index | ||||
|                       frame-or-index) | ||||
|                    exwm-workspace--current))) | ||||
|       (exwm-workspace--get-remove-frame-next-workspace frame) | ||||
|       (delete-frame frame)))) | ||||
| 
 | ||||
| (defun exwm-workspace--set-desktop (id) | ||||
|  | @ -1131,7 +1110,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
| 
 | ||||
| (defun exwm-workspace--update-minibuffer-height (&optional echo-area) | ||||
|   "Update the minibuffer frame height." | ||||
|   (unless (exwm-workspace--client-p) | ||||
|   (when (exwm--terminal-p) | ||||
|     (let ((height | ||||
|            (with-current-buffer | ||||
|                (window-buffer (minibuffer-window exwm-workspace--minibuffer)) | ||||
|  | @ -1248,7 +1227,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
|   "Run in minibuffer-setup-hook to show the minibuffer and its container." | ||||
|   (exwm--log) | ||||
|   (when (and (= 1 (minibuffer-depth)) | ||||
|              (not (exwm-workspace--client-p))) | ||||
|              (exwm--terminal-p)) | ||||
|     (add-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height) | ||||
|     (exwm-workspace--show-minibuffer)) | ||||
|   ;; FIXME: This is a temporary fix for the *Completions* buffer not | ||||
|  | @ -1270,16 +1249,16 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
|   "Run in minibuffer-exit-hook to hide the minibuffer container." | ||||
|   (exwm--log) | ||||
|   (when (and (= 1 (minibuffer-depth)) | ||||
|              (not (exwm-workspace--client-p))) | ||||
|              (exwm--terminal-p)) | ||||
|     (remove-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height) | ||||
|     (exwm-workspace--hide-minibuffer))) | ||||
| 
 | ||||
| (defun exwm-workspace--on-echo-area-dirty () | ||||
|   "Run when new message arrives to show the echo area and its container." | ||||
|   (when (and (not (active-minibuffer-window)) | ||||
|              (not (exwm-workspace--client-p)) | ||||
|              (or (current-message) | ||||
|                  cursor-in-echo-area)) | ||||
|                  cursor-in-echo-area) | ||||
|              (exwm--terminal-p)) | ||||
|     (exwm-workspace--update-minibuffer-height t) | ||||
|     (exwm-workspace--show-minibuffer) | ||||
|     (unless (or (not exwm-workspace-display-echo-area-timeout) | ||||
|  | @ -1302,7 +1281,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
| 
 | ||||
| (defun exwm-workspace--on-echo-area-clear () | ||||
|   "Run in echo-area-clear-hook to hide echo area container." | ||||
|   (unless (exwm-workspace--client-p) | ||||
|   (when (exwm--terminal-p) | ||||
|     (unless (active-minibuffer-window) | ||||
|       (exwm-workspace--hide-minibuffer)) | ||||
|     (when exwm-workspace--display-echo-area-timer | ||||
|  | @ -1332,8 +1311,6 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
|     (set-frame-parameter frame 'exwm-outer-id outer-id) | ||||
|     (set-frame-parameter frame 'exwm-id window-id) | ||||
|     (set-frame-parameter frame 'exwm-container container) | ||||
|     ;; In case it's created by emacsclient. | ||||
|     (set-frame-parameter frame 'client nil) | ||||
|     ;; Copy RandR frame parameters from the first workspace to | ||||
|     ;; prevent potential problems.  The values do not matter here as | ||||
|     ;; they'll be updated by the RandR module later. | ||||
|  | @ -1392,7 +1369,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
|         (make-instance 'xcb:MapWindow :window container))) | ||||
|   (xcb:flush exwm--connection) | ||||
|   ;; Delay making the workspace fullscreen until Emacs becomes idle | ||||
|   (exwm--defer 0 #'set-frame-parameter frame 'fullscreen 'fullboth) | ||||
|   (exwm--defer 0 #'exwm-workspace--fullscreen-workspace frame) | ||||
|   ;; Update EWMH properties. | ||||
|   (exwm-workspace--update-ewmh-props) | ||||
|   (if exwm-workspace--create-silently | ||||
|  | @ -1403,41 +1380,41 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." | |||
|                frame exwm-workspace-current-index original-index)) | ||||
|     (run-hooks 'exwm-workspace-list-change-hook))) | ||||
| 
 | ||||
| (defun exwm-workspace--get-remove-frame-next-workspace (frame) | ||||
|   "Return the next workspace if workspace FRAME is removed. | ||||
| 
 | ||||
| All X windows currently on workspace FRAME will be automatically moved to | ||||
| the next workspace." | ||||
| (defun exwm-workspace--get-next-workspace (frame) | ||||
|   "Return the next workspace if workspace FRAME were removed. | ||||
| Return nil if FRAME is the only workspace." | ||||
|   (let* ((index (exwm-workspace--position frame)) | ||||
|          (lastp (= index (1- (exwm-workspace--count)))) | ||||
|          (nextw (elt exwm-workspace--list (+ index (if lastp -1 +1))))) | ||||
|     ;; Clients need to be moved to some other workspace before this being | ||||
|     ;; removed. | ||||
|     (dolist (pair exwm--id-buffer-alist) | ||||
|       (with-current-buffer (cdr pair) | ||||
|         (when (eq exwm--frame frame) | ||||
|           (exwm-workspace-move-window nextw exwm--id)))) | ||||
|     nextw)) | ||||
|     (unless (eq frame nextw) | ||||
|       nextw))) | ||||
| 
 | ||||
| (defun exwm-workspace--remove-frame-as-workspace (frame) | ||||
|   "Stop treating frame FRAME as a workspace." | ||||
|   ;; TODO: restore all frame parameters (e.g. exwm-workspace, buffer-predicate, | ||||
|   ;; etc) | ||||
|   (exwm--log "Removing frame `%s' as workspace" frame) | ||||
|   (let* ((index (exwm-workspace--position frame)) | ||||
|          (nextw (exwm-workspace--get-remove-frame-next-workspace frame))) | ||||
|     ;; Need to remove the workspace from the list in order for | ||||
|     ;; the correct calculation of indexes. | ||||
|   (let* ((next-frame (exwm-workspace--get-next-workspace frame)) | ||||
|          (following-frames (cdr (memq frame exwm-workspace--list)))) | ||||
|     ;; Need to remove the workspace from the list for the correct calculation of | ||||
|     ;; indexes below. | ||||
|     (setq exwm-workspace--list (delete frame exwm-workspace--list)) | ||||
|     ;; Update the _NET_WM_DESKTOP property of each X window affected. | ||||
|     (unless next-frame | ||||
|       ;; The user managed to delete the last workspace, so create a new one. | ||||
|       (exwm--log "Last workspace deleted; create a new one") | ||||
|       (let ((exwm-workspace--create-silently t)) | ||||
|         (setq next-frame (make-frame)))) | ||||
|     (dolist (pair exwm--id-buffer-alist) | ||||
|       (when (<= (1- index) | ||||
|                 (exwm-workspace--position (buffer-local-value 'exwm--frame | ||||
|                                                               (cdr pair)))) | ||||
|         (exwm-workspace--set-desktop (car pair)))) | ||||
|       (let ((other-frame (buffer-local-value 'exwm--frame (cdr pair)))) | ||||
|         ;; Move X windows to next-frame. | ||||
|         (when (eq other-frame frame) | ||||
|           (exwm-workspace-move-window next-frame (car pair))) | ||||
|         ;; Update the _NET_WM_DESKTOP property of each following X window. | ||||
|         (when (memq other-frame following-frames) | ||||
|           (exwm-workspace--set-desktop (car pair))))) | ||||
|     ;; If the current workspace is deleted, switch to next one. | ||||
|     (when (eq frame exwm-workspace--current) | ||||
|       (exwm-workspace-switch nextw))) | ||||
|       (exwm-workspace-switch next-frame))) | ||||
|   ;; Reparent out the frame. | ||||
|   (let ((outer-id (frame-parameter frame 'exwm-outer-id))) | ||||
|     (xcb:+request exwm--connection | ||||
|  | @ -1480,15 +1457,13 @@ the next workspace." | |||
|    ((not (exwm-workspace--workspace-p frame)) | ||||
|     (exwm--log "Frame `%s' is not a workspace" frame)) | ||||
|    (t | ||||
|     (when (= 1 (exwm-workspace--count)) | ||||
|       ;; The user managed to delete the last workspace, so create a new one. | ||||
|       (exwm--log "Last workspace deleted; create a new one") | ||||
|       ;; TODO: this makes sense in the hook.  But we need a function that takes | ||||
|       ;; care of converting a workspace into a regular unmanaged frame. | ||||
|       (let ((exwm-workspace--create-silently t)) | ||||
|         (make-frame))) | ||||
|     (exwm-workspace--remove-frame-as-workspace frame) | ||||
|     (remhash frame exwm-workspace--client-p-hash-table)))) | ||||
|     (exwm-workspace--remove-frame-as-workspace frame)))) | ||||
| 
 | ||||
| (defun exwm-workspace--fullscreen-workspace (frame) | ||||
|   "Make workspace FRAME fullscreen. | ||||
| Called from a timer." | ||||
|   (when (frame-live-p frame) | ||||
|     (set-frame-parameter frame 'fullscreen 'fullboth))) | ||||
| 
 | ||||
| (defun exwm-workspace--on-after-make-frame (frame) | ||||
|   "Hook run upon `make-frame' that configures FRAME as a workspace." | ||||
|  | @ -1497,6 +1472,11 @@ the next workspace." | |||
|     (exwm--log "Frame `%s' is already a workspace" frame)) | ||||
|    ((not (display-graphic-p frame)) | ||||
|     (exwm--log "Frame `%s' is not graphical" frame)) | ||||
|    ((not (eq (frame-terminal) exwm--terminal)) | ||||
|     (exwm--log "Frame `%s' is on a different terminal (%S instead of %S)" | ||||
|                frame | ||||
|                (frame-terminal frame) | ||||
|                exwm--terminal)) | ||||
|    ((not (string-equal | ||||
|           (replace-regexp-in-string "\\.0$" "" | ||||
|                                     (slot-value exwm--connection 'display)) | ||||
|  | @ -1562,8 +1542,7 @@ applied to all subsequently created X frames." | |||
|   (setq exwm-workspace--minibuffer | ||||
|         (make-frame '((window-system . x) (minibuffer . only) | ||||
|                       (left . 10000) (right . 10000) | ||||
|                       (width . 1) (height . 1) | ||||
|                       (client . nil)))) | ||||
|                       (width . 1) (height . 1)))) | ||||
|   ;; This is the only usable minibuffer frame. | ||||
|   (setq default-minibuffer-frame exwm-workspace--minibuffer) | ||||
|   (exwm-workspace--modify-all-x-frames-parameters | ||||
|  | @ -1633,6 +1612,8 @@ applied to all subsequently created X frames." | |||
|   (remove-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup) | ||||
|   (remove-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit) | ||||
|   (remove-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear) | ||||
|   (when exwm-workspace--display-echo-area-timer | ||||
|     (cancel-timer exwm-workspace--display-echo-area-timer)) | ||||
|   (when exwm-workspace--timer | ||||
|     (cancel-timer exwm-workspace--timer) | ||||
|     (setq exwm-workspace--timer nil)) | ||||
|  | @ -1640,15 +1621,16 @@ applied to all subsequently created X frames." | |||
|         (cl-delete '(exwm-workspace--display-buffer) display-buffer-alist | ||||
|                    :test #'equal)) | ||||
|   (setq default-minibuffer-frame nil) | ||||
|   (let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id))) | ||||
|     (when (and exwm-workspace--minibuffer id) | ||||
|       (xcb:+request exwm--connection | ||||
|           (make-instance 'xcb:ReparentWindow | ||||
|                          :window id | ||||
|                          :parent exwm--root | ||||
|                          :x 0 | ||||
|                          :y 0))) | ||||
|     (setq exwm-workspace--minibuffer nil))) | ||||
|   (when (frame-live-p exwm-workspace--minibuffer) ; might be already dead | ||||
|     (let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id))) | ||||
|       (when (and exwm-workspace--minibuffer id) | ||||
|         (xcb:+request exwm--connection | ||||
|             (make-instance 'xcb:ReparentWindow | ||||
|                            :window id | ||||
|                            :parent exwm--root | ||||
|                            :x 0 | ||||
|                            :y 0))) | ||||
|       (setq exwm-workspace--minibuffer nil)))) | ||||
| 
 | ||||
| (defun exwm-workspace--init () | ||||
|   "Initialize workspace module." | ||||
|  | @ -1666,33 +1648,22 @@ applied to all subsequently created X frames." | |||
|           (dolist (i initial-workspaces) | ||||
|             (unless (frame-parameter i 'window-id) | ||||
|               (setq initial-workspaces (delq i initial-workspaces)))) | ||||
|           (setq exwm-workspace--client | ||||
|                 (frame-parameter (car initial-workspaces) 'client)) | ||||
|           (let ((f (car initial-workspaces))) | ||||
|             ;; Remove the possible internal border. | ||||
|             (set-frame-parameter f 'internal-border-width 0) | ||||
|             ;; Prevent user from deleting the first frame by accident. | ||||
|             (set-frame-parameter f 'client nil))) | ||||
|             (set-frame-parameter f 'internal-border-width 0))) | ||||
|       (exwm-workspace--init-minibuffer-frame) | ||||
|       ;; Remove/hide existing frames. | ||||
|       (dolist (f initial-workspaces) | ||||
|         (if (frame-parameter f 'client) | ||||
|             (progn | ||||
|               (unless exwm-workspace--client | ||||
|                 (setq exwm-workspace--client (frame-parameter f 'client))) | ||||
|               (make-frame-invisible f)) | ||||
|           (when (eq 'x (framep f))   ;do not delete the initial frame. | ||||
|             (delete-frame f)))) | ||||
|         (when (eq 'x (framep f))        ;do not delete the initial frame. | ||||
|           (delete-frame f))) | ||||
|       ;; Recreate one frame with the external minibuffer set. | ||||
|       (setq initial-workspaces (list (make-frame '((window-system . x) | ||||
|                                                    (client . nil)))))) | ||||
|       (setq initial-workspaces (list (make-frame '((window-system . x)))))) | ||||
|     ;; Prevent `other-buffer' from selecting already displayed EXWM buffers. | ||||
|     (modify-all-frames-parameters | ||||
|      '((buffer-predicate . exwm-layout--other-buffer-predicate))) | ||||
|     ;; Create remaining workspaces. | ||||
|     (dotimes (_ (- exwm-workspace-number (length initial-workspaces))) | ||||
|       (nconc initial-workspaces (list (make-frame '((window-system . x) | ||||
|                                                     (client . nil)))))) | ||||
|       (nconc initial-workspaces (list (make-frame '((window-system . x)))))) | ||||
|     ;; Configure workspaces | ||||
|     (let ((exwm-workspace--create-silently t)) | ||||
|       (dolist (i initial-workspaces) | ||||
|  | @ -1739,34 +1710,22 @@ applied to all subsequently created X frames." | |||
|   ;; X windows will be re-mapped). | ||||
|   (setq exwm-workspace--current nil) | ||||
|   (dolist (i exwm-workspace--list) | ||||
|     (exwm-workspace--remove-frame-as-workspace i) | ||||
|     (modify-frame-parameters i '((exwm-selected-window . nil) | ||||
|                                  (exwm-urgency . nil) | ||||
|                                  (exwm-outer-id . nil) | ||||
|                                  (exwm-id . nil) | ||||
|                                  (exwm-container . nil) | ||||
|                                  ;; (internal-border-width . nil) ; integerp | ||||
|                                  ;; (client . nil) | ||||
|                                  (fullscreen . nil) | ||||
|                                  (buffer-predicate . nil)))) | ||||
|   ;; Restore the 'client' frame parameter (before `exwm-exit'). | ||||
|   (when exwm-workspace--client | ||||
|     (dolist (f exwm-workspace--list) | ||||
|       (set-frame-parameter f 'client exwm-workspace--client)) | ||||
|     (when (exwm-workspace--minibuffer-own-frame-p) | ||||
|       (set-frame-parameter exwm-workspace--minibuffer 'client | ||||
|                            exwm-workspace--client)) | ||||
|     (setq exwm-workspace--client nil))) | ||||
|     (when (frame-live-p i)                    ; might be already dead | ||||
|       (exwm-workspace--remove-frame-as-workspace i) | ||||
|       (modify-frame-parameters i '((exwm-selected-window . nil) | ||||
|                                    (exwm-urgency . nil) | ||||
|                                    (exwm-outer-id . nil) | ||||
|                                    (exwm-id . nil) | ||||
|                                    (exwm-container . nil) | ||||
|                                    ;; (internal-border-width . nil) ; integerp | ||||
|                                    (fullscreen . nil) | ||||
|                                    (buffer-predicate . nil))))) | ||||
|   ;; Don't let dead frames linger. | ||||
|   (setq exwm-workspace--list nil)) | ||||
| 
 | ||||
| (defun exwm-workspace--post-init () | ||||
|   "The second stage in the initialization of the workspace module." | ||||
|   (exwm--log) | ||||
|   (when exwm-workspace--client | ||||
|     ;; Reset the 'fullscreen' frame parameter to make emacsclinet frames | ||||
|     ;; fullscreen (even without the RandR module enabled). | ||||
|     (dolist (i exwm-workspace--list) | ||||
|       (set-frame-parameter i 'fullscreen nil) | ||||
|       (set-frame-parameter i 'fullscreen 'fullboth))) | ||||
|   ;; Wait until all workspace frames are resized. | ||||
|   (with-timeout (1) | ||||
|     (while (< exwm-workspace--fullscreen-frame-count (exwm-workspace--count)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue