Fix character loss with exwm-xim

* exwm-xim.el (exwm-xim--handle-forward-event-request): Events unread
can either be reused by input methods or forwarded to X windows as is.
This commit is contained in:
Chris Feng 2019-06-09 00:00:00 +00:00
parent 672a5e2a23
commit 75833e0c53

View file

@ -544,57 +544,64 @@ The actual XIM request is in client message data or a property."
exwm-xim--conn exwm-xim--conn
(car keysym) (car keysym)
(logand state (lognot (cdr keysym))))))) (logand state (lognot (cdr keysym)))))))
(if (or (not im-func) (while (or (slot-value req 'event) unread-command-events)
;; `list' is the default method. (unless (slot-value req 'event)
(eq im-func #'list) (setq event (pop unread-command-events)))
(not event) (if (or (not im-func)
;; Select only printable keys. ;; `list' is the default method.
(not (integerp event)) (> #x20 event) (< #x7e event)) (eq im-func #'list)
;; Either there is no active input method, or invalid key (not event)
;; is detected. ;; Select only printable keys.
(with-slots (im-id ic-id serial-number event) req (not (integerp event)) (> #x20 event) (< #x7e event))
(exwm-xim--make-request ;; Either there is no active input method, or invalid key
(make-instance 'xim:forward-event ;; is detected.
:im-id im-id (with-slots ((raw-event event)
:ic-id ic-id im-id ic-id serial-number)
:flag xim:commit-flag:synchronous req
:serial-number serial-number (if raw-event
:event event) (setq event raw-event)
conn client-xwin) (setq keysym (xcb:keysyms:event->keysym exwm-xim--conn event))
(xcb:flush conn)) (with-slots (detail state) key-event
(when (eq exwm--selected-input-mode 'char-mode) (setf detail (xcb:keysyms:keysym->keycode exwm-xim--conn
;; Grab keyboard temporarily for char-mode. (car keysym))
(exwm-input--grab-keyboard)) state (cdr keysym)))
(unwind-protect (setq event (let ((xcb:lsb lsb))
(with-temp-buffer (xcb:marshal key-event conn))))
;; Always show key strokes. (when event
(let ((input-method-use-echo-area t)) (exwm-xim--make-request
(while (or event unread-command-events) (make-instance 'xim:forward-event
(unless event :im-id im-id
(setq event (pop unread-command-events))) :ic-id ic-id
;; `quail-input-method' seems to unread 'return instead of :flag xim:commit-flag:synchronous
;; ?\n hence this conversion. :serial-number serial-number
(when (eq event 'return) :event event)
(setq event ?\n)) conn client-xwin)))
(when (characterp event)
(setq result (funcall im-func event))
;; This also works for portable character encoding.
(setq result
(encode-coding-string (concat result)
'compound-text-with-extensions))
(exwm-xim--make-request
(make-instance 'xim:commit-x-lookup-chars
:im-id (slot-value req 'im-id)
:ic-id (slot-value req 'ic-id)
:flag (logior xim:commit-flag:synchronous
xim:commit-flag:x-lookup-chars)
:length (length result)
:string result)
conn client-xwin)
(xcb:flush conn))
(setq event nil))))
(when (eq exwm--selected-input-mode 'char-mode) (when (eq exwm--selected-input-mode 'char-mode)
(exwm-input--release-keyboard)))))) ;; Grab keyboard temporarily for char-mode.
(exwm-input--grab-keyboard))
(unwind-protect
(with-temp-buffer
;; Always show key strokes.
(let ((input-method-use-echo-area t))
(setq result (funcall im-func event))
;; This also works for portable character encoding.
(setq result
(encode-coding-string (concat result)
'compound-text-with-extensions))
(exwm-xim--make-request
(make-instance 'xim:commit-x-lookup-chars
:im-id (slot-value req 'im-id)
:ic-id (slot-value req 'ic-id)
:flag (logior xim:commit-flag:synchronous
xim:commit-flag:x-lookup-chars)
:length (length result)
:string result)
conn client-xwin)))
(when (eq exwm--selected-input-mode 'char-mode)
(exwm-input--release-keyboard))))
(xcb:flush conn)
(setf event nil
(slot-value req 'event) nil))))
(defun exwm-xim--make-request (req conn client-xwin) (defun exwm-xim--make-request (req conn client-xwin)
"Make an XIM request REQ via connection CONN. "Make an XIM request REQ via connection CONN.