Re: Send prefix key to emacs does not work (`send-escape')

Phil Hudson <[email protected]> Tue, 24 Feb 2026 20:45:56 +0000
Newsgroups gmane.comp.window-managers.stumpwm.devel
Message-ID <[email protected]>
Here's what I have, based on someone else's code found online, slightly 
modified and with one extra modified command:


;; from https://notabug.org/grafov/stumpwm-config/src/master/utils.lisp
(defun al/class-window-p (class &optional (win (current-window)))
   "Return T if a window WIN is of class CLASS."
   (and win (string= class (window-class win))))

(defcommand al/focus-window-by-class (class) ((:string "Window class: "))
   "Focus window class CLASS.
Return the window or nil if there is no such."
   (if (al/class-window-p class)
       (current-window)
     (let ((win (car (or ;; priority to the window from the current group
                      (find-matching-windows (list :class class) nil nil)
                      (find-matching-windows (list :class class) t t)))))
       (if win
           (focus-all win)
         (message "No ~a window." class))
       win)))

;;; Sending keys to windows

(defcommand al/send-key (key &optional (win (current-window))) (:key)
   "Send key press and key release events for KEY to window WIN."
   (let ((xwin (window-xwin win)))
     (multiple-value-bind (code state) (key-to-keycode+state key)
       (flet ((send (event)
                    (xlib:send-event xwin event (xlib:make-event-mask event)
                                     :display *display*
                                     :root (screen-root (window-screen win))
                                     :x 0 :y 0 :root-x 0 :root-y 0
                                     :window xwin :event-window xwin
                                     :code code
                                     :state state)))
         (send :key-press)
         (send :key-release)
         (xlib:display-finish-output *display*)))))

(defun al/send-keys (keys &key (win (current-window))
                           (sleep 0) loop loop-quit-var)
   "Send keys to the window WIN.

KEYS is a string for `kbd', a list of such strings or functions or a
function returning a string or a list.

SLEEP is a time between sending keys or a function for defining
this time.

If LOOP is t, send keys in a loop (the whole combination of strings,
lists and functions in KEYS will be repeated).  It will be broken when
a variable which name is passed to LOOP-QUIT-VAR returns t.  Be aware,
infinite loop is not a joke."
   (labels ((send-key (key)
                      (al/send-key (kbd key) win)
                      ;; (print key)
                      (sleep (if (numberp sleep)
                                 sleep
                               (funcall sleep))))
            (send-keys (key-def &optional loop)
                       (loop
                        do (cond
                            ((stringp key-def)
                             (send-key key-def))
                            ((listp key-def)
                             (dolist (key key-def) (send-keys key)))
                            ((functionp key-def)
                             (send-keys (funcall key-def)))
                            (t (error "Keys should be a string, a list 
or a function")))
                        while (and loop
                                   (null (and loop-quit-var (eval 
loop-quit-var)))))))
     (send-keys keys loop)
     (echo "Quitting sending keys.")))

;;; Interacting with emacs

(defun ph/emacs-window-p (&optional (window (current-window)))
   "Return non-nil, if WINDOW is Emacs window in the current frame."
   (al/class-window-p "Emacs" window))

(defcommand al/send-key-to-emacs (key) ((:key "Key: "))
   "Focus emacs window and send KEY to it."
   (let ((win (al/focus-window-by-class "Emacs")))
     (and win (al/send-key key win))))

(defun ph/send-keys-to-emacs (keys)
   "Focus emacs window and send KEYS to it."
   (let ((win (al/focus-window-by-class "Emacs")))
     (and win (mapc #'al/send-key-to-emacs (mapcar #'kbd keys)))))

(defcommand al/emacs-eval (arg &optional server-name) ((:shell 
"emacs-eval: "))
   "Evaluate ARG with emacsclient."
   (let ((args (list "--eval" arg)))
     (when server-name
       (setq args (append (list "--socket-name" server-name) args)))
     (run-prog "emacsclient" :args args :wait nil :search t)))

(defcommand al/emacs-eval-show (arg) ((:shell "emacs-eval: "))
   "Evaluate ARG with emacsclient and raise emacs."
   (al/emacs-eval arg)
   (or (ph/emacs-window-p) (emacs)))



On 2026-02-24 13:05, StyxSailor wrote:
> Hello, as the title I am trying to send the prefix key `C-t' to emacs
> through `send-escape' (C-t t), but it doesn't go through to emacs. It
> works on firefox however. What am I missing here?
>
> stumpwm version is 24.11, emacs version 30.2, firefox 147.0.4
>
> All the best!
>