From 6fdc3fac5658a7ab142c358cddd90f3db5665ef5 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Fri, 8 Jun 2018 22:47:27 -0700 Subject: [PATCH] Support terminal focus notifications * lisp/frame.el (handle-focus-in,handle-focus-out): Make event argument optional. (blink-cursor-check): Make sure that the current frame is a window-system frame before restarting the blink timer. TTY frames can get focus, but don't need a blink timer because the terminal will do the blinking. * lisp/term/xterm.el (xterm-handle-focus-in,xterm-handle-focus-out): New functions. (xterm-rxvt-function-map): Recognize focus notification sequences. (xterm--init-focus-tracking): New function. (terminal-init-xterm): Call it. --- etc/NEWS | 5 +++++ lisp/frame.el | 7 ++++--- lisp/term/xterm.el | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 46a57b1888c..3371718473f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -575,6 +575,11 @@ manual for more details. * Lisp Changes in Emacs 27.1 ++++ +** Emacs now requests and recognizes focus-change notifications from + terminals that support the feature, meaning that `focus-in-hook' + and `focus-out-hook' may run for TTY frames. + +++ ** Face specifications (of the kind used in `face-remapping-alist') now support filters, allowing faces to vary between windows display diff --git a/lisp/frame.el b/lisp/frame.el index 359c5036557..c3daff44406 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -129,7 +129,7 @@ appended when the minibuffer frame is created." ;; Gildea@x.org says it is ok to ask questions before terminating. (save-buffers-kill-emacs)))) -(defun handle-focus-in (_event) +(defun handle-focus-in (&optional _event) "Handle a focus-in event. Focus-in events are usually bound to this function. Focus-in events occur when a frame has focus, but a switch-frame event @@ -138,7 +138,7 @@ This function runs the hook `focus-in-hook'." (interactive "e") (run-hooks 'focus-in-hook)) -(defun handle-focus-out (_event) +(defun handle-focus-out (&optional _event) "Handle a focus-out event. Focus-out events are usually bound to this function. Focus-out events occur when no frame has focus. @@ -2339,7 +2339,8 @@ frame receives focus." This is done when a frame gets focus. Blink timers may be stopped by `blink-cursor-suspend'." (when (and blink-cursor-mode - (not blink-cursor-idle-timer)) + (not blink-cursor-idle-timer) + (display-graphic-p)) (remove-hook 'post-command-hook 'blink-cursor-check) (blink-cursor--start-idle-timer))) diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index fea9851d720..6410a4b83c9 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -104,6 +104,16 @@ Return the pasted text as a string." (define-key global-map [xterm-paste] #'xterm-paste) +(defun xterm-handle-focus-in () + (interactive) + (handle-focus-in)) +(define-key global-map [xterm-focus-in] #'xterm-handle-focus-in) + +(defun xterm-handle-focus-out () + (interactive) + (handle-focus-out)) +(define-key global-map [xterm-focus-out] #'xterm-handle-focus-out) + (defvar xterm-rxvt-function-map (let ((map (make-sparse-keymap))) (define-key map "\e[2~" [insert]) @@ -136,6 +146,9 @@ Return the pasted text as a string." ;; internally recognizes the end. (define-key map "\e[200~" [xterm-paste]) + (define-key map "\e[I" [xterm-focus-in]) + (define-key map "\e[O" [xterm-focus-out]) + map) "Keymap of escape sequences, shared between xterm and rxvt support.") @@ -817,6 +830,8 @@ We run the first FUNCTION whose STRING matches the input events." ;; Unconditionally enable bracketed paste mode: terminals that don't ;; support it just ignore the sequence. (xterm--init-bracketed-paste-mode) + ;; We likewise unconditionally enable support for focus tracking. + (xterm--init-focus-tracking) (run-hooks 'terminal-init-xterm-hook)) @@ -832,6 +847,12 @@ We run the first FUNCTION whose STRING matches the input events." (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings)) (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings))) +(defun xterm--init-focus-tracking () + "Terminal initialization for focus tracking mode." + (send-string-to-terminal "\e[?1004h") + (push "\e[?1004l" (terminal-parameter nil 'tty-mode-reset-strings)) + (push "\e[?1004h" (terminal-parameter nil 'tty-mode-set-strings))) + (defun xterm--init-activate-get-selection () "Terminal initialization for `gui-get-selection'." (set-terminal-parameter nil 'xterm--get-selection t)) -- 2.39.2