Fix detection of modifier keys in Emacs events
* exwm-input.el (exwm-input--grab-global-prefix-keys) (exwm-input--fake-key): * exwm-xim.el (exwm-xim--handle-forward-event-request): X11 allows multiple combinations of KEYSYM-MODIFIERS to generate a same KEYSYM, thus the result of an Emacs event to KEYSYM-MODIFIERS conversion is not necessarily unique. Previously the result of `xcb:keysyms:event->keysym' is misused as the modifiers returned is actually the ones should be consumed.
This commit is contained in:
parent
2c0dcc46cd
commit
37098a4009
2 changed files with 25 additions and 22 deletions
|
@ -488,23 +488,26 @@ ARGS are additional arguments to CALLBACK."
|
||||||
:key nil
|
:key nil
|
||||||
:pointer-mode xcb:GrabMode:Async
|
:pointer-mode xcb:GrabMode:Async
|
||||||
:keyboard-mode xcb:GrabMode:Async))
|
:keyboard-mode xcb:GrabMode:Async))
|
||||||
keysym keycode)
|
keysyms keycode alt-modifier)
|
||||||
(dolist (k exwm-input--global-prefix-keys)
|
(dolist (k exwm-input--global-prefix-keys)
|
||||||
(setq keysym (xcb:keysyms:event->keysym exwm--connection k)
|
(setq keysyms (xcb:keysyms:event->keysyms exwm--connection k)
|
||||||
keycode (xcb:keysyms:keysym->keycode exwm--connection
|
keycode (xcb:keysyms:keysym->keycode exwm--connection
|
||||||
(car keysym)))
|
(caar keysyms)))
|
||||||
(exwm--log "Grabbing key=%s (keysym=%s keycode=%s)"
|
(exwm--log "Grabbing key=%s (keysyms=%s keycode=%s)"
|
||||||
(single-key-description k) keysym keycode)
|
(single-key-description k) keysyms keycode)
|
||||||
|
(dolist (keysym keysyms)
|
||||||
(setf (slot-value req 'modifiers) (cdr keysym)
|
(setf (slot-value req 'modifiers) (cdr keysym)
|
||||||
(slot-value req 'key) keycode)
|
(slot-value req 'key) keycode)
|
||||||
|
;; Also grab this key with num-lock mask set.
|
||||||
|
(when (and (/= 0 xcb:keysyms:num-lock-mask)
|
||||||
|
(= 0 (logand (cdr keysym) xcb:keysyms:num-lock-mask)))
|
||||||
|
(setf alt-modifier (logior (cdr keysym) xcb:keysyms:num-lock-mask)))
|
||||||
(dolist (xwin xwins)
|
(dolist (xwin xwins)
|
||||||
(setf (slot-value req 'grab-window) xwin)
|
(setf (slot-value req 'grab-window) xwin)
|
||||||
(xcb:+request exwm--connection req)
|
(xcb:+request exwm--connection req)
|
||||||
;; Also grab this key with num-lock mask set.
|
(when alt-modifier
|
||||||
(when (/= 0 xcb:keysyms:num-lock-mask)
|
(setf (slot-value req 'modifiers) alt-modifier)
|
||||||
(setf (slot-value req 'modifiers)
|
(xcb:+request exwm--connection req)))))
|
||||||
(logior (cdr keysym) xcb:keysyms:num-lock-mask))
|
|
||||||
(xcb:+request exwm--connection req))))
|
|
||||||
(xcb:flush exwm--connection)))
|
(xcb:flush exwm--connection)))
|
||||||
|
|
||||||
(defun exwm-input--set-key (key command)
|
(defun exwm-input--set-key (key command)
|
||||||
|
@ -817,12 +820,12 @@ button event."
|
||||||
|
|
||||||
(defun exwm-input--fake-key (event)
|
(defun exwm-input--fake-key (event)
|
||||||
"Fake a key event equivalent to Emacs event EVENT."
|
"Fake a key event equivalent to Emacs event EVENT."
|
||||||
(let* ((keysym (xcb:keysyms:event->keysym exwm--connection event))
|
(let* ((keysyms (xcb:keysyms:event->keysyms exwm--connection event))
|
||||||
keycode id)
|
keycode id)
|
||||||
(when (= 0 (car keysym))
|
(when (= 0 (caar keysyms))
|
||||||
(user-error "[EXWM] Invalid key: %s" (single-key-description event)))
|
(user-error "[EXWM] Invalid key: %s" (single-key-description event)))
|
||||||
(setq keycode (xcb:keysyms:keysym->keycode exwm--connection
|
(setq keycode (xcb:keysyms:keysym->keycode exwm--connection
|
||||||
(car keysym)))
|
(caar keysyms)))
|
||||||
(when (/= 0 keycode)
|
(when (/= 0 keycode)
|
||||||
(setq id (exwm--buffer->id (window-buffer (selected-window))))
|
(setq id (exwm--buffer->id (window-buffer (selected-window))))
|
||||||
(exwm--log "id=#x%x event=%s keycode" id event keycode)
|
(exwm--log "id=#x%x event=%s keycode" id event keycode)
|
||||||
|
@ -839,7 +842,7 @@ button event."
|
||||||
:child 0
|
:child 0
|
||||||
:root-x 0 :root-y 0
|
:root-x 0 :root-y 0
|
||||||
:event-x 0 :event-y 0
|
:event-x 0 :event-y 0
|
||||||
:state (cdr keysym)
|
:state (cdar keysyms)
|
||||||
:same-screen 1)
|
:same-screen 1)
|
||||||
exwm--connection)))))
|
exwm--connection)))))
|
||||||
(xcb:flush exwm--connection)))
|
(xcb:flush exwm--connection)))
|
||||||
|
|
|
@ -530,7 +530,7 @@ The actual XIM request is in client message data or a property."
|
||||||
(defun exwm-xim--handle-forward-event-request (req lsb conn client-xwin)
|
(defun exwm-xim--handle-forward-event-request (req lsb conn client-xwin)
|
||||||
(let ((im-func (with-current-buffer (window-buffer)
|
(let ((im-func (with-current-buffer (window-buffer)
|
||||||
input-method-function))
|
input-method-function))
|
||||||
key-event keysym event result)
|
key-event keysym keysyms event result)
|
||||||
;; Note: The flag slot is ignored.
|
;; Note: The flag slot is ignored.
|
||||||
;; Do conversion in client's byte-order.
|
;; Do conversion in client's byte-order.
|
||||||
(let ((xcb:lsb lsb))
|
(let ((xcb:lsb lsb))
|
||||||
|
@ -564,11 +564,11 @@ The actual XIM request is in client message data or a property."
|
||||||
req
|
req
|
||||||
(if raw-event
|
(if raw-event
|
||||||
(setq event raw-event)
|
(setq event raw-event)
|
||||||
(setq keysym (xcb:keysyms:event->keysym exwm-xim--conn event))
|
(setq keysyms (xcb:keysyms:event->keysyms exwm-xim--conn event))
|
||||||
(with-slots (detail state) key-event
|
(with-slots (detail state) key-event
|
||||||
(setf detail (xcb:keysyms:keysym->keycode exwm-xim--conn
|
(setf detail (xcb:keysyms:keysym->keycode exwm-xim--conn
|
||||||
(car keysym))
|
(caar keysyms))
|
||||||
state (cdr keysym)))
|
state (cdar keysyms)))
|
||||||
(setq event (let ((xcb:lsb lsb))
|
(setq event (let ((xcb:lsb lsb))
|
||||||
(xcb:marshal key-event conn))))
|
(xcb:marshal key-event conn))))
|
||||||
(when event
|
(when event
|
||||||
|
|
Loading…
Reference in a new issue