Check EXWM terminal instead of client or graphical frames

* exwm-core.el (exwm--terminal-p): Add function.
* exwm.el (exwm--confirm-kill-terminal): Use it.
* exwm-input.el (exwm-input--on-buffer-list-update): Use it.
(exwm-input--on-minibuffer-setup)
(exwm-input--on-minibuffer-exit): Use it.
(exwm-input--on-minibuffer-exit): Use the minibuffer's selected
window's frame or selected frame instead of current workspace.
(exwm-input--on-echo-area-dirty): Removed test, as it's checked in
`exwm-input--on-minibuffer-setup'.
* exwm-layout.el (exwm-layout--on-minibuffer-setup)
(exwm-layout--on-echo-area-change): Use it.
(exwm-layout--on-echo-area-change): Refresh layout the
frame of selected window's minibuffer if it's an EXWM frame.
* exwm-workspace.el (exwm-workspace--update-minibuffer-height)
(exwm-workspace--on-minibuffer-setup)
(exwm-workspace--on-minibuffer-exit)
(exwm-workspace--on-echo-area-dirty)
(exwm-workspace--on-echo-area-clear)
(exwm-workspace--on-delete-frame): Use it.
* exwm-workspace.el (exwm-workspace--client-p-hash-table): Remove
variable.
(exwm-workspace--client-p): Remove function.
This commit is contained in:
Adrián Medraño Calvo 2021-12-09 00:00:00 +00:00
parent d4a7d16676
commit d6f62ff55a
5 changed files with 59 additions and 61 deletions

View file

@ -180,6 +180,11 @@ least SECS seconds later."
,function ,function
,@args)) ,@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 () (defun exwm--get-client-event-mask ()
"Return event mask set on all managed windows." "Return event mask set on all managed windows."
(logior xcb:EventMask:StructureNotify (logior xcb:EventMask:StructureNotify

View file

@ -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--iconic-state-p "exwm-layout.el" (&optional id))
(declare-function exwm-layout--show "exwm-layout.el" (id &optional window)) (declare-function exwm-layout--show "exwm-layout.el" (id &optional window))
(declare-function exwm-reset "exwm.el" ()) (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--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace--workspace-p "exwm-workspace.el" (workspace)) (declare-function exwm-workspace--workspace-p "exwm-workspace.el" (workspace))
(declare-function exwm-workspace-switch "exwm-workspace.el" (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 () (defun exwm-input--on-buffer-list-update ()
"Run in `buffer-list-update-hook' to track input focus." "Run in `buffer-list-update-hook' to track input focus."
(when (and (not (exwm-workspace--client-p)) (when (and ; this hook is called incesantly; place cheap tests on top
(not exwm-input--skip-buffer-list-update)) (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" (exwm--log "current-buffer=%S selected-window=%S"
(current-buffer) (selected-window)) (current-buffer) (selected-window))
(redirect-frame-focus (selected-frame) nil) (redirect-frame-focus (selected-frame) nil)
@ -1100,37 +1099,40 @@ One use is to access the keymap bound to KEYS (as prefix keys) in char-mode."
(defun exwm-input--on-minibuffer-setup () (defun exwm-input--on-minibuffer-setup ()
"Run in `minibuffer-setup-hook' to grab keyboard if necessary." "Run in `minibuffer-setup-hook' to grab keyboard if necessary."
(exwm--log) (let* ((window (or (minibuffer-selected-window) ; minibuffer-setup-hook
(with-current-buffer (selected-window))) ; echo-area-clear-hook
(window-buffer (frame-selected-window exwm-workspace--current)) (frame (window-frame window)))
(when (and (derived-mode-p 'exwm-mode) (when (exwm--terminal-p frame)
(not (exwm-workspace--client-p)) (with-current-buffer (window-buffer window)
(eq exwm--selected-input-mode 'char-mode)) (when (and (derived-mode-p 'exwm-mode)
(exwm-input--grab-keyboard exwm--id)))) (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 () (defun exwm-input--on-minibuffer-exit ()
"Run in `minibuffer-exit-hook' to release keyboard if necessary." "Run in `minibuffer-exit-hook' to release keyboard if necessary."
(exwm--log) (let* ((window (or (minibuffer-selected-window) ; minibuffer-setup-hook
(with-current-buffer (selected-window))) ; echo-area-clear-hook
(window-buffer (frame-selected-window exwm-workspace--current)) (frame (window-frame window)))
(when (and (derived-mode-p 'exwm-mode) (when (exwm--terminal-p frame)
(not (exwm-workspace--client-p)) (with-current-buffer (window-buffer window)
(eq exwm--selected-input-mode 'char-mode) (when (and (derived-mode-p 'exwm-mode)
(eq exwm--input-mode 'line-mode)) (eq exwm--selected-input-mode 'char-mode)
(exwm-input--release-keyboard exwm--id)))) (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 () (defun exwm-input--on-echo-area-dirty ()
"Run when new message arrives to grab keyboard if necessary." "Run when new message arrives to grab keyboard if necessary."
(exwm--log) (when (and cursor-in-echo-area
(when (and (not (active-minibuffer-window)) (not (active-minibuffer-window)))
(not (exwm-workspace--client-p)) (exwm--log)
cursor-in-echo-area)
(exwm-input--on-minibuffer-setup))) (exwm-input--on-minibuffer-setup)))
(defun exwm-input--on-echo-area-clear () (defun exwm-input--on-echo-area-clear ()
"Run in `echo-area-clear-hook' to release keyboard if necessary." "Run in `echo-area-clear-hook' to release keyboard if necessary."
(exwm--log)
(unless (current-message) (unless (current-message)
(exwm--log)
(exwm-input--on-minibuffer-exit))) (exwm-input--on-minibuffer-exit)))
(defun exwm-input--init () (defun exwm-input--init ()

View file

@ -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-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--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--minibuffer-own-frame-p "exwm-workspace.el")
(declare-function exwm-workspace--workspace-p "exwm-workspace.el" (declare-function exwm-workspace--workspace-p "exwm-workspace.el"
(workspace)) (workspace))
@ -405,22 +403,27 @@ selected by `other-buffer'."
(defun exwm-layout--on-minibuffer-setup () (defun exwm-layout--on-minibuffer-setup ()
"Refresh layout when minibuffer grows." "Refresh layout when minibuffer grows."
(exwm--log) (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 () (exwm--defer 0 (lambda ()
(when (< 1 (window-height (minibuffer-window))) (when (< 1 (window-height (minibuffer-window)))
(exwm-layout--refresh)))))) (exwm-layout--refresh))))))
(defun exwm-layout--on-echo-area-change (&optional dirty) (defun exwm-layout--on-echo-area-change (&optional dirty)
"Run when message arrives or in `echo-area-clear-hook' to refresh layout." "Run when message arrives or in `echo-area-clear-hook' to refresh layout."
(when (and (current-message) (let ((frame (window-frame (minibuffer-window)))
(not (exwm-workspace--client-p)) (msg (current-message)))
(or (cl-position ?\n (current-message)) ;; Check whether the frame where current window's minibuffer resides (not
(> (length (current-message)) ;; current window's frame for floating windows!) must be adjusted.
(frame-width exwm-workspace--current)))) (when (and msg
(exwm--log) (exwm--terminal-p frame)
(if dirty (or (cl-position ?\n msg)
(exwm-layout--refresh) (> (length msg) (frame-width frame))))
(exwm--defer 0 #'exwm-layout--refresh)))) (exwm--log)
(if dirty
(exwm-layout--refresh exwm-workspace--current)
(exwm--defer 0 #'exwm-layout--refresh exwm-workspace--current)))))
;;;###autoload ;;;###autoload
(defun exwm-layout-enlarge-window (delta &optional horizontal) (defun exwm-layout-enlarge-window (delta &optional horizontal)

View file

@ -162,22 +162,6 @@ 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))
(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 (defvar exwm-workspace--switch-map nil
"Keymap used for interactively selecting workspace.") "Keymap used for interactively selecting workspace.")
@ -1126,7 +1110,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(defun exwm-workspace--update-minibuffer-height (&optional echo-area) (defun exwm-workspace--update-minibuffer-height (&optional echo-area)
"Update the minibuffer frame height." "Update the minibuffer frame height."
(unless (exwm-workspace--client-p) (when (exwm--terminal-p)
(let ((height (let ((height
(with-current-buffer (with-current-buffer
(window-buffer (minibuffer-window exwm-workspace--minibuffer)) (window-buffer (minibuffer-window exwm-workspace--minibuffer))
@ -1243,7 +1227,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
"Run in minibuffer-setup-hook to show the minibuffer and its container." "Run in minibuffer-setup-hook to show the minibuffer and its container."
(exwm--log) (exwm--log)
(when (and (= 1 (minibuffer-depth)) (when (and (= 1 (minibuffer-depth))
(not (exwm-workspace--client-p))) (exwm--terminal-p))
(add-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height) (add-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height)
(exwm-workspace--show-minibuffer)) (exwm-workspace--show-minibuffer))
;; FIXME: This is a temporary fix for the *Completions* buffer not ;; FIXME: This is a temporary fix for the *Completions* buffer not
@ -1265,16 +1249,16 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
"Run in minibuffer-exit-hook to hide the minibuffer container." "Run in minibuffer-exit-hook to hide the minibuffer container."
(exwm--log) (exwm--log)
(when (and (= 1 (minibuffer-depth)) (when (and (= 1 (minibuffer-depth))
(not (exwm-workspace--client-p))) (exwm--terminal-p))
(remove-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height) (remove-hook 'post-command-hook #'exwm-workspace--update-minibuffer-height)
(exwm-workspace--hide-minibuffer))) (exwm-workspace--hide-minibuffer)))
(defun exwm-workspace--on-echo-area-dirty () (defun exwm-workspace--on-echo-area-dirty ()
"Run when new message arrives to show the echo area and its container." "Run when new message arrives to show the echo area and its container."
(when (and (not (active-minibuffer-window)) (when (and (not (active-minibuffer-window))
(not (exwm-workspace--client-p))
(or (current-message) (or (current-message)
cursor-in-echo-area)) cursor-in-echo-area)
(exwm--terminal-p))
(exwm-workspace--update-minibuffer-height t) (exwm-workspace--update-minibuffer-height t)
(exwm-workspace--show-minibuffer) (exwm-workspace--show-minibuffer)
(unless (or (not exwm-workspace-display-echo-area-timeout) (unless (or (not exwm-workspace-display-echo-area-timeout)
@ -1297,7 +1281,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(defun exwm-workspace--on-echo-area-clear () (defun exwm-workspace--on-echo-area-clear ()
"Run in echo-area-clear-hook to hide echo area container." "Run in echo-area-clear-hook to hide echo area container."
(unless (exwm-workspace--client-p) (when (exwm--terminal-p)
(unless (active-minibuffer-window) (unless (active-minibuffer-window)
(exwm-workspace--hide-minibuffer)) (exwm-workspace--hide-minibuffer))
(when exwm-workspace--display-echo-area-timer (when exwm-workspace--display-echo-area-timer
@ -1455,8 +1439,7 @@ Return nil if FRAME is the only workspace."
((not (exwm-workspace--workspace-p frame)) ((not (exwm-workspace--workspace-p frame))
(exwm--log "Frame `%s' is not a workspace" frame)) (exwm--log "Frame `%s' is not a workspace" frame))
(t (t
(exwm-workspace--remove-frame-as-workspace frame) (exwm-workspace--remove-frame-as-workspace frame))))
(remhash frame exwm-workspace--client-p-hash-table))))
(defun exwm-workspace--fullscreen-workspace (frame) (defun exwm-workspace--fullscreen-workspace (frame)
"Make workspace FRAME fullscreen. "Make workspace FRAME fullscreen.
@ -1471,6 +1454,11 @@ Called from a timer."
(exwm--log "Frame `%s' is already a workspace" frame)) (exwm--log "Frame `%s' is already a workspace" frame))
((not (display-graphic-p frame)) ((not (display-graphic-p frame))
(exwm--log "Frame `%s' is not graphical" 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 ((not (string-equal
(replace-regexp-in-string "\\.0$" "" (replace-regexp-in-string "\\.0$" ""
(slot-value exwm--connection 'display)) (slot-value exwm--connection 'display))

View file

@ -995,7 +995,7 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
"Confirm before killing terminal." "Confirm before killing terminal."
;; This is invoked instead of `save-buffers-kill-emacs' (C-x C-c) on client ;; This is invoked instead of `save-buffers-kill-emacs' (C-x C-c) on client
;; frames. ;; frames.
(if (eq (frame-terminal) exwm--terminal) (if (exwm--terminal-p)
(exwm--confirm-kill-emacs "[EXWM] Kill terminal?") (exwm--confirm-kill-emacs "[EXWM] Kill terminal?")
t)) t))