[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 1c706daeb0 7/8: Merge branch 'drop-client-p' into
From: |
ELPA Syncer |
Subject: |
[elpa] externals/exwm 1c706daeb0 7/8: Merge branch 'drop-client-p' into externals/exwm |
Date: |
Tue, 22 Nov 2022 18:57:44 -0500 (EST) |
branch: externals/exwm
commit 1c706daeb089d8f9c50eeecb898cad6336f0e3e6
Merge: 6408a74312 d6f62ff55a
Author: Adrián Medraño Calvo <adrian@medranocalvo.com>
Commit: Adrián Medraño Calvo <adrian@medranocalvo.com>
Merge branch 'drop-client-p' into externals/exwm
---
exwm-core.el | 8 +++
exwm-input.el | 46 +++++++-------
exwm-layout.el | 27 ++++----
exwm-workspace.el | 183 +++++++++++++++++++++---------------------------------
exwm.el | 29 +++++++--
5 files changed, 143 insertions(+), 150 deletions(-)
diff --git a/exwm-core.el b/exwm-core.el
index 3215dcdd2c..75c7c1b17b 100644
--- a/exwm-core.el
+++ b/exwm-core.el
@@ -59,6 +59,9 @@ Here are some predefined candidates:
(defvar exwm--connection nil "X connection.")
+(defvar exwm--terminal nil
+ "Terminal corresponding to `exwm--connection'.")
+
(defvar exwm--wmsn-window nil
"An X window owning the WM_S0 selection.")
@@ -177,6 +180,11 @@ least SECS seconds later."
,function
,@args))
+(defsubst exwm--terminal-p (&optional frame)
+ "Return t when FRAME's terminal is EXWM's terminal.
+If FRAME is null, use selected frame."
+ (eq exwm--terminal (frame-terminal frame)))
+
(defun exwm--get-client-event-mask ()
"Return event mask set on all managed windows."
(logior xcb:EventMask:StructureNotify
diff --git a/exwm-input.el b/exwm-input.el
index 8fd0af50d8..79bc78ef0f 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -159,8 +159,6 @@ Current buffer will be the `exwm-mode' buffer when this
hook runs.")
(declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id))
(declare-function exwm-layout--show "exwm-layout.el" (id &optional window))
(declare-function exwm-reset "exwm.el" ())
-(declare-function exwm-workspace--client-p "exwm-workspace.el"
- (&optional frame))
(declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace--workspace-p "exwm-workspace.el" (workspace))
(declare-function exwm-workspace-switch "exwm-workspace.el"
@@ -296,8 +294,9 @@ ARGS are additional arguments to CALLBACK."
(defun exwm-input--on-buffer-list-update ()
"Run in `buffer-list-update-hook' to track input focus."
- (when (and (not (exwm-workspace--client-p))
- (not exwm-input--skip-buffer-list-update))
+ (when (and ; this hook is called incesantly; place cheap tests on
top
+ (not exwm-input--skip-buffer-list-update)
+ (exwm--terminal-p)) ; skip other terminals, e.g. TTY client
frames
(exwm--log "current-buffer=%S selected-window=%S"
(current-buffer) (selected-window))
(redirect-frame-focus (selected-frame) nil)
@@ -1100,30 +1099,33 @@ One use is to access the keymap bound to KEYS (as
prefix keys) in char-mode."
(defun exwm-input--on-minibuffer-setup ()
"Run in `minibuffer-setup-hook' to grab keyboard if necessary."
- (exwm--log)
- (with-current-buffer
- (window-buffer (frame-selected-window exwm-workspace--current))
- (when (and (derived-mode-p 'exwm-mode)
- (not (exwm-workspace--client-p))
- (eq exwm--selected-input-mode 'char-mode))
- (exwm-input--grab-keyboard exwm--id))))
+ (let* ((window (or (minibuffer-selected-window) ; minibuffer-setup-hook
+ (selected-window))) ; echo-area-clear-hook
+ (frame (window-frame window)))
+ (when (exwm--terminal-p frame)
+ (with-current-buffer (window-buffer window)
+ (when (and (derived-mode-p 'exwm-mode)
+ (eq exwm--selected-input-mode 'char-mode))
+ (exwm--log "Grab #x%x window=%s frame=%s" exwm--id window frame)
+ (exwm-input--grab-keyboard exwm--id))))))
(defun exwm-input--on-minibuffer-exit ()
"Run in `minibuffer-exit-hook' to release keyboard if necessary."
- (exwm--log)
- (with-current-buffer
- (window-buffer (frame-selected-window exwm-workspace--current))
- (when (and (derived-mode-p 'exwm-mode)
- (not (exwm-workspace--client-p))
- (eq exwm--selected-input-mode 'char-mode)
- (eq exwm--input-mode 'line-mode))
- (exwm-input--release-keyboard exwm--id))))
+ (let* ((window (or (minibuffer-selected-window) ; minibuffer-setup-hook
+ (selected-window))) ; echo-area-clear-hook
+ (frame (window-frame window)))
+ (when (exwm--terminal-p frame)
+ (with-current-buffer (window-buffer window)
+ (when (and (derived-mode-p 'exwm-mode)
+ (eq exwm--selected-input-mode 'char-mode)
+ (eq exwm--input-mode 'line-mode))
+ (exwm--log "Release #x%x window=%s frame=%s" exwm--id window frame)
+ (exwm-input--release-keyboard exwm--id))))))
(defun exwm-input--on-echo-area-dirty ()
"Run when new message arrives to grab keyboard if necessary."
- (when (and (not (active-minibuffer-window))
- (not (exwm-workspace--client-p))
- cursor-in-echo-area)
+ (when (and cursor-in-echo-area
+ (not (active-minibuffer-window)))
(exwm--log)
(exwm-input--on-minibuffer-setup)))
diff --git a/exwm-layout.el b/exwm-layout.el
index 9173a1c049..3d78b42655 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -57,8 +57,6 @@
(declare-function exwm-input--grab-keyboard "exwm-input.el")
(declare-function exwm-input-grab-keyboard "exwm-input.el")
(declare-function exwm-workspace--active-p "exwm-workspace.el" (frame))
-(declare-function exwm-workspace--client-p "exwm-workspace.el"
- (&optional frame))
(declare-function exwm-workspace--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace--workspace-p "exwm-workspace.el"
(workspace))
@@ -405,22 +403,27 @@ selected by `other-buffer'."
(defun exwm-layout--on-minibuffer-setup ()
"Refresh layout when minibuffer grows."
(exwm--log)
- (unless (exwm-workspace--client-p)
+ ;; Only when the minibuffer's frame is an EXWM frame.
+ ;; FIXME: would it be enough checking for workspace frames?
+ (when (exwm--terminal-p)
(exwm--defer 0 (lambda ()
(when (< 1 (window-height (minibuffer-window)))
(exwm-layout--refresh))))))
(defun exwm-layout--on-echo-area-change (&optional dirty)
"Run when message arrives or in `echo-area-clear-hook' to refresh layout."
- (when (and (current-message)
- (not (exwm-workspace--client-p))
- (or (cl-position ?\n (current-message))
- (> (length (current-message))
- (frame-width exwm-workspace--current))))
- (exwm--log)
- (if dirty
- (exwm-layout--refresh)
- (exwm--defer 0 #'exwm-layout--refresh))))
+ (let ((frame (window-frame (minibuffer-window)))
+ (msg (current-message)))
+ ;; Check whether the frame where current window's minibuffer resides (not
+ ;; current window's frame for floating windows!) must be adjusted.
+ (when (and msg
+ (exwm--terminal-p frame)
+ (or (cl-position ?\n msg)
+ (> (length msg) (frame-width frame))))
+ (exwm--log)
+ (if dirty
+ (exwm-layout--refresh exwm-workspace--current)
+ (exwm--defer 0 #'exwm-layout--refresh exwm-workspace--current)))))
;;;###autoload
(defun exwm-layout-enlarge-window (delta &optional horizontal)
diff --git a/exwm-workspace.el b/exwm-workspace.el
index 12319958ca..06217a7769 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -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))
diff --git a/exwm.el b/exwm.el
index 61595634e3..345f76beb6 100644
--- a/exwm.el
+++ b/exwm.el
@@ -127,7 +127,7 @@
"Restart EXWM."
(interactive)
(exwm--log)
- (when (exwm--confirm-kill-emacs "[EXWM] Restart? " 'no-check)
+ (when (exwm--confirm-kill-emacs "Restart?" 'no-check)
(let* ((attr (process-attributes (emacs-pid)))
(args (cdr (assq 'args attr)))
(ppid (cdr (assq 'ppid attr)))
@@ -434,7 +434,6 @@
((and (> current requested)
(> current 1))
(let ((frame (car (last exwm-workspace--list))))
- (exwm-workspace--get-remove-frame-next-workspace frame)
(delete-frame frame))))))
;; _NET_CURRENT_DESKTOP.
((= type xcb:Atom:_NET_CURRENT_DESKTOP)
@@ -610,6 +609,13 @@
(eq selection xcb:Atom:WM_S0))
(exwm-exit))))
+(defun exwm--on-delete-terminal (terminal)
+ "Handle terminal being deleted without Emacs being killed.
+This may happen when invoking `save-buffers-kill-terminal' within an
emacsclient
+session."
+ (when (eq terminal exwm--terminal)
+ (exwm-exit)))
+
(defun exwm--init-icccm-ewmh ()
"Initialize ICCCM/EWMH support."
(exwm--log)
@@ -846,6 +852,7 @@ manager. If t, replace it, if nil, abort and ask the user
if `ask'."
(condition-case err
(progn
(exwm-enable 'undo) ;never initialize again
+ (setq exwm--terminal (frame-terminal frame))
(setq exwm--connection (xcb:connect))
(set-process-query-on-exit-flag (slot-value exwm--connection 'process)
nil) ;prevent query message on exit
@@ -868,6 +875,10 @@ manager. If t, replace it, if nil, abort and ask the user
if `ask'."
;; Disable some features not working well with EXWM
(setq use-dialog-box nil
confirm-kill-emacs #'exwm--confirm-kill-emacs)
+ (advice-add 'save-buffers-kill-terminal
+ :before-while #'exwm--confirm-kill-terminal)
+ ;; Clean up if the terminal is deleted.
+ (add-hook 'delete-terminal-functions 'exwm--on-delete-terminal)
(exwm--lock)
(exwm--init-icccm-ewmh)
(exwm-layout--init)
@@ -904,7 +915,9 @@ manager. If t, replace it, if nil, abort and ask the user
if `ask'."
(when exwm--connection
(xcb:flush exwm--connection)
(xcb:disconnect exwm--connection))
- (setq exwm--connection nil))
+ (setq exwm--connection nil)
+ (setq exwm--terminal nil)
+ (exwm--log "Exited"))
;;;###autoload
(defun exwm-enable (&optional undo)
@@ -983,6 +996,14 @@ manager. If t, replace it, if nil, abort and ask the user
if `ask'."
;; For other types, return the value as-is.
(t result))))))
+(defun exwm--confirm-kill-terminal (&optional _)
+ "Confirm before killing terminal."
+ ;; This is invoked instead of `save-buffers-kill-emacs' (C-x C-c) on client
+ ;; frames.
+ (if (exwm--terminal-p)
+ (exwm--confirm-kill-emacs "[EXWM] Kill terminal?")
+ t))
+
(defun exwm--confirm-kill-emacs (prompt &optional force)
"Confirm before exiting Emacs."
(exwm--log)
@@ -1001,7 +1022,7 @@ manager. If t, replace it, if nil, abort and ask the
user if `ask'."
(`break (y-or-n-p prompt))
(x x)))
(t
- (yes-or-no-p (format "[EXWM] %d window(s) will be destroyed. %s"
+ (yes-or-no-p (format "[EXWM] %d X window(s) will be destroyed. %s"
(length exwm--id-buffer-alist) prompt))))
;; Run `kill-emacs-hook' (`server-force-stop' excluded) before Emacs
;; frames are unmapped so that errors (if any) can be visible.
- [elpa] externals/exwm updated (6408a74312 -> b62d5e79b0), ELPA Syncer, 2022/11/22
- [elpa] externals/exwm 62ffde76aa 1/8: Refactor `exwm-workspace--get-remove-frame-next-workspace', ELPA Syncer, 2022/11/22
- [elpa] externals/exwm d4a7d16676 5/8: Improve confirmation prompts, ELPA Syncer, 2022/11/22
- [elpa] externals/exwm a11bb099fb 2/8: Refactor re-creation of last frame, ELPA Syncer, 2022/11/22
- [elpa] externals/exwm b62d5e79b0 8/8: Use `active-minibuffer-window' rather than `minibuffer-window', ELPA Syncer, 2022/11/22
- [elpa] externals/exwm 1c706daeb0 7/8: Merge branch 'drop-client-p' into externals/exwm,
ELPA Syncer <=
- [elpa] externals/exwm ca7623349e 4/8: Leave `client' frame parameter in place, ELPA Syncer, 2022/11/22
- [elpa] externals/exwm 1aa4ca781d 3/8: Support for killing the X terminal, ELPA Syncer, 2022/11/22
- [elpa] externals/exwm d6f62ff55a 6/8: Check EXWM terminal instead of client or graphical frames, ELPA Syncer, 2022/11/22