--- Begin Message ---
Subject: |
27.2; XELB under EXWM stops processing all keyboard events |
Date: |
Mon, 25 Apr 2022 01:16:49 +0800 |
Sorry if this is not be the right place to report: this is a bug of
GNU ELPA package XELB running under EXWM, and not a bug of vanilla
emacs. However it seems the official place to report EXWM is on Github,
and, unless I missed something, it won't let me report a bug there
unless I create a github account, which I won't.
Description: after hitting a key from the number row, EXWM acting as the
X Window Manager stops processing all keyboard input. Emacs and
all other graphical programs lose keyboard input. For me this happens
always after hitting any key from the numbers row of my
keyboard. Specifics may very possibly vary for other users but my
informed guess is that the risk is existing for all keyboard
configurations, as I will try to explain.
Cause: a backtrace is generated showing that an array of xkb keytypes
was referenced out of its range in the method xcb:keysyms:keycode->keysym.
I included this backtrace at the end of this message.
This situation develops for the following reason:
When initializing EXWM, XELB creates a keyboard representation including
2 arrays for keysyms and keytypes. After I hit a first key and start using the
WM, XELB processes an XkbNewKeyBoardNotify event. XELB reacts to this
event by creating a new keysyms array without creating a new keytypes
array. Because the original keyboard had 28 keytypes but the new
keyboard has 29 keytypes in Xkb, and since my number row keys get associated
to the highest index keytype of the new keyboard, this causes the legacy
keytypes array to be accessed out of range by one index after I hit one
of the number row keys.
Solution: I propose a patch. I'm not sure it's absolutely the best thing
to do but it is tested on my configuration and I think it probably
should not cause breaks for other users: calling the method
xcb:keysyms:-update-keytypes with correct parameters is in effect
retrieving information from Xkb and putting XELB in sync. My guess
is that the logic which drives this condition of
xcb:keysyms:-update-keycodes to be called alone without
calling xcb:keysyms:-update-keytype is not sanely selecting only
cases where it would be a good idea to skip the call... At this
stage of my understanding, calling both methods has to be safe in all
cases, and solves the severe crash of the WM that I experience.
* in method xcb:keysyms:-on-NewKeyboardNotify, update keytypes of
new keyboard in order to prevent the WM from crashing when
processing keycodes
diff --git a/xcb-keysyms.el b/xcb-keysyms.el
index af4f97b..2b7f89f 100644
--- a/xcb-keysyms.el
+++ b/xcb-keysyms.el
@@ -161,6 +161,7 @@ This method must be called before using any other method in
this module."
(setq device (xcb:-get-extra-plist obj 'keysyms deviceID))
(when (and device
(not (slot-value device 'updated)))
+ (xcb:keysyms:-update-keytypes obj deviceID)
(xcb:keysyms:-update-keycodes obj deviceID)
(when (= deviceID device-id)
(setq updated t)
Below is the backtrace that I obtained when I hit a key from the numbers
row while EXWM is managing X windows:
window-list xcb-debug:buffer t ...))) (while --dolist-tail-- (let (...)
(if ... ...) (setq --dolist-tail-- ...)))) (save-excursion (goto-char
(point-max)) (let ((standard-output ...)) (backtrace))) (let
((--dolist-tail-- windows-eob)) (while --dolist-tail-- (let (...)
(set-window-point w ...) (setq --dolist-tail-- ...)))))))(error
(args-out-of-range [#<xcb:xkb:KeyType xcb:xkb:KeyType-d97a0c>
#<xcb:xkb:KeyType xcb:xkb:KeyType-d97a20> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c84518> #<xcb:xkb:KeyType xcb:xkb:KeyType-ca101c>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c4e190> #<xcb:xkb:KeyType
xcb:xkb:KeyType-cbc07c> #<xcb:xkb:KeyType xcb:xkb:KeyType-c4e150>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c8d79c> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c96104> #<xcb:xkb:KeyType xcb:xkb:KeyType-c9207c>
#<xcb:xkb:KeyType xcb:xkb:KeyType-d0c5b8> #<xcb:xkb:KeyType
xcb:xkb:KeyType-d9620c> #<xcb:xkb:KeyType xcb:xkb:KeyType-d96220>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c8d774> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c14764> #<xcb:xkb:KeyType xcb:xkb:KeyType-be9f50>
#<xcb:xkb:KeyType xcb:xkb:KeyType-ce2990> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c149b0> #<xcb:xkb:KeyType xcb:xkb:KeyType-c142dc>
#<xcb:xkb:KeyType xcb:xkb:KeyType-cbbd98> #<xcb:xkb:KeyType
xcb:xkb:KeyType-d97430> #<xcb:xkb:KeyType xcb:xkb:KeyType-be8d74>
#<xcb:xkb:KeyType xcb:xkb:KeyType-be8e00> #<xcb:xkb:KeyType
xcb:xkb:KeyType-b9aa80> #<xcb:xkb:KeyType xcb:xkb:KeyType-c4e424>
#<xcb:xkb:KeyType xcb:xkb:KeyType-cde514> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c37118> #<xcb:xkb:KeyType xcb:xkb:KeyType-d11e10>] 28))
aref([#<xcb:xkb:KeyType xcb:xkb:KeyType-d97a0c> #<xcb:xkb:KeyType
xcb:xkb:KeyType-d97a20> #<xcb:xkb:KeyType xcb:xkb:KeyType-c84518>
#<xcb:xkb:KeyType xcb:xkb:KeyType-ca101c> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c4e190> #<xcb:xkb:KeyType xcb:xkb:KeyType-cbc07c>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c4e150> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c8d79c> #<xcb:xkb:KeyType xcb:xkb:KeyType-c96104>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c9207c> #<xcb:xkb:KeyType
xcb:xkb:KeyType-d0c5b8> #<xcb:xkb:KeyType xcb:xkb:KeyType-d9620c>
#<xcb:xkb:KeyType xcb:xkb:KeyType-d96220> #<xcb:xkb:KeyType
xcb:xkb:KeyType-c8d774> #<xcb:xkb:KeyType xcb:xkb:KeyType-c14764>
#<xcb:xkb:KeyType xcb:xkb:KeyType-be9f50> #<xcb:xkb:KeyType
xcb:xkb:KeyType-ce2990> #<xcb:xkb:KeyType xcb:xkb:KeyType-c149b0>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c142dc> #<xcb:xkb:KeyType
xcb:xkb:KeyType-cbbd98> #<xcb:xkb:KeyType xcb:xkb:KeyType-d97430>
#<xcb:xkb:KeyType xcb:xkb:KeyType-be8d74> #<xcb:xkb:KeyType
xcb:xkb:KeyType-be8e00> #<xcb:xkb:KeyType xcb:xkb:KeyType-b9aa80>
#<xcb:xkb:KeyType xcb:xkb:KeyType-c4e424> #<xcb:xkb:KeyType
xcb:xkb:KeyType-cde514> #<xcb:xkb:KeyType xcb:xkb:KeyType-c37118>
#<xcb:xkb:KeyType xcb:xkb:KeyType-d11e10>] 28)
(setq keytype (aref (slot-value object 'keytypes) (elt (slot-value
keycode 'kt-index) group)))
(catch 'return (if (<= (slot-value object 'min-keycode) keycode
(slot-value object 'max-keycode)) nil (throw 'return '(0 . 0)))
(setq keycode (aref (slot-value object 'keycodes) (- keycode
(slot-value object 'min-keycode))) group-info (slot-value keycode
'groupInfo) group-number (logand group-info 15)) (if (=
group-number 0) (progn (throw 'return '(0 . 0)))) (setq group (if
(null modifiers) 0 (logand (lsh modifiers -13) 3))) (if (>= group
group-number) (progn (let* ((val (logand group-info 192))) (cond
((eq val 'xcb:xkb:GroupsWrap:RedirectIntoRange) (setq group
(logand 255 ...)) (if (>= group group-number) (progn ...))) ((eq
val 'xcb:xkb:GroupsWrap:ClampIntoRange) (setq group (1-
group-number))) (t (setq group (% group group-number))))))) (setq
index (* group (slot-value keycode 'width))) (progn (message
"KEYSTROKE keysym: %s kt-index: %s" (slot-value keycode 'syms)
(slot-value keycode 'kt-index)) (let* ((object keycode)) (message
"KEYSTROKE keysym: %s kt-index: %s" (slot-value object 'syms)
(slot-value object 'kt-index))) (message "number of keysyms: %s"
(length (slot-value object 'keycodes))) (message "number of
keytypes: %s" (length (slot-value object 'keytypes))) (let*
((--cl-vec-- (slot-value object 'keycodes)) (--cl-idx-- -1) (code
nil)) (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length
--cl-vec--)) (setq code (aref --cl-vec-- --cl-idx--)) (if code
(progn (let* (...) (if ... ...))))) nil)) (setq keytype (aref
(slot-value object 'keytypes) (elt (slot-value keycode 'kt-index)
group))) (let* ((object keytype)) (if (null modifiers) (delq nil
(mapcar #'(lambda (entry) (if ... ...)) (slot-value object 'map)))
(catch 'break (let ((--dolist-tail-- (slot-value object ...)))
(while --dolist-tail-- (let (...) (let* ... ...) (setq
--dolist-tail-- ...))))) (cons (elt (slot-value keycode 'syms)
index) (logand (slot-value object 'mods-mask) (lognot
preserve))))))
(let* ((object (xcb:keysyms:-get-current-device obj))) (catch
'return (if (<= (slot-value object 'min-keycode) keycode
(slot-value object 'max-keycode)) nil (throw 'return '(0 . 0)))
(setq keycode (aref (slot-value object 'keycodes) (- keycode
(slot-value object 'min-keycode))) group-info (slot-value
keycode 'groupInfo) group-number (logand group-info 15)) (if (=
group-number 0) (progn (throw 'return '(0 . 0)))) (setq group
(if (null modifiers) 0 (logand (lsh modifiers -13) 3))) (if (>=
group group-number) (progn (let* ((val (logand group-info 192)))
(cond ((eq val ...) (setq group ...) (if ... ...)) ((eq val ...)
(setq group ...)) (t (setq group ...)))))) (setq index (* group
(slot-value keycode 'width))) (progn (message "KEYSTROKE keysym:
%s kt-index: %s" (slot-value keycode 'syms) (slot-value keycode
'kt-index)) (let* ((object keycode)) (message "KEYSTROKE keysym:
%s kt-index: %s" (slot-value object 'syms) (slot-value object
'kt-index))) (message "number of keysyms: %s" (length
(slot-value object 'keycodes))) (message "number of keytypes:
%s" (length (slot-value object 'keytypes))) (let* ((--cl-vec--
(slot-value object 'keycodes)) (--cl-idx-- -1) (code nil))
(while (< (setq --cl-idx-- (1+ --cl-idx--)) (length --cl-vec--))
(setq code (aref --cl-vec-- --cl-idx--)) (if code (progn (let*
... ...)))) nil)) (setq keytype (aref (slot-value object
'keytypes) (elt (slot-value keycode 'kt-index) group))) (let*
((object keytype)) (if (null modifiers) (delq nil (mapcar
#'(lambda ... ...) (slot-value object 'map))) (catch 'break (let
((--dolist-tail-- ...)) (while --dolist-tail-- (let
... ... ...)))) (cons (elt (slot-value keycode 'syms) index)
(logand (slot-value object 'mods-mask) (lognot preserve)))))))
(let ((preserve 0) group group-info group-number index
keytype) (let* ((object (xcb:keysyms:-get-current-device
obj))) (catch 'return (if (<= (slot-value object 'min-keycode)
keycode (slot-value object 'max-keycode)) nil (throw 'return
'(0 . 0))) (setq keycode (aref (slot-value object 'keycodes)
(- keycode (slot-value object 'min-keycode))) group-info
(slot-value keycode 'groupInfo) group-number (logand
group-info 15)) (if (= group-number 0) (progn (throw 'return
'(0 . 0)))) (setq group (if (null modifiers) 0 (logand (lsh
modifiers -13) 3))) (if (>= group group-number) (progn (let*
((val ...)) (cond (... ... ...) (... ...) (t ...))))) (setq
index (* group (slot-value keycode 'width))) (progn (message
"KEYSTROKE keysym: %s kt-index: %s" (slot-value keycode 'syms)
(slot-value keycode 'kt-index)) (let* ((object keycode))
(message "KEYSTROKE keysym: %s kt-index: %s" (slot-value
object 'syms) (slot-value object 'kt-index))) (message "number
of keysyms: %s" (length (slot-value object 'keycodes)))
(message "number of keytypes: %s" (length (slot-value object
'keytypes))) (let* ((--cl-vec-- (slot-value object ...))
(--cl-idx-- -1) (code nil)) (while (< (setq --cl-idx-- ...)
(length --cl-vec--)) (setq code (aref --cl-vec-- --cl-idx--))
(if code (progn ...))) nil)) (setq keytype (aref (slot-value
object 'keytypes) (elt (slot-value keycode 'kt-index) group)))
(let* ((object keytype)) (if (null modifiers) (delq nil
(mapcar #'... (slot-value object ...))) (catch 'break (let
(...) (while --dolist-tail-- ...))) (cons (elt (slot-value
keycode ...) index) (logand (slot-value object ...) (lognot
preserve))))))))
(progn (let ((preserve 0) group group-info group-number
index keytype) (let* ((object
(xcb:keysyms:-get-current-device obj))) (catch 'return (if
(<= (slot-value object 'min-keycode) keycode (slot-value
object 'max-keycode)) nil (throw 'return '(0 . 0))) (setq
keycode (aref (slot-value object 'keycodes) (- keycode
(slot-value object ...))) group-info (slot-value keycode
'groupInfo) group-number (logand group-info 15)) (if (=
group-number 0) (progn (throw 'return '...))) (setq group
(if (null modifiers) 0 (logand (lsh modifiers -13) 3))) (if
(>= group group-number) (progn (let* (...) (cond
... ... ...)))) (setq index (* group (slot-value keycode
'width))) (progn (message "KEYSTROKE keysym: %s kt-index:
%s" (slot-value keycode 'syms) (slot-value keycode
'kt-index)) (let* ((object keycode)) (message "KEYSTROKE
keysym: %s kt-index: %s" (slot-value object ...) (slot-value
object ...))) (message "number of keysyms: %s" (length
(slot-value object ...))) (message "number of keytypes: %s"
(length (slot-value object ...))) (let* ((--cl-vec-- ...)
(--cl-idx-- -1) (code nil)) (while (< ... ...) (setq code
...) (if code ...)) nil)) (setq keytype (aref (slot-value
object 'keytypes) (elt (slot-value keycode ...) group)))
(let* ((object keytype)) (if (null modifiers) (delq nil
(mapcar ... ...)) (catch 'break (let ... ...)) (cons (elt
... index) (logand ... ...))))))))
(closure (t) (obj keycode modifiers) "Convert KEYCODE to
keysym or get possible modifier..." (progn (let ((preserve
0) group group-info group-number index keytype) (let*
((object (xcb:keysyms:-get-current-device obj))) (catch
'return (if (<= ... keycode ...) nil (throw ... ...))
(setq keycode (aref ... ...) group-info (slot-value
keycode ...) group-number (logand group-info 15)) (if (=
group-number 0) (progn ...)) (setq group (if ... 0 ...))
(if (>= group group-number) (progn ...)) (setq index (*
group ...)) (progn (message "KEYSTROKE keysym: %s
kt-index: %s" ... ...) (let* ... ...) (message "number of
keysyms: %s" ...) (message "number of keytypes: %s" ...)
(let* ... ... nil)) (setq keytype (aref ... ...)) (let*
(...) (if ... ... ... ...)))))))(#<xcb:connection
xcb:connection-ca0fd0> 20 16)
apply((closure (t) (obj keycode modifiers) "Convert
KEYCODE to keysym or get possible modifier..." (progn
(let ((preserve 0) group group-info group-number index
keytype) (let* ((object (xcb:keysyms:-get-current-device
obj))) (catch 'return (if (<= ... keycode ...) nil
(throw ... ...)) (setq keycode (aref ... ...) group-info
(slot-value keycode ...) group-number (logand group-info
15)) (if (= group-number 0) (progn ...)) (setq group (if
... 0 ...)) (if (>= group group-number) (progn ...))
(setq index (* group ...)) (progn (message "KEYSTROKE
keysym: %s kt-index: %s" ... ...) (let* ... ...)
(message "number of keysyms: %s" ...) (message "number
of keytypes: %s" ...) (let* ... ... nil)) (setq keytype
(aref ... ...)) (let* (...) (if ... ... ... ...)))))))
#<xcb:connection xcb:connection-ca0fd0> (20 16))
xcb:keysyms:keycode->keysym(#<xcb:connection
xcb:connection-ca0fd0> 20 16)
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#55094: 27.2; XELB under EXWM stops processing all keyboard events |
Date: |
Mon, 25 Apr 2022 08:54:16 +0800 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.91 (gnu/linux) |
Maze <maze@pkbd.org> writes:
> Sorry if this is not be the right place to report: this is a bug of
> GNU ELPA package XELB running under EXWM, and not a bug of vanilla
> emacs. However it seems the official place to report EXWM is on Github,
> and, unless I missed something, it won't let me report a bug there
> unless I create a github account, which I won't.
This is definitely not the right place to report this bug, so I'm
closing it.
You might want to ask the EXWM maintainer directly, but he hasn't been
active for a while.
--- End Message ---