mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-30 16:07:59 +01:00
Fix auto commit issue with input methods
* exwm-xim.el (exwm-xim--handle-forward-event-request): Factored out from `exwm-xim--on-request' to make auto commit work. With input methods providing candidates the first candidate can be implicitly selected if no further matching is possible. The last event would be stored in `unread-command-events' (at least for `quail-input-method') and should be reused by the input method. (exwm-xim--on-request): Use it.
This commit is contained in:
parent
f70bdb5868
commit
fe2336a11e
1 changed files with 74 additions and 64 deletions
138
exwm-xim.el
138
exwm-xim.el
|
@ -490,70 +490,8 @@ The actual XIM request is in client message data or a property."
|
||||||
(exwm--log "FORWARD-EVENT")
|
(exwm--log "FORWARD-EVENT")
|
||||||
(setq req (make-instance 'xim:forward-event))
|
(setq req (make-instance 'xim:forward-event))
|
||||||
(xcb:unmarshal req data)
|
(xcb:unmarshal req data)
|
||||||
(let ((im-func (with-current-buffer (window-buffer)
|
(exwm-xim--handle-forward-event-request req xim:lsb conn
|
||||||
input-method-function))
|
client-xwin))
|
||||||
key-event keysym event result)
|
|
||||||
;; Note: The flag slot is ignored.
|
|
||||||
;; Do conversion in client's byte-order.
|
|
||||||
(let ((xcb:lsb xim:lsb))
|
|
||||||
(setq key-event (make-instance 'xcb:KeyPress))
|
|
||||||
(xcb:unmarshal key-event (slot-value req 'event)))
|
|
||||||
(with-slots (detail state) key-event
|
|
||||||
(setq keysym (xcb:keysyms:keycode->keysym exwm-xim--conn detail
|
|
||||||
state))
|
|
||||||
(when (/= (car keysym) 0)
|
|
||||||
(setq event (xcb:keysyms:keysym->event
|
|
||||||
exwm-xim--conn
|
|
||||||
(car keysym)
|
|
||||||
(logand state (lognot (cdr keysym)))))))
|
|
||||||
(if exwm-xim--event-pending
|
|
||||||
;; In case any event reaches here, it should be forwarded
|
|
||||||
;; to Emacs.
|
|
||||||
(when event
|
|
||||||
(setq unread-command-events
|
|
||||||
(append unread-command-events (list event))))
|
|
||||||
(setq exwm-xim--event-pending t)
|
|
||||||
(if (or (not im-func)
|
|
||||||
;; `list' is the default method.
|
|
||||||
(eq im-func #'list)
|
|
||||||
(not event)
|
|
||||||
;; Select only printable keys.
|
|
||||||
(not (integerp event)) (> #x20 event) (< #x7e event))
|
|
||||||
;; Either there is no active input method, or invalid key
|
|
||||||
;; is detected.
|
|
||||||
(with-slots (im-id ic-id serial-number event) req
|
|
||||||
(push (make-instance 'xim:forward-event
|
|
||||||
:im-id im-id
|
|
||||||
:ic-id ic-id
|
|
||||||
:flag xim:commit-flag:synchronous
|
|
||||||
:serial-number serial-number
|
|
||||||
:event event)
|
|
||||||
replies))
|
|
||||||
(when (eq exwm--selected-input-mode 'char-mode)
|
|
||||||
;; 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))))
|
|
||||||
(when (eq exwm--selected-input-mode 'char-mode)
|
|
||||||
(exwm-input--release-keyboard)))
|
|
||||||
;; This also works for portable character encoding.
|
|
||||||
(setq result
|
|
||||||
(encode-coding-string (concat result)
|
|
||||||
'compound-text-with-extensions))
|
|
||||||
(message "")
|
|
||||||
(push
|
|
||||||
(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)
|
|
||||||
replies))
|
|
||||||
(setq exwm-xim--event-pending nil))))
|
|
||||||
((= opcode xim:opcode:sync)
|
((= opcode xim:opcode:sync)
|
||||||
(exwm--log "SYNC")
|
(exwm--log "SYNC")
|
||||||
(setq req (make-instance 'xim:sync))
|
(setq req (make-instance 'xim:sync))
|
||||||
|
@ -591,6 +529,78 @@ The actual XIM request is in client message data or a property."
|
||||||
replies)
|
replies)
|
||||||
(xcb:flush conn))))
|
(xcb:flush conn))))
|
||||||
|
|
||||||
|
(defun exwm-xim--handle-forward-event-request (req lsb conn client-xwin)
|
||||||
|
(let ((im-func (with-current-buffer (window-buffer)
|
||||||
|
input-method-function))
|
||||||
|
key-event keysym event result)
|
||||||
|
;; Note: The flag slot is ignored.
|
||||||
|
;; Do conversion in client's byte-order.
|
||||||
|
(let ((xcb:lsb lsb))
|
||||||
|
(setq key-event (make-instance 'xcb:KeyPress))
|
||||||
|
(xcb:unmarshal key-event (slot-value req 'event)))
|
||||||
|
(with-slots (detail state) key-event
|
||||||
|
(setq keysym (xcb:keysyms:keycode->keysym exwm-xim--conn detail
|
||||||
|
state))
|
||||||
|
(when (/= (car keysym) 0)
|
||||||
|
(setq event (xcb:keysyms:keysym->event
|
||||||
|
exwm-xim--conn
|
||||||
|
(car keysym)
|
||||||
|
(logand state (lognot (cdr keysym)))))))
|
||||||
|
(if exwm-xim--event-pending
|
||||||
|
;; In case any event reaches here, it should be forwarded
|
||||||
|
;; to Emacs.
|
||||||
|
(when event
|
||||||
|
(setq unread-command-events
|
||||||
|
(append unread-command-events (list event))))
|
||||||
|
(setq exwm-xim--event-pending t)
|
||||||
|
(if (or (not im-func)
|
||||||
|
;; `list' is the default method.
|
||||||
|
(eq im-func #'list)
|
||||||
|
(not event)
|
||||||
|
;; Select only printable keys.
|
||||||
|
(not (integerp event)) (> #x20 event) (< #x7e event))
|
||||||
|
;; Either there is no active input method, or invalid key
|
||||||
|
;; is detected.
|
||||||
|
(with-slots (im-id ic-id serial-number event) req
|
||||||
|
(exwm-xim--make-request
|
||||||
|
(make-instance 'xim:forward-event
|
||||||
|
:im-id im-id
|
||||||
|
:ic-id ic-id
|
||||||
|
:flag xim:commit-flag:synchronous
|
||||||
|
:serial-number serial-number
|
||||||
|
:event event)
|
||||||
|
conn client-xwin)
|
||||||
|
(xcb:flush conn))
|
||||||
|
(when (eq exwm--selected-input-mode 'char-mode)
|
||||||
|
;; 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))
|
||||||
|
(while (or event unread-command-events)
|
||||||
|
(unless event
|
||||||
|
(setq event (pop unread-command-events)))
|
||||||
|
(setq result (funcall im-func event)
|
||||||
|
event nil)
|
||||||
|
;; 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))))
|
||||||
|
(when (eq exwm--selected-input-mode 'char-mode)
|
||||||
|
(exwm-input--release-keyboard))))
|
||||||
|
(setq exwm-xim--event-pending 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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue