diff --git a/exwm-core.el b/exwm-core.el index 5bcf943..85bbe58 100644 --- a/exwm-core.el +++ b/exwm-core.el @@ -180,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 c27ee1b..79bc78e 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,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 () "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." - (exwm--log) - (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))) (defun exwm-input--on-echo-area-clear () "Run in `echo-area-clear-hook' to release keyboard if necessary." - (exwm--log) (unless (current-message) + (exwm--log) (exwm-input--on-minibuffer-exit))) (defun exwm-input--init () diff --git a/exwm-layout.el b/exwm-layout.el index 9173a1c..3d78b42 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 3e53a7a..450a381 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -162,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.") @@ -1126,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)) @@ -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." (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 @@ -1265,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) @@ -1297,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 @@ -1455,8 +1439,7 @@ Return nil if FRAME is the only workspace." ((not (exwm-workspace--workspace-p frame)) (exwm--log "Frame `%s' is not a workspace" frame)) (t - (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. @@ -1471,6 +1454,11 @@ Called from a timer." (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)) diff --git a/exwm.el b/exwm.el index 8a85002..ecce55c 100644 --- a/exwm.el +++ b/exwm.el @@ -995,7 +995,7 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'." "Confirm before killing terminal." ;; This is invoked instead of `save-buffers-kill-emacs' (C-x C-c) on client ;; frames. - (if (eq (frame-terminal) exwm--terminal) + (if (exwm--terminal-p) (exwm--confirm-kill-emacs "[EXWM] Kill terminal?") t))