diff options
Diffstat (limited to 'exwm-input.el')
-rw-r--r-- | exwm-input.el | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/exwm-input.el b/exwm-input.el index a7fb16a1755f..d0ae4ad81250 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -1,6 +1,6 @@ ;;; exwm-input.el --- Input Module for EXWM -*- lexical-binding: t -*- -;; Copyright (C) 2015-2018 Free Software Foundation, Inc. +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. ;; Author: Chris Feng <chris.w.feng@gmail.com> @@ -117,6 +117,9 @@ defined in `exwm-mode-map' here." (defvar exwm-input--simulation-keys nil "Simulation keys in line-mode.") +(defvar exwm-input--skip-buffer-list-update nil + "Skip the upcoming 'buffer-list-update'.") + (defvar exwm-input--temp-line-mode nil "Non-nil indicates it's in temporary line-mode for char-mode.") @@ -224,7 +227,7 @@ ARGS are additional arguments to CALLBACK." (with-slots (time root event root-x root-y event-x event-y state) evt (setq buffer (exwm--id->buffer event) window (get-buffer-window buffer t)) - (exwm--log "EnterNotify: buffer=%s; window=%s" buffer window) + (exwm--log "buffer=%s; window=%s" buffer window) (when (and buffer window (not (eq window (selected-window)))) (setq frame (window-frame window) frame-xid (frame-parameter frame 'exwm-id)) @@ -260,12 +263,14 @@ ARGS are additional arguments to CALLBACK." (xcb:flush exwm--connection))))) (defun exwm-input--on-keysyms-update () + (exwm--log) (let ((exwm-input--global-prefix-keys nil)) (exwm-input--update-global-prefix-keys))) (defun exwm-input--on-buffer-list-update () "Run in `buffer-list-update-hook' to track input focus." (when (and (not (eq this-command #'handle-switch-frame)) + (not exwm-input--skip-buffer-list-update) (not (exwm-workspace--client-p)) ;; The following conditions filter out events relating to temp ;; buffers. @@ -380,6 +385,7 @@ ARGS are additional arguments to CALLBACK." buffer (exwm--id->buffer event) window (get-buffer-window buffer t)) (cond ((and (eq button-event exwm-input-move-event) + buffer ;; Either an undecorated or a floating X window. (with-current-buffer buffer (or (not (derived-mode-p 'exwm-mode)) @@ -388,12 +394,13 @@ ARGS are additional arguments to CALLBACK." (exwm-floating--start-moveresize event xcb:ewmh:_NET_WM_MOVERESIZE_MOVE)) ((and (eq button-event exwm-input-resize-event) + buffer (with-current-buffer buffer (or (not (derived-mode-p 'exwm-mode)) exwm--floating-frame))) ;; Resize (exwm-floating--start-moveresize event)) - (t + (buffer ;; Click to focus (unless (eq window (selected-window)) (setq frame (window-frame window)) @@ -412,13 +419,18 @@ ARGS are additional arguments to CALLBACK." (select-window window) (setq window (get-buffer-window buffer t)) (when window (select-window window)))) + ;; Also process keybindings. (with-current-buffer buffer (when (derived-mode-p 'exwm-mode) (cl-case exwm--input-mode (line-mode - (setq mode (exwm-input--on-ButtonPress-line-mode buffer button-event))) + (setq mode (exwm-input--on-ButtonPress-line-mode + buffer button-event))) (char-mode - (setq mode (exwm-input--on-ButtonPress-char-mode))))))))) + (setq mode (exwm-input--on-ButtonPress-char-mode))))))) + (t + ;; Replay this event by default. + (setq mode xcb:Allow:ReplayPointer)))) (xcb:+request exwm--connection (make-instance 'xcb:AllowEvents :mode mode :time xcb:Time:CurrentTime)) (xcb:flush exwm--connection)) @@ -491,6 +503,7 @@ ARGS are additional arguments to CALLBACK." (xcb:flush exwm--connection))) (defun exwm-input--set-key (key command) + (exwm--log "key: %s, command: %s" key command) (global-set-key key command) (cl-pushnew key exwm-input--global-keys)) @@ -534,9 +547,9 @@ instead." (exwm-input--update-global-prefix-keys))) ;; Putting (t . EVENT) into `unread-command-events' does not really work -;; as documented for Emacs < 27. +;; as documented for Emacs < 26.2. (eval-and-compile - (if (< emacs-major-version 27) + (if (string-version-lessp emacs-version "26.2") (defsubst exwm-input--unread-event (event) (setq unread-command-events (append unread-command-events (list event)))) @@ -570,8 +583,9 @@ instead." (cl-return-from exwm-input--translate translation))))) key) -(defun exwm-input--cache-event (event) +(defun exwm-input--cache-event (event &optional temp-line-mode) "Cache EVENT." + (exwm--log "%s" event) (setq exwm-input--line-mode-cache (vconcat exwm-input--line-mode-cache (vector event))) ;; Attempt to translate this key sequence. @@ -580,8 +594,12 @@ instead." ;; When the key sequence is complete (not a keymap). ;; Note that `exwm-input--line-mode-cache' might get translated to nil, for ;; example 'mouse--down-1-maybe-follows-link' does this. - (unless (and exwm-input--line-mode-cache - (keymapp (key-binding exwm-input--line-mode-cache))) + (if (and exwm-input--line-mode-cache + (keymapp (key-binding exwm-input--line-mode-cache))) + ;; Grab keyboard temporarily to intercept the complete key sequence. + (when temp-line-mode + (setq exwm-input--temp-line-mode t) + (exwm-input--grab-keyboard)) (setq exwm-input--line-mode-cache nil) (when exwm-input--temp-line-mode (setq exwm-input--temp-line-mode nil) @@ -657,10 +675,7 @@ Current buffer must be an `exwm-mode' buffer." (setq event (exwm-input--mimic-read-event raw-event))) (if (not (derived-mode-p 'exwm-mode)) (exwm-input--unread-event raw-event) - ;; Grab keyboard temporarily. - (setq exwm-input--temp-line-mode t) - (exwm-input--grab-keyboard) - (exwm-input--cache-event event) + (exwm-input--cache-event event t) (exwm-input--unread-event raw-event))))) (xcb:+request exwm--connection (make-instance 'xcb:AllowEvents @@ -677,6 +692,7 @@ The return value is used as event_mode to release the original button event." (with-current-buffer buffer (let ((read-event (exwm-input--mimic-read-event button-event))) + (exwm--log "%s" read-event) (if (and read-event (exwm-input--event-passthrough-p read-event)) ;; The event should be forwarded to emacs @@ -691,10 +707,12 @@ button event." "Handle button events in char-mode. The return value is used as event_mode to release the original button event." + (exwm--log) xcb:Allow:ReplayPointer) (defun exwm-input--update-mode-line (id) "Update the propertized `mode-line-process' for window ID." + (exwm--log "#x%x" id) (let (help-echo cmd mode) (cl-case exwm--input-mode (line-mode @@ -826,6 +844,7 @@ button event." EXWM will prompt for the key to send. This command can be prefixed to send multiple keys." (interactive "p") + (exwm--log) (unless (derived-mode-p 'exwm-mode) (cl-return-from exwm-input-send-next-key)) (when (> times 12) (setq times 12)) @@ -844,6 +863,7 @@ multiple keys." (defun exwm-input--set-simulation-keys (simulation-keys &optional no-refresh) "Set simulation keys." + (exwm--log "%s" simulation-keys) (unless no-refresh ;; Unbind simulation keys. (let ((hash (buffer-local-value 'exwm-input--simulation-keys @@ -894,14 +914,15 @@ Notes: * Setting the value directly (rather than customizing it) after EXWM finishes initialization has no effect. * Original-keys consist of multiple key events are only supported in Emacs - 27 and later. + 26.2 and later. * A minority of applications do not accept simulated keys by default. It's required to customize them to accept events sent by SendEvent. * The predefined examples in the Customize interface are not guaranteed to work for all applications. This can be tweaked on a per application basis with `exwm-input-set-local-simulation-keys'." - :type '(alist :key-type (choice (key-sequence :tag "Original")) - :value-type (choice (key-sequence :tag "Move left" [left]) + :type '(alist :key-type (key-sequence :tag "Original") + :value-type (choice (key-sequence :tag "User-defined") + (key-sequence :tag "Move left" [left]) (key-sequence :tag "Move right" [right]) (key-sequence :tag "Move up" [up]) (key-sequence :tag "Move down" [down]) @@ -913,8 +934,7 @@ Notes: (key-sequence :tag "Paste" [C-v]) (key-sequence :tag "Delete" [delete]) (key-sequence :tag "Delete to EOL" - [S-end delete]) - (key-sequence :tag "User-defined"))) + [S-end delete]))) :set (lambda (symbol value) (set symbol value) (exwm-input--set-simulation-keys value))) @@ -945,6 +965,7 @@ ends unless it's specifically saved in the Customize interface for (format "Simulate %s as" (key-description original)) ?\C-g))) (list original simulated))) + (exwm--log "original: %s, simulated: %s" original-key simulated-key) (when (and original-key simulated-key) (let ((entry `((,original-key . ,simulated-key)))) (setq exwm-input-simulation-keys (append exwm-input-simulation-keys @@ -953,6 +974,7 @@ ends unless it's specifically saved in the Customize interface for (defun exwm-input--unset-simulation-keys () "Clear simulation keys and key bindings defined." + (exwm--log) (when (hash-table-p exwm-input--simulation-keys) (maphash (lambda (key _value) (when (sequencep key) @@ -965,6 +987,7 @@ ends unless it's specifically saved in the Customize interface for SIMULATION-KEYS is an alist of the form (original-key . simulated-key), where both ORIGINAL-KEY and SIMULATED-KEY are key sequences." + (exwm--log) (make-local-variable 'exwm-input--simulation-keys) (use-local-map (copy-keymap exwm-mode-map)) (let ((exwm-input--local-simulation-keys t)) @@ -974,6 +997,7 @@ where both ORIGINAL-KEY and SIMULATED-KEY are key sequences." (cl-defun exwm-input-send-simulation-key (times) "Fake a key event according to the last input key sequence." (interactive "p") + (exwm--log) (unless (derived-mode-p 'exwm-mode) (cl-return-from exwm-input-send-simulation-key)) (let ((keys (gethash (this-single-command-keys) @@ -993,6 +1017,7 @@ where both ORIGINAL-KEY and SIMULATED-KEY are key sequences." (defun exwm-input--init () "Initialize the keyboard module." + (exwm--log) ;; Refresh keyboard mapping (xcb:keysyms:init exwm--connection #'exwm-input--on-keysyms-update) ;; Create the X window and intern the atom used to fetch timestamp. @@ -1015,14 +1040,7 @@ where both ORIGINAL-KEY and SIMULATED-KEY are key sequences." (make-instance 'xcb:ewmh:set-_NET_WM_NAME :window exwm-input--timestamp-window :data "EXWM: exwm-input--timestamp-window")) - (let ((atom "_TIME")) - (setq exwm-input--timestamp-atom - (slot-value (xcb:+request-unchecked+reply exwm--connection - (make-instance 'xcb:InternAtom - :only-if-exists 0 - :name-len (length atom) - :name atom)) - 'atom))) + (setq exwm-input--timestamp-atom (exwm--intern-atom "_TIME")) ;; Initialize global keys. (dolist (i exwm-input-global-keys) (exwm-input--set-key (car i) (cdr i))) @@ -1050,10 +1068,12 @@ where both ORIGINAL-KEY and SIMULATED-KEY are key sequences." (defun exwm-input--post-init () "The second stage in the initialization of the input module." + (exwm--log) (exwm-input--update-global-prefix-keys)) (defun exwm-input--exit () "Exit the input module." + (exwm--log) (exwm-input--unset-simulation-keys) (remove-hook 'pre-command-hook #'exwm-input--on-pre-command) (remove-hook 'post-command-hook #'exwm-input--on-post-command) |