From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Maze Newsgroups: gmane.emacs.bugs Subject: bug#55094: 27.2; XELB under EXWM stops processing all keyboard events Date: Mon, 25 Apr 2022 01:16:49 +0800 Message-ID: <20220424171649.fgms4eqcyedzbieu@ubik.pkbd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36616"; mail-complaints-to="usenet@ciao.gmane.io" To: 55094@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Apr 24 19:35:22 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nig8n-0009MU-QX for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 24 Apr 2022 19:35:22 +0200 Original-Received: from localhost ([::1]:51182 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nig8m-00009S-Fm for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 24 Apr 2022 13:35:20 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44262) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nig8V-00008v-AK for bug-gnu-emacs@gnu.org; Sun, 24 Apr 2022 13:35:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:37963) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nig8U-0007Pp-Rv for bug-gnu-emacs@gnu.org; Sun, 24 Apr 2022 13:35:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nig8U-0004JO-KY for bug-gnu-emacs@gnu.org; Sun, 24 Apr 2022 13:35:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Maze Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 24 Apr 2022 17:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 55094 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.165082169316550 (code B ref -1); Sun, 24 Apr 2022 17:35:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 24 Apr 2022 17:34:53 +0000 Original-Received: from localhost ([127.0.0.1]:60093 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nig8J-0004Ir-PK for submit@debbugs.gnu.org; Sun, 24 Apr 2022 13:34:53 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:56160) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nifrB-0003s6-MD for submit@debbugs.gnu.org; Sun, 24 Apr 2022 13:17:10 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:40302) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nifrB-0004nM-I4 for bug-gnu-emacs@gnu.org; Sun, 24 Apr 2022 13:17:09 -0400 Original-Received: from mx1.polytechnique.org ([129.104.30.34]:49065) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nifr7-0004uA-48 for bug-gnu-emacs@gnu.org; Sun, 24 Apr 2022 13:17:08 -0400 Original-Received: from ubik (unknown [199.167.29.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ssl.polytechnique.org (Postfix) with ESMTPSA id 85D9856468C for ; Sun, 24 Apr 2022 19:16:58 +0200 (CEST) Original-Received: from maze by ubik with local (Exim 4.95) (envelope-from ) id 1nifqr-0006M5-PK for bug-gnu-emacs@gnu.org; Mon, 25 Apr 2022 01:16:49 +0800 X-PGP-Key: http://data.pkbd.org/pgp/maze/pubkey.asc Content-Disposition: inline X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Sun Apr 24 19:16:59 2022 +0200 (CEST)) Received-SPF: pass client-ip=129.104.30.34; envelope-from=SRS0=Pst4=VC=ubik.pkbd.org=maze@bounces.m4x.org; helo=mx1.polytechnique.org X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 24 Apr 2022 13:34:50 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:230581 Archived-At: =0D =0D Sorry if this is not be the right place to report: this is a bug of=0D GNU ELPA package XELB running under EXWM, and not a bug of vanilla=0D emacs. However it seems the official place to report EXWM is on Github,=0D and, unless I missed something, it won't let me report a bug there=0D unless I create a github account, which I won't.=0D =0D Description: after hitting a key from the number row, EXWM acting as the=0D X Window Manager stops processing all keyboard input. Emacs and=0D all other graphical programs lose keyboard input. For me this happens=0D always after hitting any key from the numbers row of my=0D keyboard. Specifics may very possibly vary for other users but my=0D informed guess is that the risk is existing for all keyboard=0D configurations, as I will try to explain.=0D =0D Cause: a backtrace is generated showing that an array of xkb keytypes=0D was referenced out of its range in the method xcb:keysyms:keycode->keysym.= =0D I included this backtrace at the end of this message.=0D =0D This situation develops for the following reason:=0D When initializing EXWM, XELB creates a keyboard representation including=0D 2 arrays for keysyms and keytypes. After I hit a first key and start using = the=0D WM, XELB processes an XkbNewKeyBoardNotify event. XELB reacts to this=0D event by creating a new keysyms array without creating a new keytypes=0D array. Because the original keyboard had 28 keytypes but the new=0D keyboard has 29 keytypes in Xkb, and since my number row keys get associate= d=0D to the highest index keytype of the new keyboard, this causes the legacy=0D keytypes array to be accessed out of range by one index after I hit one=0D of the number row keys.=0D =0D Solution: I propose a patch. I'm not sure it's absolutely the best thing=0D to do but it is tested on my configuration and I think it probably=0D should not cause breaks for other users: calling the method =0D xcb:keysyms:-update-keytypes with correct parameters is in effect=0D retrieving information from Xkb and putting XELB in sync. My guess =0D is that the logic which drives this condition of=0D xcb:keysyms:-update-keycodes to be called alone without=0D calling xcb:keysyms:-update-keytype is not sanely selecting only=0D cases where it would be a good idea to skip the call... At this =0D stage of my understanding, calling both methods has to be safe in all =0D cases, and solves the severe crash of the WM that I experience. =0D =0D * in method xcb:keysyms:-on-NewKeyboardNotify, update keytypes of =0D new keyboard in order to prevent the WM from crashing when =0D processing keycodes=0D =0D diff --git a/xcb-keysyms.el b/xcb-keysyms.el=0D index af4f97b..2b7f89f 100644=0D --- a/xcb-keysyms.el=0D +++ b/xcb-keysyms.el=0D @@ -161,6 +161,7 @@ This method must be called before using any other metho= d in this module."=0D (setq device (xcb:-get-extra-plist obj 'keysyms deviceID))=0D (when (and device=0D (not (slot-value device 'updated)))=0D + (xcb:keysyms:-update-keytypes obj deviceID)=0D (xcb:keysyms:-update-keycodes obj deviceID)=0D (when (=3D deviceID device-id)=0D (setq updated t)=0D =0D Below is the backtrace that I obtained when I hit a key from the numbers=0D row while EXWM is managing X windows:=0D =0D window-list xcb-debug:buffer t ...))) (while --dolist-tail-- (let (...)=0D (if ... ...) (setq --dolist-tail-- ...)))) (save-excursion (goto-char=0D (point-max)) (let ((standard-output ...)) (backtrace))) (let=0D ((--dolist-tail-- windows-eob)) (while --dolist-tail-- (let (...)=0D (set-window-point w ...) (setq --dolist-tail-- ...)))))))(error=0D (args-out-of-range [#=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #] 28))=0D aref([# # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D # # #=0D #] 28)=0D (setq keytype (aref (slot-value object 'keytypes) (elt (slot-value=0D keycode 'kt-index) group)))=0D (catch 'return (if (<=3D (slot-value object 'min-keycode) keycode=0D (slot-value object 'max-keycode)) nil (throw 'return '(0 . 0)))=0D (setq keycode (aref (slot-value object 'keycodes) (- keycode=0D (slot-value object 'min-keycode))) group-info (slot-value keycode=0D 'groupInfo) group-number (logand group-info 15)) (if (=3D=0D group-number 0) (progn (throw 'return '(0 . 0)))) (setq group (if=0D (null modifiers) 0 (logand (lsh modifiers -13) 3))) (if (>=3D group=0D group-number) (progn (let* ((val (logand group-info 192))) (cond=0D ((eq val 'xcb:xkb:GroupsWrap:RedirectIntoRange) (setq group=0D (logand 255 ...)) (if (>=3D group group-number) (progn ...))) ((eq=0D val 'xcb:xkb:GroupsWrap:ClampIntoRange) (setq group (1-=0D group-number))) (t (setq group (% group group-number))))))) (setq=0D index (* group (slot-value keycode 'width))) (progn (message=0D "KEYSTROKE keysym: %s kt-index: %s" (slot-value keycode 'syms)=0D (slot-value keycode 'kt-index)) (let* ((object keycode)) (message=0D "KEYSTROKE keysym: %s kt-index: %s" (slot-value object 'syms)=0D (slot-value object 'kt-index))) (message "number of keysyms: %s"=0D (length (slot-value object 'keycodes))) (message "number of=0D keytypes: %s" (length (slot-value object 'keytypes))) (let*=0D ((--cl-vec-- (slot-value object 'keycodes)) (--cl-idx-- -1) (code=0D nil)) (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length=0D --cl-vec--)) (setq code (aref --cl-vec-- --cl-idx--)) (if code=0D (progn (let* (...) (if ... ...))))) nil)) (setq keytype (aref=0D (slot-value object 'keytypes) (elt (slot-value keycode 'kt-index)=0D group))) (let* ((object keytype)) (if (null modifiers) (delq nil=0D (mapcar #'(lambda (entry) (if ... ...)) (slot-value object 'map)))=0D (catch 'break (let ((--dolist-tail-- (slot-value object ...)))=0D (while --dolist-tail-- (let (...) (let* ... ...) (setq=0D --dolist-tail-- ...))))) (cons (elt (slot-value keycode 'syms)=0D index) (logand (slot-value object 'mods-mask) (lognot=0D preserve))))))=0D (let* ((object (xcb:keysyms:-get-current-device obj))) (catch=0D 'return (if (<=3D (slot-value object 'min-keycode) keycode=0D (slot-value object 'max-keycode)) nil (throw 'return '(0 . 0)))=0D (setq keycode (aref (slot-value object 'keycodes) (- keycode=0D (slot-value object 'min-keycode))) group-info (slot-value=0D keycode 'groupInfo) group-number (logand group-info 15)) (if (=3D=0D group-number 0) (progn (throw 'return '(0 . 0)))) (setq group=0D (if (null modifiers) 0 (logand (lsh modifiers -13) 3))) (if (>=3D=0D group group-number) (progn (let* ((val (logand group-info 192)))=0D (cond ((eq val ...) (setq group ...) (if ... ...)) ((eq val ...)=0D (setq group ...)) (t (setq group ...)))))) (setq index (* group=0D (slot-value keycode 'width))) (progn (message "KEYSTROKE keysym:=0D %s kt-index: %s" (slot-value keycode 'syms) (slot-value keycode=0D 'kt-index)) (let* ((object keycode)) (message "KEYSTROKE keysym:=0D %s kt-index: %s" (slot-value object 'syms) (slot-value object=0D 'kt-index))) (message "number of keysyms: %s" (length=0D (slot-value object 'keycodes))) (message "number of keytypes:=0D %s" (length (slot-value object 'keytypes))) (let* ((--cl-vec--=0D (slot-value object 'keycodes)) (--cl-idx-- -1) (code nil))=0D (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length --cl-vec--))=0D (setq code (aref --cl-vec-- --cl-idx--)) (if code (progn (let*=0D ... ...)))) nil)) (setq keytype (aref (slot-value object=0D 'keytypes) (elt (slot-value keycode 'kt-index) group))) (let*=0D ((object keytype)) (if (null modifiers) (delq nil (mapcar=0D #'(lambda ... ...) (slot-value object 'map))) (catch 'break (let=0D ((--dolist-tail-- ...)) (while --dolist-tail-- (let=0D ... ... ...)))) (cons (elt (slot-value keycode 'syms) index)=0D (logand (slot-value object 'mods-mask) (lognot preserve)))))))=0D (let ((preserve 0) group group-info group-number index=0D keytype) (let* ((object (xcb:keysyms:-get-current-device=0D obj))) (catch 'return (if (<=3D (slot-value object 'min-keycode)= =0D keycode (slot-value object 'max-keycode)) nil (throw 'return=0D '(0 . 0))) (setq keycode (aref (slot-value object 'keycodes)=0D (- keycode (slot-value object 'min-keycode))) group-info=0D (slot-value keycode 'groupInfo) group-number (logand=0D group-info 15)) (if (=3D group-number 0) (progn (throw 'return=0D '(0 . 0)))) (setq group (if (null modifiers) 0 (logand (lsh=0D modifiers -13) 3))) (if (>=3D group group-number) (progn (let*=0D ((val ...)) (cond (... ... ...) (... ...) (t ...))))) (setq=0D index (* group (slot-value keycode 'width))) (progn (message=0D "KEYSTROKE keysym: %s kt-index: %s" (slot-value keycode 'syms)=0D (slot-value keycode 'kt-index)) (let* ((object keycode))=0D (message "KEYSTROKE keysym: %s kt-index: %s" (slot-value=0D object 'syms) (slot-value object 'kt-index))) (message "number=0D of keysyms: %s" (length (slot-value object 'keycodes)))=0D (message "number of keytypes: %s" (length (slot-value object=0D 'keytypes))) (let* ((--cl-vec-- (slot-value object ...))=0D (--cl-idx-- -1) (code nil)) (while (< (setq --cl-idx-- ...)=0D (length --cl-vec--)) (setq code (aref --cl-vec-- --cl-idx--))=0D (if code (progn ...))) nil)) (setq keytype (aref (slot-value=0D object 'keytypes) (elt (slot-value keycode 'kt-index) group)))=0D (let* ((object keytype)) (if (null modifiers) (delq nil=0D (mapcar #'... (slot-value object ...))) (catch 'break (let=0D (...) (while --dolist-tail-- ...))) (cons (elt (slot-value=0D keycode ...) index) (logand (slot-value object ...) (lognot=0D preserve))))))))=0D (progn (let ((preserve 0) group group-info group-number=0D index keytype) (let* ((object=0D (xcb:keysyms:-get-current-device obj))) (catch 'return (if=0D (<=3D (slot-value object 'min-keycode) keycode (slot-value=0D object 'max-keycode)) nil (throw 'return '(0 . 0))) (setq=0D keycode (aref (slot-value object 'keycodes) (- keycode=0D (slot-value object ...))) group-info (slot-value keycode=0D 'groupInfo) group-number (logand group-info 15)) (if (=3D=0D group-number 0) (progn (throw 'return '...))) (setq group=0D (if (null modifiers) 0 (logand (lsh modifiers -13) 3))) (if=0D (>=3D group group-number) (progn (let* (...) (cond=0D ... ... ...)))) (setq index (* group (slot-value keycode=0D 'width))) (progn (message "KEYSTROKE keysym: %s kt-index:=0D %s" (slot-value keycode 'syms) (slot-value keycode=0D 'kt-index)) (let* ((object keycode)) (message "KEYSTROKE=0D keysym: %s kt-index: %s" (slot-value object ...) (slot-value=0D object ...))) (message "number of keysyms: %s" (length=0D (slot-value object ...))) (message "number of keytypes: %s"=0D (length (slot-value object ...))) (let* ((--cl-vec-- ...)=0D (--cl-idx-- -1) (code nil)) (while (< ... ...) (setq code=0D ...) (if code ...)) nil)) (setq keytype (aref (slot-value=0D object 'keytypes) (elt (slot-value keycode ...) group)))=0D (let* ((object keytype)) (if (null modifiers) (delq nil=0D (mapcar ... ...)) (catch 'break (let ... ...)) (cons (elt=0D ... index) (logand ... ...))))))))=0D (closure (t) (obj keycode modifiers) "Convert KEYCODE to=0D keysym or get possible modifier..." (progn (let ((preserve=0D 0) group group-info group-number index keytype) (let*=0D ((object (xcb:keysyms:-get-current-device obj))) (catch=0D 'return (if (<=3D ... keycode ...) nil (throw ... ...))=0D (setq keycode (aref ... ...) group-info (slot-value=0D keycode ...) group-number (logand group-info 15)) (if (=3D=0D group-number 0) (progn ...)) (setq group (if ... 0 ...))=0D (if (>=3D group group-number) (progn ...)) (setq index (*=0D group ...)) (progn (message "KEYSTROKE keysym: %s=0D kt-index: %s" ... ...) (let* ... ...) (message "number of=0D keysyms: %s" ...) (message "number of keytypes: %s" ...)=0D (let* ... ... nil)) (setq keytype (aref ... ...)) (let*=0D (...) (if ... ... ... ...)))))))(# 20 16)=0D apply((closure (t) (obj keycode modifiers) "Convert=0D KEYCODE to keysym or get possible modifier..." (progn=0D (let ((preserve 0) group group-info group-number index=0D keytype) (let* ((object (xcb:keysyms:-get-current-device=0D obj))) (catch 'return (if (<=3D ... keycode ...) nil=0D (throw ... ...)) (setq keycode (aref ... ...) group-info=0D (slot-value keycode ...) group-number (logand group-info=0D 15)) (if (=3D group-number 0) (progn ...)) (setq group (if= =0D ... 0 ...)) (if (>=3D group group-number) (progn ...))=0D (setq index (* group ...)) (progn (message "KEYSTROKE=0D keysym: %s kt-index: %s" ... ...) (let* ... ...)=0D (message "number of keysyms: %s" ...) (message "number=0D of keytypes: %s" ...) (let* ... ... nil)) (setq keytype=0D (aref ... ...)) (let* (...) (if ... ... ... ...)))))))=0D # (20 16))=0D xcb:keysyms:keycode->keysym(# 20 16)=0D