From debbugs-submit-bounces@debbugs.gnu.org Tue Nov 16 07:38:33 2021 Received: (at submit) by debbugs.gnu.org; 16 Nov 2021 12:38:33 +0000 Received: from localhost ([127.0.0.1]:57426 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mmxjI-0003Tn-F6 for submit@debbugs.gnu.org; Tue, 16 Nov 2021 07:38:32 -0500 Received: from lists.gnu.org ([209.51.188.17]:41552) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mmxjE-0003TX-EK for submit@debbugs.gnu.org; Tue, 16 Nov 2021 07:38:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:52382) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mmxjD-0004pO-Ug for bug-gnu-emacs@gnu.org; Tue, 16 Nov 2021 07:38:24 -0500 Received: from sonic309-20.consmr.mail.ne1.yahoo.com ([66.163.184.146]:39955) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mmxj7-000241-3M for bug-gnu-emacs@gnu.org; Tue, 16 Nov 2021 07:38:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637066293; bh=81K8U9Nni3V+qbY0lQHl55HvHuZUWiXZad1Uv2/lSiU=; h=From:To:Subject:Date:References:From:Subject:Reply-To; b=axPxWGzM6YZ+zz4SZs62YkjFWdeckns89xXjKVeqFjDkG+8h9hTNa63cQoDcGWu0AQYP7/Lj1H6721ogQ4Wt5dIcGzdUkKdLUgc/LA3bP6Lx74CGlJBHC40kPvhtyaU8NJtzsFW3ApU90szuaw0pIDmvZ1IZM2LJsCHexpOh0y8OyAwzeFb2i5Em/VWAHuga/oGk3jop7s0ro+mV1oJaNA4Qao+dhqK1Kts4gUlh7XkGqySnEOv8knFmIFMxoy+xDxeCXWEWr9NnYxFrPQhbETBaozH2hOwRGwYM3rzdv1L3b4Fu2BjgUhVIB+Yk/rfu9tz5skBLy+khfUo4VlWQvQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637066293; bh=pg5zEPbhOe8L1FkH2U2TU87KgCbZskQp/LyTaCFQX3Z=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=T/vqeBdTu44uvToxs3j6LnMRoX9E7YNiqFUE1rTZPNp3P57pRpBSJ/TmWzwXYzGkPiB9wlXlhb5sDP9iJ5LWxM3xOrlK14LewO1ivT3D8IzLV2kYpynsmqHHvxE8gOUtAjEdLI9VLQQ2CSiIw+b+Y84z2quVbf4a+7RrK+aJwV8gmLUaqoKP/LQeRa6/fKoESfW7mNL8k2FV5N470RbixdNa/FClnNMlHCWjwYhE2qNCjts7uY7z0gfR9Ly30GtxHj8Y3Ipadf36+7NY4Coie3xDedhfQ5tiBjBLYg3j50p6Bj99Jds/qQNH05gfqW25Cw2zTnXnBvB59OakCxa++w== X-YMail-OSG: Go6L6zwVM1mH8j6vuHxL6CTq0B_4t0KB9JM7yi4wBddO_I5qVblVgOSp63YIfOD _q8X37QnNAZRWnTZL1xtXV16mJN1Dgubp1kQT7OCGHizclQoWb2SUGPxMRpfR6g9j7pI3XeeHne0 QT6CPNeIqz5Z2YsTNNI_MxvBe188L0i3kP1yTEfylCsLdTQznhljmHPUDk3zGfP80jAyltiNrmln bIE6PzuVTqKgxXIrpMJLL_aLYBuX7E6h7Mx5Y8ZKQNkbUwq7poSZqIV4nnvS.ntgDa46wnQSnAAy cNMPlWevhMyyNwBHe7AenWLNJKbg.LAN.WRChr2MdAFIi4gb4cblMy4caEZOQVsKkmHNLlJKm.vB rUvElETyXFh22PVbDAQtQYJbfTv5zBtSHsvApWsfmHAqQgdvbEvga1WRoY7Ul1xlB2flSOL8Fcmz iITrV2eO3p.m7tK0PkZU01h6tlfp0OcCgaQP2s5zV8sC.N.oEgQ15juDjmSzZTVF7FZu9YyiAOm5 AoH91Eqkod_wEeGgCkL0KQWEtFq_f.dV54G3fGPd0E28hmluJ6c74rj.AuZL4xfFmtuTs6_8DUSy wxBFPXSk6xoKLgGvb.mnyM8R8rYwCX4ozXpdSSAyhFBCsGrGN3EHOsjc2eZO30Q73Uy7IvkVzvPT xH1J1cH4ouOtSYO1LH9C7tK.xZyOs8NrrAN2dK0_86F0U_Ti1R.m9KjnIgtRst0lk3_R7EukAhbH C1cx_l49phlSfojQt0QvRYEE4Gpje0uqp7VSVYd1WbdFV0g_XAOR.bBnt5awrJmlg8lZKFr4Z_UQ lvwrpxe18_cDAgNbLXjkXa1.8LuW2uQSp6AgdvVMbK8qWNQBTMic5Bw4TBrrBcqVsESMuzMnNmbr jMqBMHQUlnQ2_eD9pB_7uHEGpV7SRu9g6QXasvFK1RxtsY1LO6SBCskVq5afDAJSHWmHNTsY3O90 37c9egtQNC8wIEJt9pbo3njGbA2qsPtikIJELEOgFB.vv01iPeObacaUSAOYeXZp6uBtl2_7nERC oPua36s1Lwi5p1cK1okMwT9Fr.I2J4461cU6fa0VgrBMdZrOTUAWhA9oZN1Zld92ZRtFazgzt26Z pLXZ6Vq2SZZV9XoX.6B_HpSKRWnt8oUQyGajgiyCHwoES72zAYJTjqPM2P5Obgamy55NQTxrxlHl KXcaLcLhfSF4999fWDvI6GtFmOyF3sHoal0GFAgU3z47clRsXwYXUa4xlKBNg_Y.U.GlToPAb_oy 1510bgkRC9FExWv_1s4hHO8AAC5JVT6dDaFYy6Sl1JGekLHlT0WfsWBGISy27j4ivc7QESuDymJk XCzp5j1bCCwdHNhQGLTlDCyBrqIlbWUCPBue5AXrHtZzYb9421xA53PZzpfrS.1CxJ8P6OzSRG13 ZtP.45tFND.6GLpdXn_8uRNMv806czOdtejI.TBxS1S9Aaz.dH7OixURq9GQ8CUj6HDXe39frtxb 4SSXTqIogjAvvpfiRLUkh_U2b98wGQLz0hrdxYeiOTm0BAqcE5Ai8XQ5aObF80g2NrfBHAKL18ia DOxUiL1EBKD5AWKpnWMTD2o0gFTaCZKdJA3ONu5yNwhjSw9pPgPq.i9hw9KOlGsZ_UqGccdQJ0Vm M0P0Y9rnlTrPw1D4B_AlUd9.L7nbkK60pQKwHBF4d7UUNuvMKfqJCrACCOpkppsJGxkjKdiWYhGY 22..cgmgqclzFJ7wM..V8s1K0Ha8c8mlltDdiMuCPtCZHnSE73xakgnWY75CuJAOCmrSgudnpWKN MAC5lgrL_95DSEfJXx4ZdyNnhpEDjPcNMpjfbQpzSnvbC_RGQ_MT79Nqai7c5gc1pLusCy1voZsr LC2ZQZKyp3BXoXY6YzI5HHEZ_166VVCRXHaSmMIe9SL2AlMt83O6hV9IiJvUIqgfIVEIUMzmrQ52 bg_TmK9ZiKiMDxWGEd.LnkULuuxmEjug6gHXb7Qmyp5ZWAXHeOwYxuwOv2m66jMCTXmQ6fLvwXeT 5CeoxzDmdcjFLXuORCF5tDMjc_v_XdbDIa6VP4GfK6gz58Ugg8u8Gy0wss0HPryijHDpb5DWlG3e VkuKE5lCARn3LOSZTt9Z_NR8TcDLoquRCDz_plL290ntGesgr6W10VfU.v9qmKvgcGUOnTTV5aBJ oYm6WI0PPxqYC4WsTYdPBLn68BA1Z0zBT2gbbrgzwfFTCTgdPTNg0hrFcMlclv0XGwehQrCdKzij _z.rhw0ALMAm7gwthzrlbiuDGuNImow-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Tue, 16 Nov 2021 12:38:13 +0000 Received: by kubenode503.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8048f6b9082a25c2698ef6d9e8858b9f; Tue, 16 Nov 2021 12:38:06 +0000 (UTC) From: Po Lu To: bug-gnu-emacs@gnu.org Subject: 29.0.50; [PATCH] Pixel delta support for wheel events on X Date: Tue, 16 Nov 2021 20:38:03 +0800 Message-ID: <87zgq4uvh0.fsf@yahoo.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" References: <87zgq4uvh0.fsf.ref@yahoo.com> X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 63690 Received-SPF: pass client-ip=66.163.184.146; envelope-from=luangruo@yahoo.com; helo=sonic309-20.consmr.mail.ne1.yahoo.com X-Spam_score_int: -7 X-Spam_score: -0.8 X-Spam_bar: / X-Spam_report: (-0.8 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, NML_ADSP_CUSTOM_MED=0.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: -0.6 (/) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.6 (-) --=-=-= Content-Type: text/plain I've implemented support for exposing the pixel delta of XInput 2 wheel events to Lisp code. With GC turned off, utilizing a modified pixel-scroll.el with this support results in a quite pleasant experience, but pixel-scroll still GCs too much to be useful. Pixel based scrolling is a popular feature in modern X applications, and does make life a lot easier in many cases. The existing support is inadequate as it cannot utilize the detailed delta information available from modern touch-based scroll wheels, which this patch enables. The XInput 2 support isn't the best from a code duplication POV, but the behavior of the XInput 2 code often differs in subtle ways from that of the Core Input code, and trying to combine the two together would result in a more catastrophic mess than leaving them apart. Obviously, here is the original XInput 2 support patch: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-support-for-event-processing-via-XInput-2.patch >From 39458cca1d83a9fcd9e4ced05cef67468d7cd21c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 16 Oct 2021 13:15:36 +0800 Subject: [PATCH 1/2] Add support for event processing via XInput 2 * configure.ac: Add an option to use XInput 2 if available. * src/Makefile.in (XINPUT_LIBS, XINPUT_CFLAGS): New variables. (EMACS_CFLAGS): Add Xinput CFLAGS. (LIBES): Add XInput libs. * src/xmenu.c (popup_activated_flag): Expose flag if XInput 2 is available. * src/xfns.c (x_window): Set XInput 2 event mask. (setup_xi_event_mask): New function. (syms_of_xfns): Provide XInput 2 feature. * src/xterm.c (x_detect_focus_change): Handle XInput 2 GenericEvents. (handle_one_xevent): Handle XInput 2 events. (x_term_init): Ask the server for XInput 2 support and set xkb_desc if available. (x_delete_terminal): Free XKB kb desc if it exists, and free XI2 devices if they exist. (xi_grab_or_ungrab_device) (xi_reset_scroll_valuators_for_device_id) (x_free_xi_devices, x_init_master_valuators): New functions. (x_get_scroll_valuator_delta): New function. (init_xterm): Don't tell GTK to only use Core Input when built with XInput 2 support. * src/xterm.h (struct x_display_info): Add fields for XKB and XI2 support. * src/gtkutil.c (xg_event_is_for_menubar): Handle XIDeviceEvents. (xg_is_menu_window): New function. (xg_event_is_for_scrollbar): Handle XIDeviceEvents. * etc/NEWS: Document changes. * lisp/mwheel.el (mouse-wheel-down-alternate-event) (mouse-wheel-up-alternate-event) (mouse-wheel-left-alternate-event) (mouse-wheel-right-alternate-event): New user options. (mouse-wheel-text-scale) (mwheel-scroll): Test for alternate events. (mouse-wheel--setup-bindings): Set up bindings for alternate buttons. --- configure.ac | 22 + etc/NEWS | 17 + lisp/mwheel.el | 66 ++- src/Makefile.in | 7 +- src/gtkutil.c | 72 ++- src/gtkutil.h | 4 + src/xfns.c | 50 +++ src/xmenu.c | 4 + src/xterm.c | 1107 ++++++++++++++++++++++++++++++++++++++++++++++- src/xterm.h | 44 ++ 10 files changed, 1372 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index c231c2ceae..239bf72f71 100644 --- a/configure.ac +++ b/configure.ac @@ -487,6 +487,7 @@ AC_DEFUN OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) OPTION_DEFAULT_OFF([native-compilation],[compile with Emacs Lisp native compiler support]) OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin]) +OPTION_DEFAULT_OFF([xinput2],[use version 2.0 the X Input Extension for input]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -4237,6 +4238,26 @@ AC_DEFUN AC_SUBST(XFIXES_CFLAGS) AC_SUBST(XFIXES_LIBS) +## Use XInput 2.0 if available +HAVE_XINPUT2=no +if test "${HAVE_X11}" = "yes" && test "${with_xinput2}" != "no"; then + EMACS_CHECK_MODULES([XINPUT], [xi]) + if test $HAVE_XINPUT = yes; then + # Now check for XInput2.h + AC_CHECK_HEADER(X11/extensions/XInput2.h, + [AC_CHECK_LIB(Xi, XIGrabButton, HAVE_XINPUT2=yes)]) + fi + if test $HAVE_XINPUT2 = yes; then + AC_DEFINE(HAVE_XINPUT2, 1, [Define to 1 if the X Input Extension version 2.0 is present.]) + if test "$USE_GTK_TOOLKIT" = "GTK2"; then + AC_MSG_WARN([You are building Emacs with GTK+ 2 and the X Input Extension version 2. +This might lead to problems if your version of GTK+ is not built with support for XInput 2.]) + fi + fi +fi +AC_SUBST(XINPUT_CFLAGS) +AC_SUBST(XINPUT_LIBS) + ### Use Xdbe (-lXdbe) if available HAVE_XDBE=no if test "${HAVE_X11}" = "yes"; then @@ -6011,6 +6032,7 @@ AC_DEFUN Does Emacs support legacy unexec dumping? ${with_unexec} Which dumping strategy does Emacs use? ${with_dumping} Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP} + Does Emacs use version 2 of the the X Input Extension? ${HAVE_XINPUT2} "]) if test -n "${EMACSDATA}"; then diff --git a/etc/NEWS b/etc/NEWS index 80be6c0e49..ca6b946843 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -30,6 +30,14 @@ The file is typically installed using a file name akin to If a constant file name is required, the file can be renamed to "emacs.pdmp", and Emacs will find it during startup anyway. +** Emacs now supports use of XInput 2 for input events. +If your X server has support and you have the XInput 2 development headers +installed, you can configure Emacs with the option '--with-xinput2' to enable +this support. + +The named feature `xinput2' can be used to test for the presence of +XInput 2 support from Lisp programs. + * Startup Changes in Emacs 29.1 @@ -217,6 +225,15 @@ The user option 'comint-terminfo-terminal' and variable 'system-uses-terminfo' can now be set as connection-local variables to change the terminal used on a remote host. +** Mwheel + +--- +*** New user options for alternate wheel events. +The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event', +'mouse-wheel-left-alternate-event', and 'mouse-wheel-right-alternate-event' have +been added to better support systems where two kinds of wheel events can be +received. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/mwheel.el b/lisp/mwheel.el index 51410e3ef4..3d0b8f07cb 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el @@ -63,6 +63,13 @@ mouse-wheel-down-event :type 'symbol :set 'mouse-wheel-change-button) +(defcustom mouse-wheel-down-alternate-event + (when (featurep 'xinput2) 'wheel-up) + "Alternative wheel down event to consider." + :group 'mouse + :type 'symbol + :set 'mouse-wheel-change-button) + (defcustom mouse-wheel-up-event (if (or (featurep 'w32-win) (featurep 'ns-win)) 'wheel-down @@ -72,6 +79,13 @@ mouse-wheel-up-event :type 'symbol :set 'mouse-wheel-change-button) +(defcustom mouse-wheel-up-alternate-event + (when (featurep 'xinput2) 'wheel-down) + "Alternative wheel up event to consider." + :group 'mouse + :type 'symbol + :set 'mouse-wheel-change-button) + (defcustom mouse-wheel-click-event 'mouse-2 "Event that should be temporarily inhibited after mouse scrolling. The mouse wheel is typically on the mouse-2 button, so it may easily @@ -226,12 +240,20 @@ mouse-wheel-left-event 'mouse-6) "Event used for scrolling left.") +(defvar mouse-wheel-left-alternate-event + (when (featurep 'xinput2) 'wheel-left) + "Alternative wheel left event to consider.") + (defvar mouse-wheel-right-event (if (or (featurep 'w32-win) (featurep 'ns-win)) 'wheel-right 'mouse-7) "Event used for scrolling right.") +(defvar mouse-wheel-right-alternate-event + (when (featurep 'xinput2) 'wheel-right) + "Alternative wheel right event to consider.") + (defun mouse-wheel--get-scroll-window (event) "Return window for mouse wheel event EVENT. If `mouse-wheel-follow-mouse' is non-nil, return the window that @@ -296,14 +318,16 @@ mwheel-scroll (condition-case nil (unwind-protect (let ((button (mwheel-event-button event))) - (cond ((and (eq amt 'hscroll) (eq button mouse-wheel-down-event)) + (cond ((and (eq amt 'hscroll) (memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event))) (when (and (natnump arg) (> arg 0)) (setq mouse-wheel-scroll-amount-horizontal arg)) (funcall (if mouse-wheel-flip-direction mwheel-scroll-left-function mwheel-scroll-right-function) mouse-wheel-scroll-amount-horizontal)) - ((eq button mouse-wheel-down-event) + ((memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event)) (condition-case nil (funcall mwheel-scroll-down-function amt) ;; Make sure we do indeed scroll to the beginning of ;; the buffer. @@ -318,23 +342,27 @@ mwheel-scroll ;; for a reason that escapes me. This problem seems ;; to only affect scroll-down. --Stef (set-window-start (selected-window) (point-min)))))) - ((and (eq amt 'hscroll) (eq button mouse-wheel-up-event)) + ((and (eq amt 'hscroll) (memq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event))) (when (and (natnump arg) (> arg 0)) (setq mouse-wheel-scroll-amount-horizontal arg)) (funcall (if mouse-wheel-flip-direction mwheel-scroll-right-function mwheel-scroll-left-function) mouse-wheel-scroll-amount-horizontal)) - ((eq button mouse-wheel-up-event) + ((memq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event)) (condition-case nil (funcall mwheel-scroll-up-function amt) ;; Make sure we do indeed scroll to the end of the buffer. (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) - ((eq button mouse-wheel-left-event) ; for tilt scroll + ((memq button (list mouse-wheel-left-event + mouse-wheel-left-alternate-event)) ; for tilt scroll (when mouse-wheel-tilt-scroll (funcall (if mouse-wheel-flip-direction mwheel-scroll-right-function mwheel-scroll-left-function) amt))) - ((eq button mouse-wheel-right-event) ; for tilt scroll + ((memq button (list mouse-wheel-right-event + mouse-wheel-right-alternate-event)) ; for tilt scroll (when mouse-wheel-tilt-scroll (funcall (if mouse-wheel-flip-direction mwheel-scroll-left-function @@ -378,9 +406,11 @@ mouse-wheel-text-scale (button (mwheel-event-button event))) (select-window scroll-window 'mark-for-redisplay) (unwind-protect - (cond ((eq button mouse-wheel-down-event) + (cond ((memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event)) (text-scale-increase 1)) - ((eq button mouse-wheel-up-event) + ((eq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event)) (text-scale-decrease 1))) (select-window selected-window)))) @@ -432,15 +462,23 @@ mouse-wheel--setup-bindings (cond ;; Bindings for changing font size. ((and (consp binding) (eq (cdr binding) 'text-scale)) - (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event)) - (mouse-wheel--add-binding `[,(list (caar binding) event)] - 'mouse-wheel-text-scale))) + (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event + mouse-wheel-down-alternate-event + mouse-wheel-up-alternate-event)) + (when event + (mouse-wheel--add-binding `[,(list (caar binding) event)] + 'mouse-wheel-text-scale)))) ;; Bindings for scrolling. (t (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event - mouse-wheel-left-event mouse-wheel-right-event)) - (dolist (key (mouse-wheel--create-scroll-keys binding event)) - (mouse-wheel--add-binding key 'mwheel-scroll))))))) + mouse-wheel-left-event mouse-wheel-right-event + mouse-wheel-down-alternate-event + mouse-wheel-up-alternate-event + mouse-wheel-left-alternate-event + mouse-wheel-right-alternate-event)) + (when event + (dolist (key (mouse-wheel--create-scroll-keys binding event)) + (mouse-wheel--add-binding key 'mwheel-scroll)))))))) (when mouse-wheel-mode (mouse-wheel--setup-bindings)) diff --git a/src/Makefile.in b/src/Makefile.in index 4c5535f8ad..0aaaf91d39 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -258,6 +258,9 @@ XINERAMA_CFLAGS = XFIXES_LIBS = @XFIXES_LIBS@ XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XINPUT_LIBS = @XINPUT_LIBS@ +XINPUT_CFLAGS = @XINPUT_CFLAGS@ + XDBE_LIBS = @XDBE_LIBS@ XDBE_CFLAGS = @XDBE_CFLAGS@ @@ -374,7 +377,7 @@ EMACS_CFLAGS= $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \ $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ - $(WEBKIT_CFLAGS) $(WEBP_CFLAGS) $(LCMS2_CFLAGS) \ + $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \ $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \ @@ -524,7 +527,7 @@ LIBES = $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ - $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) + $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) ## FORCE it so that admin/unidata can decide whether this file is ## up-to-date. Although since charprop depends on bootstrap-emacs, diff --git a/src/gtkutil.c b/src/gtkutil.c index a9eabf47d8..9e676cd025 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -47,6 +47,10 @@ Copyright (C) 2003-2021 Free Software Foundation, Inc. #include +#ifdef HAVE_XINPUT2 +#include +#endif + #ifdef HAVE_XFT #include #endif @@ -839,6 +843,23 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, } #endif +#if defined HAVE_GTK3 && defined HAVE_XINPUT2 +bool +xg_is_menu_window (Display *dpy, Window wdesc) +{ + GtkWidget *gwdesc = xg_win_to_widget (dpy, wdesc); + + if (GTK_IS_WINDOW (gwdesc)) + { + GtkWidget *fw = gtk_bin_get_child (GTK_BIN (gwdesc)); + if (GTK_IS_MENU (fw)) + return true; + } + + return false; +} +#endif + /* Make a geometry string and pass that to GTK. It seems this is the only way to get geometry position right if the user explicitly asked for a position when starting Emacs. @@ -3589,6 +3610,18 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) if (! x->menubar_widget) return 0; +#ifdef HAVE_XINPUT2 + XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; + if (event->type == GenericEvent) /* XI_ButtonPress or XI_ButtonRelease */ + { + if (! (xev->event_x >= 0 + && xev->event_x < FRAME_PIXEL_WIDTH (f) + && xev->event_y >= 0 + && xev->event_y < FRAME_MENUBAR_HEIGHT (f))) + return 0; + } + else +#endif if (! (event->xbutton.x >= 0 && event->xbutton.x < FRAME_PIXEL_WIDTH (f) && event->xbutton.y >= 0 @@ -3597,7 +3630,12 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) return 0; gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); - gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); +#ifdef HAVE_XINPUT2 + if (event->type == GenericEvent) + gw = gdk_x11_window_lookup_for_display (gdpy, xev->event); + else +#endif + gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); if (! gw) return 0; gevent.any.window = gw; gevent.any.type = GDK_NOTHING; @@ -4244,7 +4282,20 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) { bool retval = 0; +#ifdef HAVE_XINPUT2 + XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; + if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 + && event->type == GenericEvent + && (event->xgeneric.extension + == FRAME_DISPLAY_INFO (f)->xi2_opcode) + && ((event->xgeneric.evtype == XI_ButtonPress + && xev->detail < 4) + || (event->xgeneric.evtype == XI_Motion))) + || (event->type == ButtonPress + && event->xbutton.button < 4))) +#else if (f && event->type == ButtonPress && event->xbutton.button < 4) +#endif /* HAVE_XINPUT2 */ { /* Check if press occurred outside the edit widget. */ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); @@ -4262,10 +4313,29 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL); #endif retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget); +#ifdef HAVE_XINPUT2 + GtkWidget *grab = gtk_grab_get_current (); + if (event->type == GenericEvent + && event->xgeneric.evtype == XI_Motion) + retval = retval || (grab && GTK_IS_SCROLLBAR (grab)); +#endif } +#ifdef HAVE_XINPUT2 + else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 + && event->type == GenericEvent + && (event->xgeneric.extension + == FRAME_DISPLAY_INFO (f)->xi2_opcode) + && ((event->xgeneric.evtype == XI_ButtonRelease + && xev->detail < 4) + || (event->xgeneric.evtype == XI_Motion))) + || ((event->type == ButtonRelease + && event->xbutton.button < 4) + || event->type == MotionNotify))) +#else else if (f && ((event->type == ButtonRelease && event->xbutton.button < 4) || event->type == MotionNotify)) +#endif /* HAVE_XINPUT2 */ { /* If we are releasing or moving the scroll bar, it has the grab. */ GtkWidget *w = gtk_grab_get_current (); diff --git a/src/gtkutil.h b/src/gtkutil.h index 31a12cd5d3..95dd75b7fa 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -192,6 +192,10 @@ #define XG_ITEM_DATA "emacs_menuitem" extern void xg_print_frames_dialog (Lisp_Object); #endif +#if defined HAVE_GTK3 && defined HAVE_XINPUT2 +extern bool xg_is_menu_window (Display *dpy, Window); +#endif + /* Mark all callback data that are Lisp_object:s during GC. */ extern void xg_mark_data (void); diff --git a/src/xfns.c b/src/xfns.c index 785ae3baca..b33b40b330 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -57,6 +57,10 @@ Copyright (C) 1989, 1992-2021 Free Software Foundation, Inc. #include #endif +#ifdef HAVE_XINPUT2 +#include +#endif + #ifdef USE_X_TOOLKIT #include @@ -2912,6 +2916,37 @@ initial_set_up_x_back_buffer (struct frame *f) unblock_input (); } +#if defined HAVE_XINPUT2 && !defined USE_GTK +static void +setup_xi_event_mask (struct frame *f) +{ + XIEventMask mask; + ptrdiff_t l = XIMaskLen (XI_LASTEVENT); + unsigned char *m; + + mask.mask = m = alloca (l); + memset (m, 0, l); + mask.mask_len = l; + mask.deviceid = XIAllMasterDevices; + + XISetMask (m, XI_ButtonPress); + XISetMask (m, XI_ButtonRelease); + XISetMask (m, XI_KeyPress); + XISetMask (m, XI_KeyRelease); + XISetMask (m, XI_Motion); + XISetMask (m, XI_Enter); + XISetMask (m, XI_Leave); + XISetMask (m, XI_FocusIn); + XISetMask (m, XI_FocusOut); + XISetMask (m, XI_PropertyEvent); + XISetMask (m, XI_HierarchyChanged); + XISetMask (m, XI_DeviceChanged); + XISelectEvents (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + &mask, 1); +} +#endif + #ifdef USE_X_TOOLKIT /* Create and set up the X widget for frame F. */ @@ -3074,6 +3109,11 @@ x_window (struct frame *f, long window_prompting) class_hints.res_class = SSDATA (Vx_resource_class); XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); +#ifdef HAVE_XINPUT2 + if (FRAME_DISPLAY_INFO (f)->supports_xi2) + setup_xi_event_mask (f); +#endif + #ifdef HAVE_X_I18N FRAME_XIC (f) = NULL; if (use_xim) @@ -3254,6 +3294,11 @@ x_window (struct frame *f) } #endif /* HAVE_X_I18N */ +#ifdef HAVE_XINPUT2 + if (FRAME_DISPLAY_INFO (f)->supports_xi2) + setup_xi_event_mask (f); +#endif + validate_x_resource_name (); class_hints.res_name = SSDATA (Vx_resource_name); @@ -8038,6 +8083,11 @@ syms_of_xfns (void) /* Tell Emacs about this window system. */ Fprovide (Qx, Qnil); +#ifdef HAVE_XINPUT2 + DEFSYM (Qxinput2, "xinput2"); + Fprovide (Qxinput2, Qnil); +#endif + #ifdef USE_X_TOOLKIT Fprovide (intern_c_string ("x-toolkit"), Qnil); #ifdef USE_MOTIF diff --git a/src/xmenu.c b/src/xmenu.c index ea2cbab203..07255911f9 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -105,7 +105,11 @@ Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2021 Free Software /* Flag which when set indicates a dialog or menu has been posted by Xt on behalf of one of the widget sets. */ +#ifndef HAVE_XINPUT2 static int popup_activated_flag; +#else +int popup_activated_flag; +#endif #ifdef USE_X_TOOLKIT diff --git a/src/xterm.c b/src/xterm.c index 816b6dc5a8..63754a2cb6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -42,6 +42,10 @@ Copyright (C) 1989, 1993-2021 Free Software Foundation, Inc. #include #endif +#ifdef HAVE_XINPUT2 +#include +#endif + /* Load sys/types.h if not already loaded. In some systems loading it twice is suicidal. */ #ifndef makedev @@ -223,9 +227,15 @@ #define XtNinitialState "initialState" static void x_check_fullscreen (struct frame *); static void x_check_expected_move (struct frame *, int, int); static void x_sync_with_move (struct frame *, int, int, bool); +#ifndef HAVE_XINPUT2 static int handle_one_xevent (struct x_display_info *, const XEvent *, int *, struct input_event *); +#else +static int handle_one_xevent (struct x_display_info *, + XEvent *, int *, + struct input_event *); +#endif #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK static int x_dispatch_event (XEvent *, Display *); #endif @@ -335,6 +345,224 @@ x_extension_initialize (struct x_display_info *dpyinfo) dpyinfo->ext_codes = ext_codes; } + +#ifdef HAVE_XINPUT2 + +/* Free all XI2 devices on dpyinfo. */ +static void +x_free_xi_devices (struct x_display_info *dpyinfo) +{ + block_input (); + + if (dpyinfo->num_devices) + { + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, + CurrentTime); + xfree (dpyinfo->devices[i].valuators); + } + + xfree (dpyinfo->devices); + dpyinfo->devices = NULL; + dpyinfo->num_devices = 0; + } + + unblock_input (); +} + +/* Setup valuator tracking for XI2 master devices on + DPYINFO->display. */ + +static void +x_init_master_valuators (struct x_display_info *dpyinfo) +{ + int ndevices; + XIDeviceInfo *infos; + + block_input (); + x_free_xi_devices (dpyinfo); + infos = XIQueryDevice (dpyinfo->display, + XIAllMasterDevices, + &ndevices); + + if (!ndevices) + { + XIFreeDeviceInfo (infos); + unblock_input (); + return; + } + + int actual_devices = 0; + dpyinfo->devices = xmalloc (sizeof *dpyinfo->devices * ndevices); + + for (int i = 0; i < ndevices; ++i) + { + XIDeviceInfo *device = &infos[i]; + + if (device->enabled) + { + int actual_valuator_count = 0; + struct xi_device_t *xi_device = &dpyinfo->devices[actual_devices++]; + xi_device->device_id = device->deviceid; + xi_device->grab = 0; + xi_device->valuators = + xmalloc (sizeof *xi_device->valuators * device->num_classes); + + for (int c = 0; c < device->num_classes; ++c) + { + switch (device->classes[c]->type) + { +#ifdef XIScrollClass /* XInput 2.1 */ + case XIScrollClass: + { + XIScrollClassInfo *info = + (XIScrollClassInfo *) device->classes[c]; + struct xi_scroll_valuator_t *valuator = + &xi_device->valuators[actual_valuator_count++]; + + valuator->horizontal + = (info->scroll_type == XIScrollTypeHorizontal); + valuator->invalid_p = true; + valuator->emacs_value = DBL_MIN; + valuator->increment = info->increment; + valuator->number = info->number; + break; + } +#endif + default: + break; + } + } + xi_device->scroll_valuator_count = actual_valuator_count; + } + } + + dpyinfo->num_devices = actual_devices; + XIFreeDeviceInfo (infos); + unblock_input (); +} + +/* Return the delta of the scroll valuator VALUATOR_NUMBER under + DEVICE_ID in the display DPYINFO with VALUE. The valuator's + valuator will be set to VALUE afterwards. In case no scroll + valuator is found, or if device_id is not known to Emacs, DBL_MAX + is returned. Otherwise, the valuator is returned in + VALUATOR_RETURN. */ +static double +x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id, + int valuator_number, double value, + struct xi_scroll_valuator_t **valuator_return) +{ + block_input (); + + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + struct xi_device_t *device = &dpyinfo->devices[i]; + + if (device->device_id == device_id) + { + for (int j = 0; j < device->scroll_valuator_count; ++j) + { + struct xi_scroll_valuator_t *sv = &device->valuators[j]; + + if (sv->number == valuator_number) + { + if (sv->invalid_p) + { + sv->current_value = value; + sv->invalid_p = false; + *valuator_return = sv; + + unblock_input (); + return 0.0; + } + else + { + double delta = (sv->current_value - value) / sv->increment; + sv->current_value = value; + *valuator_return = sv; + + unblock_input (); + return delta; + } + } + } + + unblock_input (); + return DBL_MAX; + } + } + + unblock_input (); + return DBL_MAX; +} + +static struct xi_device_t * +xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) +{ + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + if (dpyinfo->devices[i].device_id == deviceid) + return &dpyinfo->devices[i]; + } + + return NULL; +} + +static void +xi_grab_or_ungrab_device (struct xi_device_t *device, + struct x_display_info *dpyinfo, + Window window) +{ + XIEventMask mask; + ptrdiff_t l = XIMaskLen (XI_LASTEVENT); + unsigned char *m; + mask.mask = m = alloca (l); + memset (m, 0, l); + mask.mask_len = l; + + XISetMask (m, XI_ButtonPress); + XISetMask (m, XI_ButtonRelease); + XISetMask (m, XI_Motion); + XISetMask (m, XI_Enter); + XISetMask (m, XI_Leave); + + if (device->grab) + { + XIGrabDevice (dpyinfo->display, device->device_id, window, + CurrentTime, None, GrabModeAsync, + GrabModeAsync, True, &mask); + } + else + { + XIUngrabDevice (dpyinfo->display, device->device_id, CurrentTime); + } +} + +static void +xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) +{ + struct xi_device_t *device = xi_device_from_id (dpyinfo, id); + struct xi_scroll_valuator_t *valuator; + + if (!device) + return; + + if (!device->scroll_valuator_count) + return; + + for (int i = 0; i < device->scroll_valuator_count; ++i) + { + valuator = &device->valuators[i]; + valuator->invalid_p = true; + } + + return; +} + +#endif + void x_cr_destroy_frame_context (struct frame *f) { @@ -4768,7 +4996,16 @@ x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc) x_menubar_window_to_frame (struct x_display_info *dpyinfo, const XEvent *event) { - Window wdesc = event->xany.window; + Window wdesc; +#ifdef HAVE_XINPUT2 + if (event->type == GenericEvent + && dpyinfo->supports_xi2 + && (event->xcookie.evtype == XI_ButtonPress + || event->xcookie.evtype == XI_ButtonRelease)) + wdesc = ((XIDeviceEvent *) event->xcookie.data)->event; + else +#endif + wdesc = event->xany.window; Lisp_Object tail, frame; struct frame *f; struct x_output *x; @@ -4871,6 +5108,29 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame, } break; +#ifdef HAVE_XINPUT2 + case GenericEvent: + { + XIEvent *xi_event = (XIEvent *) event; + + struct frame *focus_frame = dpyinfo->x_focus_event_frame; + int focus_state + = focus_frame ? focus_frame->output_data.x->focus_state : 0; + + if (!((xi_event->evtype == XI_Enter + || xi_event->evtype == XI_Leave) + && (focus_state & FOCUS_EXPLICIT))) + x_focus_changed ((xi_event->evtype == XI_Enter + || xi_event->evtype == XI_FocusIn + ? FocusIn : FocusOut), + (xi_event->evtype == XI_Enter + || xi_event->evtype == XI_Leave + ? FOCUS_IMPLICIT : FOCUS_EXPLICIT), + dpyinfo, frame, bufp); + break; + } +#endif + case FocusIn: case FocusOut: /* Ignore transient focus events from hotkeys, window manager @@ -7975,7 +8235,11 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc) static int handle_one_xevent (struct x_display_info *dpyinfo, +#ifndef HAVE_XINPUT2 const XEvent *event, +#else + XEvent *event, +#endif int *finish, struct input_event *hold_quit) { union buffered_input_event inev; @@ -8001,7 +8265,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.kind = NO_EVENT; inev.ie.arg = Qnil; - any = x_any_window_to_frame (dpyinfo, event->xany.window); +#ifdef HAVE_XINPUT2 + if (event->type != GenericEvent) +#endif + any = x_any_window_to_frame (dpyinfo, event->xany.window); +#ifdef HAVE_XINPUT2 + else + any = NULL; +#endif if (any && any->wait_event_type == event->type) any->wait_event_type = 0; /* Indicates we got it. */ @@ -8480,6 +8751,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case MapNotify: +#if defined HAVE_XINPUT2 && defined HAVE_GTK3 + if (xg_is_menu_window (dpyinfo->display, event->xmap.window)) + popup_activated_flag = 1; +#endif /* We use x_top_window_to_frame because map events can come for sub-windows and they don't mean that the frame is visible. */ @@ -9518,6 +9793,785 @@ handle_one_xevent (struct x_display_info *dpyinfo, case DestroyNotify: xft_settings_event (dpyinfo, event); break; +#ifdef HAVE_XINPUT2 + case GenericEvent: + { + if (!dpyinfo->supports_xi2) + goto OTHER; + if (event->xgeneric.extension != dpyinfo->xi2_opcode) + /* Not an XI2 event. */ + goto OTHER; + bool must_free_data = false; + XIEvent *xi_event = (XIEvent *) event->xcookie.data; + /* Sometimes the event is already claimed by GTK, which + will free its data in due course. */ + if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie)) + { + must_free_data = true; + xi_event = (XIEvent *) event->xcookie.data; + } + + XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; + XILeaveEvent *leave = (XILeaveEvent *) xi_event; + XIEnterEvent *enter = (XIEnterEvent *) xi_event; + XIFocusInEvent *focusin = (XIFocusInEvent *) xi_event; + XIFocusOutEvent *focusout = (XIFocusOutEvent *) xi_event; + XIValuatorState *states; + double *values; + bool found_valuator = false; + + /* A fake XMotionEvent for x_note_mouse_movement. */ + XMotionEvent ev; + /* A fake XButtonEvent for x_construct_mouse_click. */ + XButtonEvent bv; + + if (!xi_event) + { + eassert (!must_free_data); + goto OTHER; + } + + switch (event->xcookie.evtype) + { + case XI_FocusIn: + any = x_any_window_to_frame (dpyinfo, focusin->event); +#ifndef USE_GTK + /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap + minimized/iconified windows; thus, for those WMs we won't get + a MapNotify when unminimizing/deconifying. Check here if we + are deiconizing a window (Bug42655). + + But don't do that on GTK since it may cause a plain invisible + frame get reported as iconified, compare + https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. + That is fixed above but bites us here again. */ + f = any; + if (f && FRAME_ICONIFIED_P (f)) + { + SET_FRAME_VISIBLE (f, 1); + SET_FRAME_ICONIFIED (f, false); + f->output_data.x->has_been_visible = true; + inev.ie.kind = DEICONIFY_EVENT; + XSETFRAME (inev.ie.frame_or_window, f); + } +#endif /* USE_GTK */ + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + goto XI_OTHER; + case XI_FocusOut: + any = x_any_window_to_frame (dpyinfo, focusout->event); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + goto XI_OTHER; + case XI_Enter: + any = x_any_window_to_frame (dpyinfo, enter->event); + ev.x = lrint (enter->event_x); + ev.y = lrint (enter->event_y); + ev.window = leave->event; + + x_display_set_last_user_time (dpyinfo, xi_event->time); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_reset_scroll_valuators_for_device_id (dpyinfo, enter->deviceid); + f = any; + + if (f && x_mouse_click_focus_ignore_position) + ignore_next_mouse_click_timeout = xi_event->time + 200; + + /* EnterNotify counts as mouse movement, + so update things that depend on mouse position. */ + if (f && !f->output_data.x->hourglass_p) + x_note_mouse_movement (f, &ev); +#ifdef USE_GTK + /* We may get an EnterNotify on the buttons in the toolbar. In that + case we moved out of any highlighted area and need to note this. */ + if (!f && dpyinfo->last_mouse_glyph_frame) + x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); +#endif + goto XI_OTHER; + case XI_Leave: + ev.x = lrint (leave->event_x); + ev.y = lrint (leave->event_y); + ev.window = leave->event; + any = x_any_window_to_frame (dpyinfo, leave->event); + + x_display_set_last_user_time (dpyinfo, xi_event->time); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_reset_scroll_valuators_for_device_id (dpyinfo, leave->deviceid); + + f = x_top_window_to_frame (dpyinfo, leave->event); + if (f) + { + if (f == hlinfo->mouse_face_mouse_frame) + { + /* If we move outside the frame, then we're + certainly no longer on any text in the frame. */ + clear_mouse_face (hlinfo); + hlinfo->mouse_face_mouse_frame = 0; + } + + /* Generate a nil HELP_EVENT to cancel a help-echo. + Do it only if there's something to cancel. + Otherwise, the startup message is cleared when + the mouse leaves the frame. */ + if (any_help_event_p) + do_help = -1; + } +#ifdef USE_GTK + /* See comment in EnterNotify above */ + else if (dpyinfo->last_mouse_glyph_frame) + x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); +#endif + goto XI_OTHER; + case XI_Motion: + /* First test if there is some kind of scroll event + here! */ + states = &xev->valuators; + values = states->values; + + x_display_set_last_user_time (dpyinfo, xi_event->time); + + for (int i = 0; i < states->mask_len * 8; i++) + { + if (XIMaskIsSet (states->mask, i)) + { + block_input (); + + struct xi_scroll_valuator_t *val; + double delta; + + delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, + i, *values, &val); + + if (delta != DBL_MAX) + { + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + found_valuator = true; + + if (signbit (delta) != signbit (val->emacs_value)) + val->emacs_value = 0; + + val->emacs_value += delta; + + if (!f) + { + f = x_any_window_to_frame (dpyinfo, xev->event); + + if (!f) + { + unblock_input (); + goto XI_OTHER; + } + } + + bool s = signbit (val->emacs_value); + inev.ie.kind = (val->horizontal + ? HORIZ_WHEEL_EVENT + : WHEEL_EVENT); + inev.ie.timestamp = xev->time; + + XSETINT (inev.ie.x, lrint (xev->event_x)); + XSETINT (inev.ie.y, lrint (xev->event_y)); + XSETFRAME (inev.ie.frame_or_window, f); + + inev.ie.modifiers = !s ? up_modifier : down_modifier; + inev.ie.modifiers + |= x_x_to_emacs_modifiers (dpyinfo, + xev->mods.effective); + inev.ie.arg = Qnil; + + kbd_buffer_store_event_hold (&inev.ie, hold_quit); + + val->emacs_value = 0; + } + unblock_input (); + values++; + } + + inev.ie.kind = NO_EVENT; + } + + if (found_valuator) + goto XI_OTHER; + + ev.x = lrint (xev->event_x); + ev.y = lrint (xev->event_y); + ev.window = xev->event; + + previous_help_echo_string = help_echo_string; + help_echo_string = Qnil; + + if (hlinfo->mouse_face_hidden) + { + hlinfo->mouse_face_hidden = false; + clear_mouse_face (hlinfo); + } + + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + +#ifdef USE_GTK + if (f && xg_event_is_for_scrollbar (f, event)) + f = 0; +#endif + if (f) + { + /* Maybe generate a SELECT_WINDOW_EVENT for + `mouse-autoselect-window' but don't let popup menus + interfere with this (Bug#1261). */ + if (!NILP (Vmouse_autoselect_window) + && !popup_activated () + /* Don't switch if we're currently in the minibuffer. + This tries to work around problems where the + minibuffer gets unselected unexpectedly, and where + you then have to move your mouse all the way down to + the minibuffer to select it. */ + && !MINI_WINDOW_P (XWINDOW (selected_window)) + /* With `focus-follows-mouse' non-nil create an event + also when the target window is on another frame. */ + && (f == XFRAME (selected_frame) + || !NILP (focus_follows_mouse))) + { + static Lisp_Object last_mouse_window; + Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); + + /* A window will be autoselected only when it is not + selected now and the last mouse movement event was + not in it. The remainder of the code is a bit vague + wrt what a "window" is. For immediate autoselection, + the window is usually the entire window but for GTK + where the scroll bars don't count. For delayed + autoselection the window is usually the window's text + area including the margins. */ + if (WINDOWP (window) + && !EQ (window, last_mouse_window) + && !EQ (window, selected_window)) + { + inev.ie.kind = SELECT_WINDOW_EVENT; + inev.ie.frame_or_window = window; + } + + /* Remember the last window where we saw the mouse. */ + last_mouse_window = window; + } + + if (!x_note_mouse_movement (f, &ev)) + help_echo_string = previous_help_echo_string; + } + else + { +#ifndef USE_TOOLKIT_SCROLL_BARS + struct scroll_bar *bar + = x_window_to_scroll_bar (xi_event->display, xev->event, 2); + + if (bar) + x_scroll_bar_note_movement (bar, &ev); +#endif /* USE_TOOLKIT_SCROLL_BARS */ + + /* If we move outside the frame, then we're + certainly no longer on any text in the frame. */ + clear_mouse_face (hlinfo); + } + + /* If the contents of the global variable help_echo_string + has changed, generate a HELP_EVENT. */ + if (!NILP (help_echo_string) + || !NILP (previous_help_echo_string)) + do_help = 1; + goto XI_OTHER; + case XI_ButtonRelease: + case XI_ButtonPress: + { + /* If we decide we want to generate an event to be seen + by the rest of Emacs, we put it here. */ + Lisp_Object tab_bar_arg = Qnil; + bool tab_bar_p = false; + bool tool_bar_p = false; + struct xi_device_t *device; + + /* Ignore emulated scroll events when XI2 native + scroll events are present. */ + if (dpyinfo->xi2_version >= 1 && xev->detail >= 4 + && xev->detail <= 8) + goto XI_OTHER; + + device = xi_device_from_id (dpyinfo, xev->deviceid); + + bv.button = xev->detail; + bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; + bv.x = lrint (xev->event_x); + bv.y = lrint (xev->event_y); + bv.window = xev->event; + bv.state = xev->mods.base + | xev->mods.effective + | xev->mods.latched + | xev->mods.locked; + + memset (&compose_status, 0, sizeof (compose_status)); + dpyinfo->last_mouse_glyph_frame = NULL; + x_display_set_last_user_time (dpyinfo, xev->time); + + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + + if (f && xev->evtype == XI_ButtonPress + && !popup_activated () + && !x_window_to_scroll_bar (xev->display, xev->event, 2) + && !FRAME_NO_ACCEPT_FOCUS (f)) + { + /* When clicking into a child frame or when clicking + into a parent frame with the child frame selected and + `no-accept-focus' is not set, select the clicked + frame. */ + struct frame *hf = dpyinfo->highlight_frame; + + if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf))) + { + block_input (); + XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + RevertToParent, CurrentTime); + if (FRAME_PARENT_FRAME (f)) + XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); + unblock_input (); + } + } + +#ifdef USE_GTK + if (f && xg_event_is_for_scrollbar (f, event)) + f = 0; +#endif + + if (f) + { + /* Is this in the tab-bar? */ + if (WINDOWP (f->tab_bar_window) + && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window))) + { + Lisp_Object window; + int x = bv.x; + int y = bv.y; + + window = window_from_coordinates (f, x, y, 0, true, true); + tab_bar_p = EQ (window, f->tab_bar_window); + + if (tab_bar_p) + tab_bar_arg = handle_tab_bar_click + (f, x, y, xev->evtype == XI_ButtonPress, + x_x_to_emacs_modifiers (dpyinfo, bv.state)); + } + +#if ! defined (USE_GTK) + /* Is this in the tool-bar? */ + if (WINDOWP (f->tool_bar_window) + && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window))) + { + Lisp_Object window; + int x = bv.x; + int y = bv.y; + + window = window_from_coordinates (f, x, y, 0, true, true); + tool_bar_p = EQ (window, f->tool_bar_window); + + if (tool_bar_p && xev->detail < 4) + handle_tool_bar_click + (f, x, y, xev->evtype == XI_ButtonPress, + x_x_to_emacs_modifiers (dpyinfo, bv.state)); + } +#endif /* !USE_GTK */ + + if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) + if (! popup_activated ()) +#endif + { + if (ignore_next_mouse_click_timeout) + { + if (xev->evtype == XI_ButtonPress + && xev->time > ignore_next_mouse_click_timeout) + { + ignore_next_mouse_click_timeout = 0; + x_construct_mouse_click (&inev.ie, &bv, f); + } + if (xev->evtype == XI_ButtonRelease) + ignore_next_mouse_click_timeout = 0; + } + else + x_construct_mouse_click (&inev.ie, &bv, f); + + if (!NILP (tab_bar_arg)) + inev.ie.arg = tab_bar_arg; + } + if (FRAME_X_EMBEDDED_P (f)) + xembed_send_message (f, xev->time, + XEMBED_REQUEST_FOCUS, 0, 0, 0); + } + + if (xev->evtype == XI_ButtonPress) + { + dpyinfo->grabbed |= (1 << xev->detail); + device->grab |= (1 << xev->detail); + dpyinfo->last_mouse_frame = f; + if (f && !tab_bar_p) + f->last_tab_bar_item = -1; +#if ! defined (USE_GTK) + if (f && !tool_bar_p) + f->last_tool_bar_item = -1; +#endif /* not USE_GTK */ + + } + else + { + dpyinfo->grabbed &= ~(1 << xev->detail); + device->grab &= ~(1 << xev->detail); + } + + xi_grab_or_ungrab_device (device, dpyinfo, xev->event); + + if (f) + f->mouse_moved = false; + +#if defined (USE_GTK) + /* No Xt toolkit currently available has support for XI2. + So the code here assumes use of GTK. */ + f = x_menubar_window_to_frame (dpyinfo, event); + if (f /* Gtk+ menus only react to the first three buttons. */ + && xev->detail < 3) + { + /* What is done with Core Input ButtonPressed is not + possible here, because GenericEvents cannot be saved. */ + bool was_waiting_for_input = waiting_for_input; + /* This hack was adopted from the NS port. Whether + or not it is actually safe is a different story + altogether. */ + if (waiting_for_input) + waiting_for_input = 0; + set_frame_menubar (f, true); + waiting_for_input = was_waiting_for_input; + } +#endif + goto XI_OTHER; + } + case XI_KeyPress: + { + int state = xev->mods.base + | xev->mods.effective + | xev->mods.latched + | xev->mods.locked; + Lisp_Object c; +#ifdef HAVE_XKB + unsigned int mods_rtrn; +#endif + int keycode = xev->detail; + KeySym keysym; + char copy_buffer[81]; + char *copy_bufptr = copy_buffer; + unsigned char *copy_ubufptr; +#ifdef HAVE_XKB + int copy_bufsiz = sizeof (copy_buffer); +#endif + ptrdiff_t i; + int nchars, len; + +#ifdef HAVE_XKB + if (dpyinfo->xkb_desc) + { + if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode, + state, &mods_rtrn, &keysym)) + goto XI_OTHER; + } + else + { +#endif + int keysyms_per_keycode_return; + KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1, + &keysyms_per_keycode_return); + if (!(keysym = ksms[0])) + { + XFree (ksms); + goto XI_OTHER; + } + XFree (ksms); +#ifdef HAVE_XKB + } +#endif + + if (keysym == NoSymbol) + goto XI_OTHER; + + x_display_set_last_user_time (dpyinfo, xev->time); + ignore_next_mouse_click_timeout = 0; + +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) + /* Dispatch XI_KeyPress events when in menu. */ + if (popup_activated ()) + goto XI_OTHER; +#endif + + f = x_any_window_to_frame (dpyinfo, xev->event); + + /* If mouse-highlight is an integer, input clears out + mouse highlighting. */ + if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight) + && (f == 0 +#if ! defined (USE_GTK) + || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) +#endif + || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) + ) + { + clear_mouse_face (hlinfo); + hlinfo->mouse_face_hidden = true; + } + + if (f != 0) + { +#ifdef USE_GTK + /* Don't pass keys to GTK. A Tab will shift focus to the + tool bar in GTK 2.4. Keys will still go to menus and + dialogs because in that case popup_activated is nonzero + (see above). */ + *finish = X_EVENT_DROP; +#endif + /* If not using XIM/XIC, and a compose sequence is in progress, + we break here. Otherwise, chars_matched is always 0. */ + if (compose_status.chars_matched > 0 && nbytes == 0) + goto XI_OTHER; + + memset (&compose_status, 0, sizeof (compose_status)); + + XSETFRAME (inev.ie.frame_or_window, f); + inev.ie.modifiers + = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state); + inev.ie.timestamp = xev->time; + + /* First deal with keysyms which have defined + translations to characters. */ + if (keysym >= 32 && keysym < 128) + /* Avoid explicitly decoding each ASCII character. */ + { + inev.ie.kind = ASCII_KEYSTROKE_EVENT; + inev.ie.code = keysym; + + goto xi_done_keysym; + } + + /* Keysyms directly mapped to Unicode characters. */ + if (keysym >= 0x01000000 && keysym <= 0x0110FFFF) + { + if (keysym < 0x01000080) + inev.ie.kind = ASCII_KEYSTROKE_EVENT; + else + inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; + inev.ie.code = keysym & 0xFFFFFF; + goto xi_done_keysym; + } + + /* Now non-ASCII. */ + if (HASH_TABLE_P (Vx_keysym_table) + && (c = Fgethash (make_fixnum (keysym), + Vx_keysym_table, + Qnil), + FIXNATP (c))) + { + inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c)) + ? ASCII_KEYSTROKE_EVENT + : MULTIBYTE_CHAR_KEYSTROKE_EVENT); + inev.ie.code = XFIXNAT (c); + goto xi_done_keysym; + } + + /* Random non-modifier sorts of keysyms. */ + if (((keysym >= XK_BackSpace && keysym <= XK_Escape) + || keysym == XK_Delete +#ifdef XK_ISO_Left_Tab + || (keysym >= XK_ISO_Left_Tab + && keysym <= XK_ISO_Enter) +#endif + || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */ + || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */ +#ifdef HPUX + /* This recognizes the "extended function + keys". It seems there's no cleaner way. + Test IsModifierKey to avoid handling + mode_switch incorrectly. */ + || (XK_Select <= keysym && keysym < XK_KP_Space) +#endif +#ifdef XK_dead_circumflex + || keysym == XK_dead_circumflex +#endif +#ifdef XK_dead_grave + || keysym == XK_dead_grave +#endif +#ifdef XK_dead_tilde + || keysym == XK_dead_tilde +#endif +#ifdef XK_dead_diaeresis + || keysym == XK_dead_diaeresis +#endif +#ifdef XK_dead_macron + || keysym == XK_dead_macron +#endif +#ifdef XK_dead_degree + || keysym == XK_dead_degree +#endif +#ifdef XK_dead_acute + || keysym == XK_dead_acute +#endif +#ifdef XK_dead_cedilla + || keysym == XK_dead_cedilla +#endif +#ifdef XK_dead_breve + || keysym == XK_dead_breve +#endif +#ifdef XK_dead_ogonek + || keysym == XK_dead_ogonek +#endif +#ifdef XK_dead_caron + || keysym == XK_dead_caron +#endif +#ifdef XK_dead_doubleacute + || keysym == XK_dead_doubleacute +#endif +#ifdef XK_dead_abovedot + || keysym == XK_dead_abovedot +#endif + || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ + || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */ + /* Any "vendor-specific" key is ok. */ + || (keysym & (1 << 28)) + || (keysym != NoSymbol && nbytes == 0)) + && ! (IsModifierKey (keysym) + /* The symbols from XK_ISO_Lock + to XK_ISO_Last_Group_Lock + don't have real modifiers but + should be treated similarly to + Mode_switch by Emacs. */ +#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock + || (XK_ISO_Lock <= keysym + && keysym <= XK_ISO_Last_Group_Lock) +#endif + )) + { + STORE_KEYSYM_FOR_DEBUG (keysym); + /* make_lispy_event will convert this to a symbolic + key. */ + inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; + inev.ie.code = keysym; + goto xi_done_keysym; + } + +#ifdef HAVE_XKB + int overflow = 0; + KeySym sym = keysym; + + if (dpyinfo->xkb_desc) + { + if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, + state & ~mods_rtrn, copy_bufptr, + copy_bufsiz, &overflow))) + goto XI_OTHER; + } + else +#else + { + block_input (); + char *str = XKeysymToString (keysym); + if (!str) + { + unblock_input (); + goto XI_OTHER; + } + nbytes = strlen (str) + 1; + copy_bufptr = alloca (nbytes); + strcpy (copy_bufptr, str); + unblock_input (); + } +#endif +#ifdef HAVE_XKB + if (overflow) + { + overflow = 0; + copy_bufptr = alloca (copy_bufsiz + overflow); + keysym = sym; + if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, + state & ~mods_rtrn, copy_bufptr, + copy_bufsiz + overflow, &overflow))) + goto XI_OTHER; + + if (overflow) + goto XI_OTHER; + } +#endif + + for (i = 0, nchars = 0; i < nbytes; i++) + { + if (ASCII_CHAR_P (copy_bufptr[i])) + nchars++; + STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]); + } + + if (nchars < nbytes) + { + /* Decode the input data. */ + + setup_coding_system (Vlocale_coding_system, &coding); + coding.src_multibyte = false; + coding.dst_multibyte = true; + /* The input is converted to events, thus we can't + handle composition. Anyway, there's no XIM that + gives us composition information. */ + coding.common_flags &= ~CODING_ANNOTATION_MASK; + + SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, + nbytes); + coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; + coding.mode |= CODING_MODE_LAST_BLOCK; + decode_coding_c_string (&coding, (unsigned char *) copy_bufptr, + nbytes, Qnil); + nbytes = coding.produced; + nchars = coding.produced_char; + copy_bufptr = (char *) coding.destination; + } + + copy_ubufptr = (unsigned char *) copy_bufptr; + + /* Convert the input data to a sequence of + character events. */ + for (i = 0; i < nbytes; i += len) + { + int ch; + if (nchars == nbytes) + ch = copy_ubufptr[i], len = 1; + else + ch = string_char_and_length (copy_ubufptr + i, &len); + inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch) + ? ASCII_KEYSTROKE_EVENT + : MULTIBYTE_CHAR_KEYSTROKE_EVENT); + inev.ie.code = ch; + kbd_buffer_store_buffered_event (&inev, hold_quit); + } + + inev.ie.kind = NO_EVENT; + goto xi_done_keysym; + } + goto XI_OTHER; + } + case XI_KeyRelease: + x_display_set_last_user_time (dpyinfo, xev->time); + goto XI_OTHER; + case XI_PropertyEvent: + case XI_HierarchyChanged: + case XI_DeviceChanged: + x_init_master_valuators (dpyinfo); + goto XI_OTHER; + default: + goto XI_OTHER; + } + xi_done_keysym: + if (must_free_data) + XFreeEventData (dpyinfo->display, &event->xcookie); + goto done_keysym; + XI_OTHER: + if (must_free_data) + XFreeEventData (dpyinfo->display, &event->xcookie); + goto OTHER; + } +#endif default: OTHER: @@ -13199,6 +14253,40 @@ #define NUM_ARGV 10 dpyinfo->supports_xdbe = true; #endif +#ifdef HAVE_XINPUT2 + dpyinfo->supports_xi2 = false; + int rc; + int major = 2; +#ifdef XI_BarrierHit /* XInput 2.3 */ + int minor = 3; +#elif defined XI_TouchBegin /* XInput 2.2 */ + int minor = 2; +#elif defined XIScrollClass /* XInput 1.1 */ + int minor = 1; +#else /* Some old version of XI2 we're not interested in. */ + int minor = 0; +#endif + int fer, fee; + + if (XQueryExtension (dpyinfo->display, "XInputExtension", + &dpyinfo->xi2_opcode, &fer, &fee)) + { + rc = XIQueryVersion (dpyinfo->display, &major, &minor); + if (rc == Success) + { + dpyinfo->supports_xi2 = true; + x_init_master_valuators (dpyinfo); + } + } + dpyinfo->xi2_version = minor; +#endif + +#ifdef HAVE_XKB + dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display, + XkbAllComponentsMask, + XkbUseCoreKbd); +#endif + #if defined USE_CAIRO || defined HAVE_XFT { /* If we are using Xft, the following precautions should be made: @@ -13631,6 +14719,14 @@ x_delete_terminal (struct terminal *terminal) XrmDestroyDatabase (dpyinfo->rdb); #endif +#ifdef HAVE_XKB + if (dpyinfo->xkb_desc) + XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); +#endif +#ifdef HAVE_XINPUT2 + if (dpyinfo->supports_xi2) + x_free_xi_devices (dpyinfo); +#endif #ifdef USE_GTK xg_display_close (dpyinfo->display); #else @@ -13790,9 +14886,12 @@ x_initialize (void) void init_xterm (void) { - /* Emacs can handle only core input events, so make sure - Gtk doesn't use Xinput or Xinput2 extensions. */ +#ifndef HAVE_XINPUT2 + /* Emacs can handle only core input events when built without XI2 + support, so make sure Gtk doesn't use Xinput or Xinput2 + extensions. */ xputenv ("GDK_CORE_DEVICE_EVENTS=1"); +#endif } #endif diff --git a/src/xterm.h b/src/xterm.h index 9d9534dd62..7abe168bc6 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -88,6 +88,10 @@ #define XSync(d, b) do { gdk_window_process_all_updates (); \ #include #endif +#ifdef HAVE_XKB +#include +#endif + #include "dispextern.h" #include "termhooks.h" @@ -163,6 +167,28 @@ #define MAX_CLIP_RECTS 2 char *name; }; +#ifdef HAVE_XINPUT2 +struct xi_scroll_valuator_t +{ + bool invalid_p; + double current_value; + double emacs_value; + double increment; + + int number; + int horizontal; +}; + +struct xi_device_t +{ + int device_id; + int scroll_valuator_count; + int grab; + + struct xi_scroll_valuator_t *valuators; +}; +#endif + Status x_parse_color (struct frame *f, const char *color_name, XColor *color); @@ -474,6 +500,19 @@ #define MAX_CLIP_RECTS 2 #ifdef HAVE_XDBE bool supports_xdbe; #endif + +#ifdef HAVE_XINPUT2 + bool supports_xi2; + int xi2_version; + int xi2_opcode; + + int num_devices; + struct xi_device_t *devices; +#endif + +#ifdef HAVE_XKB + XkbDescPtr xkb_desc; +#endif }; #ifdef HAVE_X_I18N @@ -481,6 +520,11 @@ #define MAX_CLIP_RECTS 2 extern bool use_xim; #endif +#ifdef HAVE_XINPUT2 +/* Defined in xmenu.c. */ +extern int popup_activated_flag; +#endif + /* This is a chain of structures for all the X displays currently in use. */ extern struct x_display_info *x_display_list; -- 2.31.1 --=-=-= Content-Type: text/plain And here is the patch that exposes pixel deltas to Lisp: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Expose-pixel-wise-wheel-events-to-Lisp.patch >From aee86e1d2f94dff95644a817cad072a1de9a88bf Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 16 Nov 2021 19:39:50 +0800 Subject: [PATCH 2/2] Expose pixel-wise wheel events to Lisp * doc/lispref/commands.texi (Misc Events): Document changes to wheel events. * src/keyboard.c (make_lispy_event): Handle wheel events with pixel delta data. * src/termhooks.h (WHEEL_EVENT): Document changes to WHEEL_EVENT args. * src/xfns.c (syms_of_xfns): Declare new symbols. * src/xterm.c (handle_one_xevent): Give wheel events pixel delta data. --- doc/lispref/commands.texi | 6 +++++- src/keyboard.c | 5 ++++- src/termhooks.h | 7 ++++++- src/xfns.c | 3 +++ src/xterm.c | 13 +++++++++++-- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 1509c200e0..be0f4189ee 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1985,7 +1985,11 @@ Misc Events These kinds of event are generated by moving a mouse wheel. The @var{position} element is a mouse position list (@pxref{Click Events}), specifying the position of the mouse cursor when the event -occurred. +occurred. The event may have additional arguments after +@var{position}. The third argument after @var{position}, if present, +is a property list of the form @w{@code{(:delta-x @var{x} :delta-y +@var{y})}}, where @var{x} and @var{y} are the number of pixels to +scroll by in each axis. @vindex mouse-wheel-up-event @vindex mouse-wheel-down-event diff --git a/src/keyboard.c b/src/keyboard.c index de9805df32..276fd8c5aa 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5980,7 +5980,10 @@ make_lispy_event (struct input_event *event) ASIZE (wheel_syms)); } - if (NUMBERP (event->arg)) + if (CONSP (event->arg)) + return list5 (head, position, make_fixnum (double_click_count), + XCAR (event->arg), XCDR (event->arg)); + else if (NUMBERP (event->arg)) return list4 (head, position, make_fixnum (double_click_count), event->arg); else if (event->modifiers & (double_modifier | triple_modifier)) diff --git a/src/termhooks.h b/src/termhooks.h index e7539bbce2..43a9fc2f22 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -119,7 +119,12 @@ #define EMACS_TERMHOOKS_H .timestamp gives a timestamp (in milliseconds) for the event. .arg may contain the number of - lines to scroll. */ + lines to scroll, or a list of + the form (NUMBER-OF-LINES . + (:DELTA-X :DELTA-Y Y)) where + DELTA-X and DELTA-Y are the number + of pixels on each axis to scroll + by. */ HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ diff --git a/src/xfns.c b/src/xfns.c index b33b40b330..9d70ba479b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -8085,6 +8085,9 @@ syms_of_xfns (void) #ifdef HAVE_XINPUT2 DEFSYM (Qxinput2, "xinput2"); + DEFSYM (QCdelta_x, ":delta-x"); + DEFSYM (QCdelta_y, ":delta-y"); + Fprovide (Qxinput2, Qnil); #endif diff --git a/src/xterm.c b/src/xterm.c index 63754a2cb6..6eb361efca 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9935,7 +9935,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, block_input (); struct xi_scroll_valuator_t *val; - double delta; + double delta, scroll_unit; delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, i, *values, &val); @@ -9943,6 +9943,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (delta != DBL_MAX) { f = mouse_or_wdesc_frame (dpyinfo, xev->event); + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); found_valuator = true; if (signbit (delta) != signbit (val->emacs_value)) @@ -9975,7 +9976,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.modifiers |= x_x_to_emacs_modifiers (dpyinfo, xev->mods.effective); - inev.ie.arg = Qnil; + + if (val->horizontal) + inev.ie.arg = list5 (Qnil, QCdelta_x, + make_float (delta * scroll_unit), + QCdelta_y, make_float (0)); + else + inev.ie.arg = list5 (Qnil, QCdelta_x, make_float (0), + QCdelta_y, + make_float (delta * scroll_unit)); kbd_buffer_store_event_hold (&inev.ie, hold_quit); -- 2.31.1 --=-=-= Content-Type: text/plain WDYT? Thanks. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Tue Nov 16 08:40:06 2021 Received: (at 51891) by debbugs.gnu.org; 16 Nov 2021 13:40:06 +0000 Received: from localhost ([127.0.0.1]:57537 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mmygv-0006XW-NC for submit@debbugs.gnu.org; Tue, 16 Nov 2021 08:40:06 -0500 Received: from mail-wm1-f41.google.com ([209.85.128.41]:38625) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mmygt-0006Wh-Ko for 51891@debbugs.gnu.org; Tue, 16 Nov 2021 08:40:04 -0500 Received: by mail-wm1-f41.google.com with SMTP id p3-20020a05600c1d8300b003334fab53afso1998340wms.3 for <51891@debbugs.gnu.org>; Tue, 16 Nov 2021 05:40:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-transfer-encoding; bh=dhaTAwb/9fC7kbT6EnbrX/9PiwPvlEJDHDaig9aQe0c=; b=gT9fGxyMcrjdcpr86wAAwXdiW/kEtVkBrlnOs7uqk977+9dmUvBBCtz3VawoEAZDv6 RmcxC9QxSH2MKXzcb0azLFRY/v/aleVf4d1B3BX+i0OjYFfgO2T/qDl9Jkq0+R7zYDXT 5zd1ZaWjv4ve0rH0ax6cCLmv3wN/Do+/yPpMJPuR7vi0er1h9B9r/vMePQj+vg1wPXA7 ZHNyAPqBU/S/pu4RgokM2+6bDASSVwBVamN35xWpfR8SgKnGTiI3ukw1E2gUYB/SeaEc VYaFvVTF1hPfKFvhYByZ79xII3VfMci4XQ9MIQ77t2Be87rrgFdKOM2fzVDRGtDUKBKI G7Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:mime-version:content-transfer-encoding; bh=dhaTAwb/9fC7kbT6EnbrX/9PiwPvlEJDHDaig9aQe0c=; b=vRJiQqyvr1ZXmNr9C65L/c4Cs3KGs/EJRHfTtj0vO2sVNaWq/uXzgrvUKQDiF53Zrx Rf08lJWq0R2AOCvZTwaYlq9Bmqn7FlkN8tk39KHiYegxYo/vu5XMWfP/zECjA1JoFqcM xr49DdEU+qi5Lc55vG4VAPCKaCw1CemnpzM3SqpRHKaVEphZiKMkEBqdUiMokBSbxfYq Wy2B/u1SuFm77lafmz1Er88CoJ4GV5IakKjeJNtWFANA5PPG6f4MEuiahRaGL/v10t7r XPBC1qpfYP/XxpNhNh8wGBDOHDTzy3GFNi2oP5Q92MKbKXj2cdwC8viDEbQKysfC2X2U 9oqg== X-Gm-Message-State: AOAM533iwTRIkYCrPg4pL4vEqsrz1Bm/i56sMH1exxfuTKTTfHEIjkRL pfUCEf+UcIZNvRjf2w34KWo= X-Google-Smtp-Source: ABdhPJwW6qBaVblOEboT95hM2Bwh5wjBRsEsbDDaBKf/hbqEDwgv80U0eiV8t8gYUDd1HnCizxKPXA== X-Received: by 2002:a7b:c388:: with SMTP id s8mr68706741wmj.170.1637069997501; Tue, 16 Nov 2021 05:39:57 -0800 (PST) Received: from rltb ([2a01:e0a:3f3:fb50:96da:7a41:4cc2:4c20]) by smtp.gmail.com with ESMTPSA id n13sm17751101wrt.44.2021.11.16.05.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Nov 2021 05:39:57 -0800 (PST) From: Robert Pluim To: 51891@debbugs.gnu.org Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> Date: Tue, 16 Nov 2021 14:39:56 +0100 In-Reply-To: <87zgq4uvh0.fsf@yahoo.com> (Po Lu via's message of "Tue, 16 Nov 2021 20:38:03 +0800") Message-ID: <871r3gnrrn.fsf@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: Po Lu X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >>>>> On Tue, 16 Nov 2021 20:38:03 +0800, Po Lu via "Bug reports for GNU Em= acs, the Swiss army knife of text editors" said: Po> +occurred. The event may have additional arguments after Po> +@var{position}. The third argument after @var{position}, if prese= nt, Po> +is a property list of the form @w{@code{(:delta-x @var{x} :delta-y Po> +@var{y})}}, where @var{x} and @var{y} are the number of pixels to Po> +scroll by in each axis. Is there really a need for this to be a plist with :delta-x and :delta-y in it? Just a cons of x and y would work. Po> @vindex mouse-wheel-up-event Po> @vindex mouse-wheel-down-event Po> diff --git a/src/keyboard.c b/src/keyboard.c Po> index de9805df32..276fd8c5aa 100644 Po> --- a/src/keyboard.c Po> +++ b/src/keyboard.c Po> @@ -5980,7 +5980,10 @@ make_lispy_event (struct input_event *event) Po> ASIZE (wheel_syms)); Po> } =20 Po> - if (NUMBERP (event->arg)) Po> + if (CONSP (event->arg)) Po> + return list5 (head, position, make_fixnum (double_click_count), Po> + XCAR (event->arg), XCDR (event->arg)); Po> + else if (NUMBERP (event->arg)) Po> return list4 (head, position, make_fixnum (double_click_= count), event-> arg); Po> else if (event->modifiers & (double_modifier | triple_modifier)) Po> diff --git a/src/termhooks.h b/src/termhooks.h Po> index e7539bbce2..43a9fc2f22 100644 Po> --- a/src/termhooks.h Po> +++ b/src/termhooks.h Po> @@ -119,7 +119,12 @@ #define EMACS_TERMHOOKS_H Po> .timestamp gives a timestamp (in Po> milliseconds) for the event. Po> .arg may contain the number of Po> - lines to scroll. */ Po> + lines to scroll, or a list of Po> + the form (NUMBER-OF-LINES . Po> + (:DELTA-X :DELTA-Y Y)) where Po> + DELTA-X and DELTA-Y are the number Po> + of pixels on each axis to scroll Po> + by. */ I don=CA=BCt think this is quite right. The 'X' is missing, and it=CA=BCs '= X' and 'Y' that give the number of pixels. And :delta-x and :delta-y (lowercase). Po> HORIZ_WHEEL_EVENT, /* A wheel event generated by a se= cond Po> horizontal wheel that is presen= t on some Po> mice. See WHEEL_EVENT. */ Po> diff --git a/src/xfns.c b/src/xfns.c Po> index b33b40b330..9d70ba479b 100644 Po> --- a/src/xfns.c Po> +++ b/src/xfns.c Po> @@ -8085,6 +8085,9 @@ syms_of_xfns (void) =20 Po> #ifdef HAVE_XINPUT2 Po> DEFSYM (Qxinput2, "xinput2"); Po> + DEFSYM (QCdelta_x, ":delta-x"); Po> + DEFSYM (QCdelta_y, ":delta-y"); Po> + Po> Fprovide (Qxinput2, Qnil); Po> #endif =20 Po> diff --git a/src/xterm.c b/src/xterm.c Po> index 63754a2cb6..6eb361efca 100644 Po> --- a/src/xterm.c Po> +++ b/src/xterm.c Po> @@ -9935,7 +9935,7 @@ handle_one_xevent (struct x_display_info *dpy= info, Po> block_input (); =20 Po> struct xi_scroll_valuator_t *val; Po> - double delta; Po> + double delta, scroll_unit; =20 Po> delta =3D x_get_scroll_valuator_delta (dpyinfo, xev->devicei= d, Po> i, *values, &val); Po> @@ -9943,6 +9943,7 @@ handle_one_xevent (struct x_display_info *dpy= info, Po> if (delta !=3D DBL_MAX) Po> { Po> f =3D mouse_or_wdesc_frame (dpyinfo, xev->event); Po> + scroll_unit =3D pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); Po> found_valuator =3D true; =20 Po> if (signbit (delta) !=3D signbit (val->emacs_value)) Po> @@ -9975,7 +9976,15 @@ handle_one_xevent (struct x_display_info *dp= yinfo, Po> inev.ie.modifiers Po> |=3D x_x_to_emacs_modifiers (dpyinfo, xev-> mods.effective); Po> - inev.ie.arg =3D Qnil; Po> + Po> + if (val->horizontal) Po> + inev.ie.arg =3D list5 (Qnil, QCdelta_x, Po> + make_float (delta * scroll_unit), Po> + QCdelta_y, make_float (0)); Po> + else Po> + inev.ie.arg =3D list5 (Qnil, QCdelta_x, make_float (0), Po> + QCdelta_y, Po> + make_float (delta * scroll_unit)); So the :delta-y value is always 0 when :delta-x is non-zero and vice versa? Why bother to return both then? (and why floats and not ints?). Robert --=20 From debbugs-submit-bounces@debbugs.gnu.org Tue Nov 16 19:34:58 2021 Received: (at 51891) by debbugs.gnu.org; 17 Nov 2021 00:34:58 +0000 Received: from localhost ([127.0.0.1]:59462 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mn8ug-0001fG-H1 for submit@debbugs.gnu.org; Tue, 16 Nov 2021 19:34:58 -0500 Received: from sonic314-21.consmr.mail.ne1.yahoo.com ([66.163.189.147]:32877) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mn8ue-0001ey-6u for 51891@debbugs.gnu.org; Tue, 16 Nov 2021 19:34:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637109290; bh=5wiJZfi+jbmhi5J+Of0AER75wjopNYwX0pdUt4CbgXc=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=S8+uUng1uAc3CykBCXoftmoaJtd4BVmqL1vr09i+2R2ichMvtqZIAJ5QG/TPWWuoMhkyFqXGHOjAqxXyYGULFdJZI7g8fkh28vfbwX9TPUI/8RhR65neoKEhgNeCRW7SItPU00h+yEOCl/6OZI5ktM/4F5y8J/N9Ili1NtNWm6Mi19VjwOCYSF6iwj77Qc/Y4F0EjFZ56vPxFkn3lr39rfvK1G7RV7eHgjUFBJDyVlUXjcMrZlet87pBwVTKUuVTZejc6GiOVLmtAfGynWqPGFfyB7ACfBtL+l9268h3kzJ6OQyP/+AF4u4K8wRrTwHyAYI7LmnV5CRkxo/VUOvJIQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637109290; bh=LIgw3kUa1paP/kuoPFfgwNbYuJQ29OKD5j0XDbhVayc=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=uflMONsjv3FwgnVl7ZDdPSQV3gzUXMagoAPXWE/tHQWRAQIDgQ7HAfB0b8nVaMAkw6fz+qP7t+HYGw23EiG17ExzMnIHW41iMyppZzFxGl889LSlPsIRLJ3eHTnQRs7IPGw7g47Pr0wQA9Wi+8SLBmrNpQOIG+UJHWCYzUM0hJR7AoCyXV+ncQeCLKijDC6JkaHJUwqsMdxkwDwX914y7eUFr0V1WxVkScygmsjqFVJZaml8dS2mZivCsO6olZYSLT6a+0yms3/vlcMN8ZaJveNUcZNMLfKoxoPUDCZxYBXEMV2y6kyVo5/j5hgm4ZEHfgm55WxZXQe9bhozhjbYNA== X-YMail-OSG: AKsw5tMVM1mNHmVm98avOF8cS5doinimVRAoOq77o_aUbtUC7Kem3XGoV92i6xL Hib0UsuJ57AJL8M67AN8T4CW2mY7XRhi0hQQ4o2TORtsqQoJojkEcEeAboObydGS342fdlEZeiap NfF6Wmoekq6Xa7SZjuZ0ZsxU3zO6hm03aKr0qBs5fhDGmj5gH6VmO8vYRGSyQkRzIbYxKuWNBnWq ZFedyzd6o4Pj0ZMGGnfkyhEXYD5xBZ8Gn6XwIVGzyiynZdZ98gfQ_OL7GXmpoZ8rWtYDFh74oFkR wIEyn5K0agnQwlzGcHFg_bxHho5cCOq4AuYVqM8iDmBK_lxxv.R.9TGYFPZXBEkxux0l_VOU92y5 Jjo01cpDjq4raJ6.j.jULwa.qfsC.xcXMcueQndbjz5lkXNom3Qws1XBAXkQwIgvuXy34ZDTgMVr .Vhqp38Hl52cTQljPuRuTjlAp3J91yxjgNgybsYdCh6OgZT0EDWfnQv6uTZyrbhkHXyR08fFcmjp _PPtPlPnj8MSxuj.t7zgxEsryUw2pQ55ZqZFTUWIVp_iKihH7cJaORYldRO8EGn._Hxg9UZVAQnR om0StbqOiKLwl2q.CFqnT.LHdQUOuN3gLhCxSCna4k1s5NgxHCOGoWpuQ5qRWcz9nF6cWsecxUcs jCsLwQ8bnMcKEY0YQPMy_TckrjmF8Pun5bNKsDp_JjmRj5SetrQ8rGbjoXZqHPaq5VulO2PV8ToZ aKF7A2MxnLT9SE0qY.WrQdlaIoEPU668jtBnVeWp3FdLVu1XzV.7y89u098KY1E2PAx..GJFtOe8 DGRYzFnPTVYSJsrSeJTzxaJjlaao1FL8V1wGckc6CFIoP8VyYzV9x3AC93xLe6TllfjjFw1UnhGo o3BoA__xgGWQcpwa9l4ZUKa_Tcsf0COKoe3oNLwtMQXerGWo6QN3hoiehEn_XCyvWqFjM_ag4vlJ tQJ5Xr6zQ9SvVy1I5L6m.ySHaMZ19398Sm5BwenR.uC6dN69BvickC38GxTvJtNbEbFWLRbqjuOb 1nc.wLQkI2npgWrMyKVckMFiX.W1oDQkRtBF5TIG683feO57JGSw3kjth_2RKVWvHgBaarUXO3bK 51avdei5dtXTWTAO6pG.Xgq23lLC_ELxwZlMf371Rmedf5vaKIaK0PQ6IIsu009WYxOF89PqIoZv GvqnDWOdQegCT9KaopdgvmDAD.52kXIaUz5hXdX9xy1_YHUfvVI6G3EfbZ2I_xKs0WwveA_4enh1 1G95sC1Q.2OA.JZuESTchzygG2oME2ya2LD9HW1MduHI3lzu94SDeQeKGiicmIw7roP_NdoBCrVU E6f6q6eDHB3FJ_7qaNHekqXjBzyx3AAwQwLelNP7hLIaNpw90jqpiO17jSqjCMm2p3XDhirjMZkD P5zwQKRdL_Q.rM6hjV36DC4HYeqPJEj6FZp5FwBEERSmInPC2nXlyB29nvyniteS9jbNtIgvBBNY NfWLi_nnJHpSye0ivVucNa5yQDws3NgpFJbPO5gAqSvPs4w1uH536YCdnQUNhZZE0gzk_0Dkucge X5fOx2LUFaFgkIxlSLlRyG9sYvZRf8_dZE1mqtZzJUOTNJphzWx7dnzgMgQjg1wW2AFbbu6Uf2vb opnF97AEgGCyVp20L6Wa5zayrHMG5HkVTp9VmRJx0Gupa7TJEPoRwDD4SkQtRkDAuEJ.T7pSN1WL s6VDk9922NfljurOg.NMpYIupbQKUz0mqnb3YGhLLq8aJGJEVgRT86MPRe6w9m3uh2.A5qtG3G2h gmUlzVrZivgRu9iV5c2fjNHf0zYpiJEFZFyCZXf7GSVxVbHqG6vWqCYkhI.6DM481Bvg9XJnbpei bYvXcvRxkSj6rADuM0xyEvXSxzK__KI5ku7ta1jF0sE_gU6tT9E8xDP4MQXvfTRHUchfAai1XqhK EfR05VnS0LOwikBS_ny_L_5guBo7N9O85q0D9tHKaomh.z4YIQ2QLJN.EhflrPlH9Gf249DeeG_B xk2ACHWvraZ0aD.GfWMc4Kn22iEzeZuEQE3Ne3LkGAnh79FH866G3VwEg8mORenMXhJtxe4IfjGt f0.v5ACVGA9IxRwsYENOcAs5nSqWRCFLEx48AUfXteDpIki54aKsEbtal1qea5HN2CNqTAIV7oKJ SnBH0IdOiFmtagdnLBCK.pNp1br1TY3jGebmqyGsM2SM77EK1WaHprg8Y1na1V5RtAMo9ysMmUu6 aCB8JeYKp_ZQ2RoGS2sSPz1scx_A_cSRBuYCsgwRRb.0DCeiztAdnIVNsjD2x X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Wed, 17 Nov 2021 00:34:50 +0000 Received: by kubenode511.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 61637422c20cbd548b74e57a2b12ef5c; Wed, 17 Nov 2021 00:34:46 +0000 (UTC) From: Po Lu To: Robert Pluim Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> Date: Wed, 17 Nov 2021 08:34:43 +0800 In-Reply-To: <871r3gnrrn.fsf@gmail.com> (Robert Pluim's message of "Tue, 16 Nov 2021 14:39:56 +0100") Message-ID: <875ysrtyak.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 994 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Robert Pluim writes: > Is there really a need for this to be a plist with :delta-x and > :delta-y in it? Just a cons of x and y would work. Yes, what if other window systems decide to expose different values to Lisp code? Such as for example, the phase of the scroll. > I don=CA=BCt think this is quite right. The 'X' is missing, and it=CA=BCs= 'X' > and 'Y' that give the number of pixels. And :delta-x and :delta-y > (lowercase). Thanks, I fixed that on my side. > So the :delta-y value is always 0 when :delta-x is non-zero and vice > versa? Why bother to return both then? (and why floats and not ints?). Because other systems (such as GDK) have different methods of reporting scroll deltas. While it makes sense in the context of the XInput 2 code to report them one at a time, it does not in the context of GDK, as it reports both deltas to Emacs at the same time. Which means the pure GTK port will report both delta-y and delta-x at the same time. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Tue Nov 16 21:39:00 2021 Received: (at 51891) by debbugs.gnu.org; 17 Nov 2021 02:39:00 +0000 Received: from localhost ([127.0.0.1]:59549 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnAqh-0006Cy-VV for submit@debbugs.gnu.org; Tue, 16 Nov 2021 21:39:00 -0500 Received: from sonic316-21.consmr.mail.ne1.yahoo.com ([66.163.187.147]:45176) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnAqf-0006Cd-87 for 51891@debbugs.gnu.org; Tue, 16 Nov 2021 21:38:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637116730; bh=JpDzfOpurw8F7jDKFbbB7BkiDp4ZJZbs//3ho9RYvm8=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=THwuBC350ranUaLSY564xLvOdc7N8L0yiDGN1tj+jZFTev1YNJiL9GBs2BKizR+bCkhKZy3OyAmmCOUUCJ0kw27I3wvdrwxx7qAop1YIa04sZWE1YWsmggt/d068z6fM9/y+VqqTc2CkxBYrJ1eVuNz48d995bWr6IGCYUkmBTK0De1LQ19DZ7973CGvfMHOFZBLBOtzAwLisrsx945LUast3yfumiqQWl4s43PiShBVoknVz5X5HHA3PCzzkYTTDwh8t6R4qBAXvi+wcpz0Nxk3UEvE3YnSsbrcRQ3YSwXapcgIitUlSKqWA0644xXOpmHmew7LeurbZh2lPHu59A== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637116730; bh=5t0a9wTOirYVa537+qMSNRVKd3N+/zkjI7p7JnsVEwP=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=WDezmBjSNxgxlL5CYGq2Y48WaAb21FKxJSog/gDpH/LGvL10+JputPkoERLfAO8VEIDUzhvj4KGXnxIcX8iuwIJJGMULtryGZWlzuNjEplUAGaBu09OKujR8ucLKDrawE5++EZE3VQkJvVDQ3SGzC32OY2Jk9PoyaWXP97hirZkvz1AKHXEY1ugcXEnOe5kSXzEUg6F4JtGRllDHiK96BwtafDiG3FtaJXU3xiSK4L+jMWBgCvc1KN0g5ISvaVwkBDq1Rv6foxf5/vP1CpmWutcqdNuxQdC5OoIRfYvCbZx8FIoe1I7TsSAxFndcAvN8aqfzd/65/u2aWwFEutJNhw== X-YMail-OSG: 3fEopFIVM1mSGyF4HW9GJO9lzi0kMl.3S_YUMLvMlBwAzb8HyR30lTtbSumBha3 hg_bJk2pq1Ap.XSn8Yhg4TTFeESLy81VeyNKjgGB_mf1Pd_mxNXGzw0QAQZ3uWgleZRdy36wcPqj mXIL3.ZmTHm7pH1GGVtepHvT_N7kTGVrzVsu.L_IFTV0EgJiItW9zmOIzTrdmGRQrUUKiGD5r0Fr Iy7mMWjoaCz0j2zMWAS4iReKe7eIW8vVpRMoK0ciF_9gaPhVnggoTx65uL5BLn4jct.7VCLn..Sm k4EVc1Q1rgocvNG3iwxfRSMkdr3YeAN_j5J0EszJQaJq7dKY71pskdI9FamnN7B6Ur9m0WWlFLq2 XNAOV6XBJilLAJcNN0JfPaD.jAPw0_bmu27VgVJ5xuWVpH0JtaTiCYvT04SjIwo7Al1ogKHKvgdw eFrjlF0fIjCXp4rbG3kJEzF_Ao2p2ARkhp_gz3aNyERVv7omsNB9Afj7iTFEO66zcNvtc_UrlYqK 4dWjMSlrU1EUWvT26QJIYS_LAyu.iubTcSmz5QTotql1GW52naYBFUJ3eAnnrL7KxeeZWMITo5HR BNhYAwwd8.R3z_HI6W6QzVf17DTJ0z3dVPc7hDLJUCOtUy2ZV33jEGJbwDgetN6CHnOCX0aB_cPu K3KVeKc1rM64wnLl.W6E05bdm143Fqc5k5ErrP8Ny_NonRYYAL.rmAxhm5429f3LD50orvEaTHjz OxCJyKknL_sBH4cAzewxndokAr9.7Yrpi4i1CY.Wo1Aof9yZgDWAaVKc4v0XT6KTTqDcCWNSfDbQ DDi1N9T_mO6LkwNTvFNu4Mj_Eu29n4YnvuuiIoyv1W3Y3MJV8w7vZHm04SPQJ3B6pUZ7qrMLyreb TS3EAXUrsOPJUcaybVJmwNNpFSeoqX62E.tpg9OAZ9cD1V0jRCMGWXiTEOVRq8UC6TmKeADE4jpM dFN2FJmcyltVTrycDQf_jfC.e56WXBSTisa7V0rBD6h3cePrGl8ueSyjSHcTkquXrLwjqSJkylJl orwg0vd8XI4LsLp2e2IYbULSjfUUNdJfwmIDIP9b55S07q_a0NB9iTVV3k_jLeG_D3.ch6wSnyhS rcm8n64Dz4pqAtE1tIMV4WAbmJkIAZOziWhdMI2Rd2SNDoRgREgQ0Y0xN__Jtcxm02cu9QWqKoFJ JFyOUeFNchc_qkmp0mqKCbHvTKtQKH4eXboCkwwYwQjxHk4hVugZ2lGMMJI207Uzwsjp_zS0AwSN cMkNV8QHClLnQ5DTm_dTVDmnUytLsoCP_w8Xt9RYiQIIw2GvBxxVE1iTN5CoQFINw1zTRJQZThfX T4Lljiho._SnfN3ERfBSdSZN7Kb3CDkKoUxbaw1zM88nmsA0jjrUu.kG5qVO3CzTWv.2hKZqo8WP m1ZoRCNir_kp5scgyTQRUgzB_ZNXYMyBhvnYiBTNGFqw5p9L4RgMzk.E7jmbWa1AHleFocD6eakx vlXW076Mi3miEg7kq9DH_JS7Hm6VQOVmDhfejfRJANAJZ8imI_H7mYWGOa.o1g50LSYwrYLSKM7g fomL0qTlAkLsgkKbmDvo5xSSXWjWvOgvUDo6zmS5IJV5Lk8lBmqyQj2wbzMbX4K8fL2OK5cIHzw0 M13urfuzj1fmBC.aTm1LKn4IndcXfi0vqnh6KgbY7AAjG7myQCDcwcZMY_2yeWOaYYflTyqSVeDP NIwYgb9bnnyGL9m8_DJqmKkX1DTN2DrS4nQswftpj.7xKI27QujLNg7RbIUsGZyo.IWlwQLOaoGE cZ_fO4UPXzyqXka1IDOQSh6tm8ub0KX7a8JdHr.RXS4eOvKrdneKwCoSLGeGy73ivN.wuGwfJ82p 78fy_aIXCTXo9cWThxnsCWkaGkykMVU9Ups_FXaXxCcU.R52SuNk.gskwTT8SPp_f9hEdLDPbMWk LmLTkbZbNMhdaufwdAkMJwfWXRnHWLxVSPYaDtaoY28P6Wu6eC74_UxkgmgFpJ._yIUEmiDh9ONg 6CWwKWbUtYyu6X3ZfM9W7uI1L.DjzZze8K6fobSyK4oLDeN4poyIM.ObbbETNOmddgC.K1JhYAdM 9TGen7EnEEHgavCCK7cDgZLWRSC8Ij61FhQ5LLEkICu78n7IySqFNEYwt4kNF9FStMYm19iuhmsa GQQErWAzh4cato.edz_Y9SMUJw1O1fBxlF1TL1R4eVmK_l1ofzJyFRnXguCK9X.ml6tICLBVvSNE m7YBtGwQ9G7i0tlfyAVFd8bZ3VZJD.Jdv5MFgwjHCxN4qZ.vGmrzWyH4fE_g- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Wed, 17 Nov 2021 02:38:50 +0000 Received: by kubenode503.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID a290314d9739565ad69e7ca72bd7cdf8; Wed, 17 Nov 2021 02:38:46 +0000 (UTC) From: Po Lu To: Robert Pluim Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> Date: Wed, 17 Nov 2021 10:38:41 +0800 In-Reply-To: <875ysrtyak.fsf@yahoo.com> (Po Lu's message of "Wed, 17 Nov 2021 08:34:43 +0800") Message-ID: <871r3ftsjy.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 7099 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Po Lu writes: > Because other systems (such as GDK) have different methods of reporting > scroll deltas. While it makes sense in the context of the XInput 2 code > to report them one at a time, it does not in the context of GDK, as it > reports both deltas to Emacs at the same time. > > Which means the pure GTK port will report both delta-y and delta-x at > the same time. > > Thanks. And here's a new version of the patch with the fixes to documentation, and an extra option to prevent motion events from being sent too rapidly. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Expose-pixel-wise-wheel-events-to-Lisp.patch >From cf9a4a28cd44077e7682c0deccda9d1fbc98344d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 16 Nov 2021 19:39:50 +0800 Subject: [PATCH 2/2] Expose pixel-wise wheel events to Lisp * doc/lispref/commands.texi (Misc Events): Document changes to wheel events. * src/keyboard.c (make_lispy_event): Handle wheel events with pixel delta data. * src/termhooks.h (WHEEL_EVENT): Document changes to WHEEL_EVENT args. * src/xfns.c (syms_of_xfns): Declare new symbols. * src/xterm.c (handle_one_xevent): Give wheel events pixel delta data. (x_coalesce_scroll_events): New user option. --- doc/lispref/commands.texi | 6 +++++- src/keyboard.c | 5 ++++- src/termhooks.h | 6 +++++- src/xfns.c | 3 +++ src/xterm.c | 37 ++++++++++++++++++++++++++----------- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 1509c200e0..be0f4189ee 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1985,7 +1985,11 @@ Misc Events These kinds of event are generated by moving a mouse wheel. The @var{position} element is a mouse position list (@pxref{Click Events}), specifying the position of the mouse cursor when the event -occurred. +occurred. The event may have additional arguments after +@var{position}. The third argument after @var{position}, if present, +is a property list of the form @w{@code{(:delta-x @var{x} :delta-y +@var{y})}}, where @var{x} and @var{y} are the number of pixels to +scroll by in each axis. @vindex mouse-wheel-up-event @vindex mouse-wheel-down-event diff --git a/src/keyboard.c b/src/keyboard.c index de9805df32..276fd8c5aa 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5980,7 +5980,10 @@ make_lispy_event (struct input_event *event) ASIZE (wheel_syms)); } - if (NUMBERP (event->arg)) + if (CONSP (event->arg)) + return list5 (head, position, make_fixnum (double_click_count), + XCAR (event->arg), XCDR (event->arg)); + else if (NUMBERP (event->arg)) return list4 (head, position, make_fixnum (double_click_count), event->arg); else if (event->modifiers & (double_modifier | triple_modifier)) diff --git a/src/termhooks.h b/src/termhooks.h index e7539bbce2..19a6cc82da 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -119,7 +119,11 @@ #define EMACS_TERMHOOKS_H .timestamp gives a timestamp (in milliseconds) for the event. .arg may contain the number of - lines to scroll. */ + lines to scroll, or a list of + the form (NUMBER-OF-LINES . + (:delta-x :delta-y Y)) where + X and Y are the number of pixels + on each axis to scroll by. */ HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ diff --git a/src/xfns.c b/src/xfns.c index b33b40b330..9d70ba479b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -8085,6 +8085,9 @@ syms_of_xfns (void) #ifdef HAVE_XINPUT2 DEFSYM (Qxinput2, "xinput2"); + DEFSYM (QCdelta_x, ":delta-x"); + DEFSYM (QCdelta_y, ":delta-y"); + Fprovide (Qxinput2, Qnil); #endif diff --git a/src/xterm.c b/src/xterm.c index 63754a2cb6..74f0cefb7b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -556,6 +556,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) { valuator = &device->valuators[i]; valuator->invalid_p = true; + valuator->emacs_value = 0.0; } return; @@ -9921,8 +9922,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif goto XI_OTHER; case XI_Motion: - /* First test if there is some kind of scroll event - here! */ states = &xev->valuators; values = states->values; @@ -9932,10 +9931,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, { if (XIMaskIsSet (states->mask, i)) { - block_input (); - struct xi_scroll_valuator_t *val; - double delta; + double delta, scroll_unit; delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, i, *values, &val); @@ -9943,6 +9940,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (delta != DBL_MAX) { f = mouse_or_wdesc_frame (dpyinfo, xev->event); + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); found_valuator = true; if (signbit (delta) != signbit (val->emacs_value)) @@ -9950,15 +9948,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, val->emacs_value += delta; + if (x_coalesce_scroll_events + && (fabs (val->emacs_value) < 1)) + continue; + if (!f) { f = x_any_window_to_frame (dpyinfo, xev->event); if (!f) - { - unblock_input (); - goto XI_OTHER; - } + goto XI_OTHER; } bool s = signbit (val->emacs_value); @@ -9975,13 +9974,22 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.modifiers |= x_x_to_emacs_modifiers (dpyinfo, xev->mods.effective); - inev.ie.arg = Qnil; + + if (val->horizontal) + inev.ie.arg = list5 (Qnil, QCdelta_x, + make_float (val->emacs_value + * scroll_unit), + QCdelta_y, make_float (0)); + else + inev.ie.arg = list5 (Qnil, QCdelta_x, make_float (0), + QCdelta_y, + make_float (val->emacs_value + * scroll_unit)); kbd_buffer_store_event_hold (&inev.ie, hold_quit); val->emacs_value = 0; } - unblock_input (); values++; } @@ -15048,4 +15056,11 @@ syms_of_xterm (void) consuming frame position adjustments. In newer versions of GTK, Emacs always uses gtk_window_move and ignores the value of this variable. */); x_gtk_use_window_move = true; + + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, + doc: /* Non-nil means to only send one wheel event for each scroll unit. +Otherwise, a wheel event will be sent every time the mouse wheel is +moved. This option is only effective when Emacs is built with XInput +2. */); + x_coalesce_scroll_events = true; } -- 2.31.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Nov 17 08:33:43 2021 Received: (at 51891) by debbugs.gnu.org; 17 Nov 2021 13:33:44 +0000 Received: from localhost ([127.0.0.1]:60445 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnL4J-0000u3-NM for submit@debbugs.gnu.org; Wed, 17 Nov 2021 08:33:43 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35058) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnL4H-0000tf-Al for 51891@debbugs.gnu.org; Wed, 17 Nov 2021 08:33:42 -0500 Received: from [2001:470:142:3::e] (port=59342 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnL4C-0005CP-29; Wed, 17 Nov 2021 08:33:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=MTydqDV1UP8tYr8BXbHC1OBXaTkzjaR3Uvkdj26haoo=; b=TIP3oUhxVrZo HeluXGI5o63auIxIepwhVjhOdFlypa+6aV1T6M3Gi5tp3QSP3/HaeoMw2of0bndhWTOaVgm8LpTjK 3Kb50ScJjUKVwCxM1V7ESw+jYvk8W8SSh+uvM1tNLq93LHUIm5hv9itYDsCZPDWk7/mgmpbZ1M8Lx xtFFRWDqiizsmQ/8PC1KjHskHiY9y6DBj5O/GiNGyadwNEIvTJOCo4cLXlFoByVGEKvWGkO9RvIkO tu2hHjVpbbuMi8uhzmWspKI0M/VJHBJtGivYgZHw3GPOqsEco9QVAV6hNGJVTcRo/5liR+szO+p9L 8ZMDF+lwmZ8sqjDg4KOk2Q==; Received: from [87.69.77.57] (port=2304 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnL4A-000845-Ml; Wed, 17 Nov 2021 08:33:36 -0500 Date: Wed, 17 Nov 2021 15:33:29 +0200 Message-Id: <83r1bezz2u.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <871r3ftsjy.fsf@yahoo.com> (bug-gnu-emacs@gnu.org) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Cc: 51891@debbugs.gnu.org > Date: Wed, 17 Nov 2021 10:38:41 +0800 > From: Po Lu via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" > > --- a/doc/lispref/commands.texi > +++ b/doc/lispref/commands.texi > @@ -1985,7 +1985,11 @@ Misc Events > These kinds of event are generated by moving a mouse wheel. The > @var{position} element is a mouse position list (@pxref{Click > Events}), specifying the position of the mouse cursor when the event > -occurred. > +occurred. The event may have additional arguments after > +@var{position}. The third argument after @var{position}, if present, > +is a property list of the form @w{@code{(:delta-x @var{x} :delta-y > +@var{y})}}, where @var{x} and @var{y} are the number of pixels to > +scroll by in each axis. Did you consider the possibility of defining a new event? And should mwheel.el be aware of this change somehow? And finally, why introduce keyword-value pairs into a form that didn't use them before? Can we store just the values there? > + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); Ouch! can we avoid calling 'pow' here? It's an expensive function. > + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, > + doc: /* Non-nil means to only send one wheel event for each scroll unit. > +Otherwise, a wheel event will be sent every time the mouse wheel is > +moved. This is confusing: what does "scroll unit" mean in this context? From debbugs-submit-bounces@debbugs.gnu.org Wed Nov 17 19:15:41 2021 Received: (at 51891) by debbugs.gnu.org; 18 Nov 2021 00:15:41 +0000 Received: from localhost ([127.0.0.1]:34129 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnV5Z-0006oZ-7R for submit@debbugs.gnu.org; Wed, 17 Nov 2021 19:15:41 -0500 Received: from sonic313-9.consmr.mail.ne1.yahoo.com ([66.163.185.32]:42997) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnV5X-0006oI-6t for 51891@debbugs.gnu.org; Wed, 17 Nov 2021 19:15:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637194533; bh=BKOiRs0ytVnxxbza2AcAYLPinaAHlTDBnUduuupgZaA=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=Rb4rcBnJ0J69eyEo7qD1wX0Cozwm5tAOP1O5QMS9+b3/23eU4Q7G3+8s4nkfYz2T6wMtQyZyl2tqnPqVFpjR9Icz0ZLDVUtsszRF1ZwIJ0clGE00FOsURvLojQ/cKkc8REYjtVh66E2IeNxp/bIe4fbtIkcz0LN8hp5WC3l+9YUCipxtJ7Zpi51S260AMVhzRFj0+GEAdmZBsyhW8HhDImY8XfmVMVwFAPQ5kHlrQrsbrooiqFEIYZmI1WAcLg/QYLHLu5ifLBYOOQ4jUBly27bSehLJ+oMxjiNPcke+GVIiWN0YudEktwxdk9fWRG8YORsRq5dQ5wFgFd4crSuTbg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637194533; bh=fKRIRi5XpkMdBlBINzB4iv1tRpm0xdm1LckhCypVYYq=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=i61edVDME7p0/4SVXfTJ5ytBhGeRQ79uIbOvYGJ1a3AdlUnrdVdz/R/wXS3mdBN96HAwNmIhAyvajK1bcbBoiHP9RYV120Fy6BLbOxGpMjCGRxbxZzpInZBd9wV9o+M8wL46R+CPvkwycXGj3aZbHKYswsfBjGO76FZW6RZVTYh8T9nJY7OZGuBXPsPSgca8rzWgHfZ6YebIXgUAO1sf9eaz6AllZd3aMJMej/Fz2wV2U9cVSFK6bjwj84Ndk3CN8/jAFe/6lwrEq1lUOZkGymSqyOZ5/AVQ0OJGlBV7uXZgVPNV7DYtfWldL4Z4uePaqJp6BWAORW+EFeASm9E3Cw== X-YMail-OSG: xtY1ZFIVM1lKmrUM8ZB2_7COn3cFx.zAtPpdgbt4TOFmMuda95z13kUHwmMT00r TmkwuPcdfBeN7TpC9w_UF1ftEeTwWknRFieQcmHYN8u.rXJ0oQaOct7XsOtCUEb1IUqKKTfNYYT4 PIXso0Qa1yXOUJqEbi4aJzEmei4MwmY4PPAiKN1LzwY.HNcDhNx5mNcJFv8WSEN5ytWVr71h18pi ._uAaqP4pZ3j0nKq3Qn8lHK1lieiSMOPoaJreWb.6z2JEgfla8ByvhpcCCNpVLOjVlHl3nv9ja5b Vh.1UMrCi9XddiINmMGM2La5oQHJS8UCX2QMqj1NeTezIH26PdcXP.r4wOTyo8sCqJ.Vta.0DTeF oIBS.mMnm8.ovqVs.8sll9rza1GYLQbnpgxvriVkuhkHkzt5ytB100wbZ3EJvAtRmYOKbseY9Itq 4bFStRuIStb5H1H2zRPWGsxi1.xhp28dw.kyL1RrDJ0uGJYDZOvrBZSGQA6DYLvZZj1ryC_LJjUh tVeleDW3Bi18_BR7YGtscWohLOWYwTAErVj5zwG.JIBXJkYEyc0H6rr_I55LS2WF.F_PNOnQImOI GdNGfJF23ACESaUhWNACBFaVvQkCXSfAsGLcBk5qvsG2APEQuvQ8wO7WeOyEp2ZhsbV9JJ_z5K0q 7FPpxwQWHswIiU7HRJ6kpy_B0GhIiq3CDgAXZA3IxwGGkbPXIgKHi8LYzyf0oyRGyxXY8NlwR.a_ i337C3VViWS8YDEFw.588vqikEL1f75McoXY2XlYTGbmR4S6SUdrn8eiY8DYSLXdPoPJWpRNUy82 diN7IFb5Ocn0F9kfmndE2FoylGRS.71d.Owa.d2hcjWEV79QGazm2iIfexVUDLAOMBawV.XWAnSr DgaDuPdwGc0NSvyQxbZ2LFCaMJjsQrUsD8McjCE_IdH4tUdo0w.11_8y6ksBIBWTR6l6kjin50tT fL5xyGSMKU81kSvl4J0_fyFxIx0XBwlPIBd3TetKiyESQMreYmTtjLaH0ugTWIU5GNSQvA_m1R__ Pv9ZpfybDKLNrdUhTRCoVx4LtY1e_KBFpeDgedZ3GAPThhh8wUf9bL9c3L7A3X3nVkuRlgBUemB2 2aSrpdMvS0GnlIN.8kfdok.mJ3YN3ZJCDCifLKKNeaJ2za8wQ.LmnzNK1dJK_ab2HyQTPvahqa46 q3GKwLuryxwawbjE6PwkhyOpGY7LVUT_FULcPY.Dzy77csOBH0nDMQDiA06zyHF3WadbgkoVyWR3 QAC2Ycrv6l7ECN7xPfm.nxrs7sFCC5TsV_AKXZwGK.y2nVLZ30rAyKAMPasUZNC9zqf_aXN81gPi CXfnMmeIC1cEKTJjpL8hgy56j8ZrSfci0vokD.hOllAYa84dhl_xu5GDY8HIVZXJNrl.b89yBJ6K sz9BK1DQ6uvhHp4rAF1WsO179KAFbTzWWXIDyV4M2QrK2Qw273MLhTva4dQT6Lx_fyeERYBapwyY K9C3LYJxHbza2SGX9n9qqn04Kl0KamBQio459u5eqYVl.WGVMH.5CcTixaHcfHFcHZm3vm5YtNRl Vf5uqgsgV8bWnfODhqcadN7beLMsU1z8QgTebbAntb2.v5gkNNBVVvwgcBMCzIp2yEYCit5aKNiq U7sjYnAQOv7Ri5mMqXXh_KDe39OwpglbzRlSACspacBYby7XpR0Jr1Q8PwnPgp.66pWoh5v6E26o Kp0am.nMre92IWyKEfwxCOUPtBFJAHx2Bl4wJB_Wx8hApXEZ7sfIfePGm4fvrXDu0OB7NTpXBYWU gJeLCxXS4UgoJciQ.OMGuKqvj_Hy4FEqzvldMRaXjiip_Ar8nLQgCp21ZvK3.fUEUlO5kGrd3BEk z.uz56rwVBvJH8XRrAG4q8rPW1rU1mWGZVybKTDqYV0VP.IV.vj4nINUcnLptsI61HkpH52kkivr 97yfhmtzbSoYVoDM1lsXpYttNa0uPYrFz1RUIRrovZ.giq6OwaiHLFUm1MtrQl4jdaTEP8gYtK49 O1nprledYxOnQOiiv3KUz8UY7MIN02PEblX6kwpr6eJnXqK0Qwd7uNcaQmxIzli1wbjAQ4crGemq IE.iTo123DsU_PwWnlV2fPlTvkaw3jtwRcof8fMhL_yZaC0HA8TCVzfLX5rwWD5FGEcrjnPPsP_I kicgmvq26TjMIbleYm0ynkLXINdkta0bpvOeKIVopIQcSy.1x9E54X6ulaF3rbPcdD.A9V_4DVAD rlj6od8tgldBXEMa.aIgEvJs0EGyTFg9xGQ8AfmZSmImP6zJCFSQ- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Thu, 18 Nov 2021 00:15:33 +0000 Received: by kubenode518.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f9a374bfc0513cc485f6edcefe69d5f7; Thu, 18 Nov 2021 00:15:30 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> Date: Thu, 18 Nov 2021 08:15:27 +0800 In-Reply-To: <83r1bezz2u.fsf@gnu.org> (Eli Zaretskii's message of "Wed, 17 Nov 2021 15:33:29 +0200") Message-ID: <87r1beqpy8.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 1541 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > Did you consider the possibility of defining a new event? Yes I did, but IMO it makes more sense to make this use the normal `wheel-events'. > And should mwheel.el be aware of this change somehow? It doesn't have to. A separate mwheel-scroll-*-function can be used to implement pixel scrolling, once we get to that. > And finally, why introduce keyword-value pairs into a form that didn't > use them before? Can we store just the values there? Different window systems might have more/different information. For instace, I can imagine the GTK port wanting to include scroll phase and inertia data into this propertly list. >> + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); > Ouch! can we avoid calling 'pow' here? It's an expensive function. That's what the other big users of XInput 2 do, including GTK+ and Mozilla Firefox, and is unfortunately the only method of obtaining true pixel scroll data from a scroll valuator. >> + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, >> + doc: /* Non-nil means to only send one wheel event for each scroll unit. >> +Otherwise, a wheel event will be sent every time the mouse wheel is >> +moved. > This is confusing: what does "scroll unit" mean in this context? An amount of scrolling that would previously generate a `mouse-4' or `mouse-5' event. But since I think most people don't know what such button events are, it would not be sufficient to just put that into the doc string. Any ideas? Thanks! From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 18 02:34:04 2021 Received: (at 51891) by debbugs.gnu.org; 18 Nov 2021 07:34:04 +0000 Received: from localhost ([127.0.0.1]:34546 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnbvo-0003fY-5T for submit@debbugs.gnu.org; Thu, 18 Nov 2021 02:34:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:42094) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnbvl-0003f2-U8 for 51891@debbugs.gnu.org; Thu, 18 Nov 2021 02:34:03 -0500 Received: from [2001:470:142:3::e] (port=38312 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnbvg-0003el-JL; Thu, 18 Nov 2021 02:33:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=EJUCmpnHIo/S1gRgqbOs+RaaiHmWDSoqPiCuggZSE5Q=; b=Ko88G8N27FSN vVqaJBZHESJ5FGzD0Je4w1/aJmQyFJO3Ebfg9VbMV+Hd4TlAImZJWXQ6FhMZqjlnxtgH/mtg3cU60 XZnl4XMowzNqeJMxlDR8WedUphOVqt8t6jRo4nwiEniZ3IGw2uuIPsDU5IeKSrDxpXokFQC6OVEbi yAoI38b57atHvpfWC9L3aW3Dgrs+pWcLg2OaqMhOFrAeHjdt5BOLc2svvXptkIZXg/PEK86KJHeUs r3pXWO4sS4I7gNzE5AtbYCnwqVGsbUjziUtdwaSTmlgX45Bk8l5JN6sFv5wlMHXc+ht9mii5hqAKG xOMqhbFrnjvP8W6uyTmvWA==; Received: from [87.69.77.57] (port=1442 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnbvf-00055X-Rg; Thu, 18 Nov 2021 02:33:56 -0500 Date: Thu, 18 Nov 2021 09:33:51 +0200 Message-Id: <83tug9yl28.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <87r1beqpy8.fsf@yahoo.com> (message from Po Lu on Thu, 18 Nov 2021 08:15:27 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Thu, 18 Nov 2021 08:15:27 +0800 > > > And finally, why introduce keyword-value pairs into a form that didn't > > use them before? Can we store just the values there? > > Different window systems might have more/different information. For > instace, I can imagine the GTK port wanting to include scroll phase and > inertia data into this propertly list. A Lisp object could have different types, one each for every use case we want to support. For example, we could use a single object there, which in your case will be a list of 2 values, and in other cases will have more members. We do this kind of stuff all the time, including in specifying POSITION in various events -- there are a gazillion of different forms of POSITION already in Emacs. I see no reason to change the format when all we need to do is add one more form of POSITION. > >> + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); > > > Ouch! can we avoid calling 'pow' here? It's an expensive function. > > That's what the other big users of XInput 2 do, including GTK+ and > Mozilla Firefox, and is unfortunately the only method of obtaining true > pixel scroll data from a scroll valuator. Sorry, I don't understand: XInput2 knows about FRAME_PIXEL_HEIGHT of our frames? > >> + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, > >> + doc: /* Non-nil means to only send one wheel event for each scroll unit. > >> +Otherwise, a wheel event will be sent every time the mouse wheel is > >> +moved. > > > This is confusing: what does "scroll unit" mean in this context? > > An amount of scrolling that would previously generate a `mouse-4' or > `mouse-5' event. That doesn't really answer my question. Let me ask it differently: how does "scroll unit" differ from "every time the wheel is moved"? > But since I think most people don't know what such button events are, > it would not be sufficient to just put that into the doc string. > > Any ideas? I might have ideas once I understand what you are trying to say ;-) From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 18 04:17:45 2021 Received: (at 51891) by debbugs.gnu.org; 18 Nov 2021 09:17:45 +0000 Received: from localhost ([127.0.0.1]:34722 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mndY8-0006uC-Qq for submit@debbugs.gnu.org; Thu, 18 Nov 2021 04:17:45 -0500 Received: from sonic312-23.consmr.mail.ne1.yahoo.com ([66.163.191.204]:36660) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mndY5-0006ta-Jq for 51891@debbugs.gnu.org; Thu, 18 Nov 2021 04:17:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637227056; bh=x/Z04ibMekc842tCjH8TWlGtc4yCYtAPIixDQWgKCGU=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=cXbVATymL80NokimItSTb2byqfybcHg1gnTSI9KQsO3PppR3cbwl7sFEDFcG2UIt06PE1PknhJopofmOzppsCXxzbrSqya7dnEpABe0wQHCdg31MY9FzEm3GLv8Tij4WPn2j9sOv0PJ3TIkyLLRPc4G5Occfl1uoisG+I1sDR1QNoJHDH590T4tSyyIcuzDssg30WhYujIU+nwDy0w5ZDmQULZxIC87QPverfouDcq1ibeDjt7ND1myoLXQ0orf02AXmC7ojwbbB8mxktl67dw1gpZ9BgkCSn3hDaXM0+6wTmcQLys4Hq89R0O+8eGDPqUJiUIM1YkPGvfZpUUjCRQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637227056; bh=INqIL3s7OCU8ULDVRKRA+ow0Ttxci+b1lamnjoLBYO+=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=fxFp0i5SOTtRU1+xp9amELLPS2dfOh/iPu0iU3X+7kkblWVsNMU6wl1+hvQDWwblqEgUaDruoCCDyJnPCDaWHLY66nODTCrUT+/ApHNJ0o/cqGkqvNZ1VC3JB0DvqVrB43mEOudCr5eaYn5Ub9S6FZ0ViG25Y8Dcxd9Z0ul97ddmOcuSgbmJIkgp9FlWVWSFR7kcQhytj3eo2H8evCnXwmSMuu7yxzIVk2jGgySlSPFT/s8VfoYNaBEnJWiJNrotIT2cxTGj1IyfJFUqbpOst/A6o2JMXeSvSuVNVcTZxU7mJ9juUcNtwY3ecNTQTxLob/QSOxGfAMo4KeH1bDVLSg== X-YMail-OSG: _mICJNQVM1m.RxcCAoZQGEyKabySIBdPZ2_V_6AUYo6nJgUQ5imNLG76nB8cqZF TeTbJocLlR1tBr2ZmscLoygOedt.UfdTnrb838iwRfptuPzKuQvR8kREVCzc_cUyDCQju9Hm3GwD nfr9vjt4kCjDM7JrluqFLP3ahsvdp3uCNdJlZM2JwI9fhwv_FjhxxQToaAne5XJFQjS6mzmHoTW_ b0tJUalK.V.hPYypjdYHLZTxH.AS1KgZvNnnSIGWzHbDjnS2rJG3JDU7VwWfgnO7EfRGHw0HGMH8 EViCbM5tBppU3OSvjbFBXiJiSlUlerKtH0ARayTCj82jGGuMKFxLqsvw53gHZ8shX84m4_LnElO1 8wmpscku6s2O3MZfPnTbDhV6M4MJZELcO.yhM2w2a7mWW7FbuZZB8iKlNClRRvHSarsx7B3P3nKH EVYw5fAo_c_za_FD6nSzq1S_7whi6lMwHRHgg8atepMWSt.MYDwhFhHy9KG.P0MqgcDDIBS6fmOr _q8SQCwg1XopPeqLErXRoO3Aw3ndA9TJtxTTvCdsGr2n.RS_CagMUxdi7hC_69JOVGGXuWQzQ_Jx o80k3l_XrGlBRyMbTCvd.AWFdDUA7mdLfyl4lZwlwzu6uPAcjOAf_SMzMYIfA75ovL0yGSqnd9_8 fxYqH9GHb8rfv42NIF5522uvYsHwN.JzuRCussoGOHbHEtnfPBH8EiwN4qFd9LJg1GG9rSWlPHhT bQXXOs03_zCd1AmB.cC590OcdHSDjrpEpujFXZDFOcjJ2WXsyf4kaZg4yZRQOYxuwKqKbrrp8rL5 Ys.Bz1kjF7hhhjIvJGTy8TasQ84wRDfpiLDy2XTU69Q0OUZR3UH.xYmDD7PP1tTrrzdwa704V8sT 3mUVOyUaFCgXcV0wBrC9_k7Kyg3PjLDnVuTWGeW_MpfOWvz7EanqS4O5pWd82RH3BOLB_LHsOhif gGvZ8_rHcoBOAeanqjNA6rqxwMaIbb4DpuYzq9oaNFr2420RZv5D.iOPxwbQW7slxAe7BaNDmEIs nrrDGd0vbOP5UbkoksGSSwp3OKfxjF81Hs43TLH2v4.jbGBcqG_lQSfDnlf6wjBOqJ9Sv5wIJX7W Uy9cWKzKkVE6PSeq94vwDHrfdGhtQXw1uji5S87FNr3s8RC7YkJhsy5FNKt2zgwOdRGaRv2kbMYN UaDnpvpCtOrPld1p0mJ2qUVRlSWdm0QsHv.7_HW8kKE1vwTS.HjBhnsiwpEp0CKtj7yuY_rcckD7 fwwO.XGqqc918JAkNVKc.EG4dzpQXPVgCLuUK9fHnJBGea0CVIhk2abSHoNzOvtPcvCtEYYpsSMK nQUZefdgz_8Zcpu5qe6zF9fxEfeY19Y104A7Qlv0SQxeu9Uk46Jw8cRVBo90cLyz_QAuovaoP5DV TQD9dArIf0UdHCCa4QpipM4taMv7ARAKIlGtoJbAS25u4OMAbhsbDJaAP3I2Q0hqtP8Jq68JAlQV UjBnzfM6gGxVs9z636bv9J79r3ll5mqrrkIAox7J_b9We4mmc5z8JjC3tkkpq3unAtg8XAyvDEGA Nq8RBJG0kMS8GtueIMFMD1Uw1GrmV4lMhGFRzSGBPBTF9FBNFRL.Nqfcdm0o16f.VjIS.eZYdbt1 CKB5uyjMk5YKuw8hecyT5dG3ir_NjBsU4H4fPIr7w9cH5FzwEj46iIo8nVz0RF0RZZOCBfc1EUi4 pE9ZsIPOj.lsyDDMKqWapcuaNYlVxXeHiZvNiNEOLIGRiJoaEzQMXo2qZ9Q3gSjOqRfjT2wBDj6E TyrhdhaHea_IxiHnrOlovZChwsp1eUIE3_rhn8S9Xn8qXw6VEZqxHGI563_5MeyPbl6Rg2WIn8ka FMX8eT6eYUmoQeY3hBV8g9_tE71rwPSNOCQCqKUyb.WiVak0J4TRlOVTeoFmRMfB.L1QNZ0en8Xv Dmp0smQgAwJAD9PAzXZrbYw2MmJ0FVGCDaST5TaIkCDAYxysrY1JEzpdIUgt0dFFA8zWXM2yNJPN __4QZ2.fUZemWYMwIqbaKNIFAiaIHV4sAaDyAVM1zom7hEDmJQEv33FK9RTkl0KTBQEQwmqOWB5I BJ1xB97ZbV7csBYftoXgpU1fVeG7YYhPazRJdgrL93twWBs3Po4_07azbTV35n9TcAv0KL.C3FYE usbVsCaMgIToZ.z0sBOojHqBT35io.N3ZgihT4KVXuA50iNO8Af1WLwOHaq36NfvFih5HZUF9XYc 8kI.3RALUk4YuvtZSkg50Ptsic7Y6W2KzpJBGtLr0zLwO1bNHwV_JRmIvdysB X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Thu, 18 Nov 2021 09:17:36 +0000 Received: by kubenode516.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 608cd43796cb626606981c79ae0cfeab; Thu, 18 Nov 2021 09:17:29 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> Date: Thu, 18 Nov 2021 17:17:25 +0800 In-Reply-To: <83tug9yl28.fsf@gnu.org> (Eli Zaretskii's message of "Thu, 18 Nov 2021 09:33:51 +0200") Message-ID: <87zgq1q0uy.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 1468 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > A Lisp object could have different types, one each for every use case > we want to support. For example, we could use a single object there, > which in your case will be a list of 2 values, and in other cases will > have more members. We do this kind of stuff all the time, including > in specifying POSITION in various events -- there are a gazillion of > different forms of POSITION already in Emacs. I see no reason to > change the format when all we need to do is add one more form of > POSITION. That makes sense, I'll modify the change in a bit to report scroll deltas as a pair of (DELTA-X . DELTA-Y) instead. > Sorry, I don't understand: XInput2 knows about FRAME_PIXEL_HEIGHT of > our frames? Indeed it does. It's the window server, after all. >> An amount of scrolling that would previously generate a `mouse-4' or >> `mouse-5' event. > That doesn't really answer my question. Let me ask it differently: > how does "scroll unit" differ from "every time the wheel is moved"? Basically, even tiny movements of the scroll wheel will cause XInput 2 to generate wheel events. This makes the behavior stay like the original by default, where you have to scroll 96 or so pixels before a wheel event is actually sent. (This is generally true, but certain mice may behave differently.) > I might have ideas once I understand what you are trying to say ;-) Thanks, I hope what I just said clears things up a bit. From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 18 05:28:02 2021 Received: (at 51891) by debbugs.gnu.org; 18 Nov 2021 10:28:02 +0000 Received: from localhost ([127.0.0.1]:34894 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnee9-0005Ew-GR for submit@debbugs.gnu.org; Thu, 18 Nov 2021 05:28:02 -0500 Received: from sonic315-22.consmr.mail.ne1.yahoo.com ([66.163.190.148]:36383) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mnee6-0005Eb-UJ for 51891@debbugs.gnu.org; Thu, 18 Nov 2021 05:27:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637231273; bh=eIvKINRzSR8EiP5PUBv4ugL34ZalimNtgnuHTt23e6w=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=p4g/bE+HQQAmxI3WrExUy8NawY6+OdqcBeXRSdSUq29C5pTMRFd/AsQMLgN8Op6nUtIqXwZ8Gn9YI29FNGdRdvtDZSzas89bZ5UA1BD3fEhGW9Ai6AgLYI94IQ+SYN7Y3frw0OuXvD9rCq9PNZQOg7YaBh0BWFN3Z6WNVwUB602o4nQb2OQ5Fkrdv44qy0ZtpAfykDMgtzsHnXP0/oEqGYclb362LEtFFYOB6wdD5toayxEeVbzvSze+P9WuQBmaGCMmkwSJVUJ1NxUz9MPwIlM3JaYIen+ASKRVsgFf973lAO45nwIa3nPJxP67x0WZsXYIoKbS9AdvicUUVxK+8A== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637231273; bh=cHvic5g1gsOg7nS7xdBF7YEs4qKo7Y7rViuV6yrEypx=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=Rx2zdliYdaziCmEkQFAQZ0+ui+AqBD8/I9510zD8a3kQGAP5Ft+rlf3Ah5cefAJfpfvEMlufPtlRg1tMjPRMnW89DB+IqCUMVZqgm28LwXAT2vIyjKARQxr0szo9EipfRzPEzJcIyfy6nOZmp/gk3jXKA19OqAd2EGfUVocRP08caLjGOkxivLq0jpqPVGG442elf1XC5apNOUDVu4EvvYB4Xw7ZwC8tWQgmZ0+yOyyOQahhuWywzBBy9jD6R6zNCMFAVfE41qENiqa8spVJ0kzNjkXRo0klCHdIU+WFZCjTO2EPpq5oT2MmC7ja+nFcrg//ivDZK/gS7oOkBcf8ww== X-YMail-OSG: .WBR.AMVM1nXhjQ_UTm1erSbCTPQj.FBwGOByi1v4vkU_x7nJOEKcRSrgUSc8oN L5XKyhzhcDwAuCQ4VLMk3BW0ilk2LMkpnKyYy_qAqrNAJGbum6tyTzF1.jN_Re2tuKRX50A2MwOd Pe_rHPxwcpuYWSZfCTO3i7jUUnJjqfFl0okezrtoTLkGFpXsmU22W5TJm5QPkQo41R7rS3l4WFJN zO005nsX7X9F1Tnab2Pwirih6LRAmN05yumSbG_ZNoGA8MxYYyHsnAClsxfEFc76msQ7iv2If6Vj yVOaTTL5cQchmApameJRE.m7VwoQyuoOMQLfpKg8Km7_7pmL6QcTBaTGPUCujuffJ84fMl9A7R76 R47wHIePrrYs6XwKMZ0kJP91VUQfc6yGNDJCklrSaIPmaDcZyUrYkt5H9rNDQGIBEXpRQg5fUzc_ .eKgEEiHFCVKX40zGYtE5EkLPHuFdGbgDAugXjFGpxDpLvB_CdILpJzCB5IxM0LroIDLTyJ00Jyg 9BQQraPzufTZtNeLKMUXBFjEMS_xJ5vN64ZpXPxMlvdaKuZR_jdtXzOI2.LXBmo_8EqQmAYjacPR cpjmDHWpPgJbLUmwL_Yn92CmwIbcwSVXJUjjaQwpYBqtajPAflGwpVCqHVYksthtiTavfmoAIXVv RBpPXEjVXwNf8J6azZBraFdfKkwLVqOZS42cfp.ng2cR0H_NFCasQuRBvxhAmQpGyDIrBmJ070B9 LyvPayq3CW6_rQJNb1MTtYOwmsudBDddIrLhvjH7lLxNAyDmjTtBdcP9YtNITfsY022b7gfOmz_O Rmz0O1U1tgBDVM2hZHch3Oa_Ky90iPb4sxR5L_e9uk1USe_2k4CEvvaDC8HKmRsqCxojhacrzxJG GCEXpDujlMiguBHitQ0CiwBeQ9OgY_ruxNt7y9MtQET_dr6mw1zresLqQViJLMRImJrAE0SvIMxz cRiJWamMrcAgRDQ2sTcOxOHD45vxnhqNjPkdBxEqgwMsSPz3UCcleLogBoQOZlfXmACJJ3YleWjw 1YHzRgz.vajutgFsL0W0TRWRbYM0tCo2R.G6y9fbrPsPlX1FSFIOhafEHb3oPXKhf8lZ5tHBwEwh MWWxa2A.h.KhZuNuzIK9id1mymim5iOmQEmAJBwYRL6NrY.J71WBZiR646H8xwo9yjsbF5l_noUV hBAPHAv1R2dSTwRJMPAIel7WD5JSmhFEUq7ninmO9qeF3LMSoTGjQnMCWIoQm6wqZY7T3Aty79NI aGIb.2vDHw1.GQ1LwVuXQaORJyDXvPDBeUwMiiBUum83PuIGyRtZhLxmpRWOZXL3AOhVcXHH6foS wUJuu40Z6hCaMQ22PW9XJiMxv03V1lfppfI0w3gNPCqTrTfdDpTOg39hOfmHr63jmvhVOYowlKIk nKZU4km6DRrBy2a9GOexB5aUK..QTNACsN6YoK4yvQ.kGQmVMrdstPewKbTlJCPlokiQJoncL8Cc nMpukcBaf9nIaZSzXM8WXUtfqdWQXZzvjbd8UtphoBBsnPtmM7P8o27uou7paiwGhygALkH49Wr3 drDW2VEM58urPD1P8XTykrZuV30ktlguFy_hkMLVAGEDdZvPu_5jIB5PvQrga45rugEQUieMfQd2 Q1_js6MnXYmp6igbfbHxeHtFiK8Qsl0y2eXlOOS3SQxUB8fDFLFRo2Zs75uFMGCWKt76My2qjpue 5rb9SPTlqUF02paKx.omZeNfrn5kHO0jZ.05XNbMztdrejxuyyseQ4Sjebdm6zjnaO63GIdnujjv V9tfi9_VlH.1z_UWYKh9Go4JVNGGllEpej2G0.F4yOku0bTCts0jBp9ERVT1O3xBXlYN_oRK2_fZ Ft6.Ud05ykOIQa.BVd.LEa8BSD5JzGXHwUqTEWTTpX20b6I5pvqIp5_xjqTM9JOQW5agJ8DxGUfL ZV8eQUNj8wWlUq5.DtwpeSmc_e6bPfZKlrMCfcI1MRtLnk8UuXZePFcqSk9i3lkxUX18JB80LhfK yEBssnW5vwZziKdHRIIRI5rhszwDA87eJeVJp151H_bQIIrCtOfDAvMMr4w1OgqlYiRyGU9gLn1b i1RADrW90jPrr3UGn35cNbtVdkVwZshAAsuXfNldTPwvc547WcLpWhRvznB8_i_eiC0t0n4H02fk N69ZdYzvPJqTQf7y4i6pYs0eMVZb_hcZ4IsQYOcWGXND90sF3mmDC6w9o8VewH6awW_Orx.BJwyk E.GKkWhvrr61znFwPWrYq7J5FHvdtfsHejRbDezwUevM1VqvMMeLW4vZpyQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic315.consmr.mail.ne1.yahoo.com with HTTP; Thu, 18 Nov 2021 10:27:53 +0000 Received: by kubenode513.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID a760b320bffc08e92e40d4746dd726d7; Thu, 18 Nov 2021 10:27:49 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> Date: Thu, 18 Nov 2021 18:27:44 +0800 In-Reply-To: <87zgq1q0uy.fsf@yahoo.com> (Po Lu's message of "Thu, 18 Nov 2021 17:17:25 +0800") Message-ID: <87v90ppxlr.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 6675 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Po Lu writes: > That makes sense, I'll modify the change in a bit to report scroll > deltas as a pair of (DELTA-X . DELTA-Y) instead. Here it is, and thanks in advance. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Expose-pixel-wise-wheel-events-to-Lisp.patch >From aeb2a2bec3936ee2e9fb0b4a135e80474d360d99 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 16 Nov 2021 19:39:50 +0800 Subject: [PATCH 2/2] Expose pixel-wise wheel events to Lisp * doc/lispref/commands.texi (Misc Events): Document changes to wheel events. * src/keyboard.c (make_lispy_event): Handle wheel events with pixel delta data. * src/termhooks.h (WHEEL_EVENT): Document changes to WHEEL_EVENT args. * src/xfns.c (syms_of_xfns): Declare new symbols. * src/xterm.c (handle_one_xevent): Give wheel events pixel delta data. (x_coalesce_scroll_events): New user option. --- doc/lispref/commands.texi | 5 ++++- src/keyboard.c | 6 +++++- src/termhooks.h | 5 ++++- src/xfns.c | 1 + src/xterm.c | 41 ++++++++++++++++++++++++++++----------- 5 files changed, 44 insertions(+), 14 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 1509c200e0..a32548e9d5 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1985,7 +1985,10 @@ Misc Events These kinds of event are generated by moving a mouse wheel. The @var{position} element is a mouse position list (@pxref{Click Events}), specifying the position of the mouse cursor when the event -occurred. +occurred. The event may have additional arguments after +@var{position}. The third argument after @var{position}, if present, +is a pair of the form @w{@code{(@var{x} . @var{y})}}, where @var{x} +and @var{y} are the number of pixels to scroll by in each axis. @vindex mouse-wheel-up-event @vindex mouse-wheel-down-event diff --git a/src/keyboard.c b/src/keyboard.c index c3bc8307d7..0c48790ce8 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5980,7 +5980,11 @@ make_lispy_event (struct input_event *event) ASIZE (wheel_syms)); } - if (NUMBERP (event->arg)) + if (CONSP (event->arg)) + return list5 (head, position, make_fixnum (double_click_count), + XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)), + XCAR (XCDR (XCDR (event->arg))))); + else if (NUMBERP (event->arg)) return list4 (head, position, make_fixnum (double_click_count), event->arg); else if (event->modifiers & (double_modifier | triple_modifier)) diff --git a/src/termhooks.h b/src/termhooks.h index e7539bbce2..b274be9e3c 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -119,7 +119,10 @@ #define EMACS_TERMHOOKS_H .timestamp gives a timestamp (in milliseconds) for the event. .arg may contain the number of - lines to scroll. */ + lines to scroll, or a list of + the form (NUMBER-OF-LINES . (X Y)) where + X and Y are the number of pixels + on each axis to scroll by. */ HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ diff --git a/src/xfns.c b/src/xfns.c index b33b40b330..0ea43d1330 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -8085,6 +8085,7 @@ syms_of_xfns (void) #ifdef HAVE_XINPUT2 DEFSYM (Qxinput2, "xinput2"); + Fprovide (Qxinput2, Qnil); #endif diff --git a/src/xterm.c b/src/xterm.c index 63754a2cb6..b98b7d1889 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -556,6 +556,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) { valuator = &device->valuators[i]; valuator->invalid_p = true; + valuator->emacs_value = 0.0; } return; @@ -9921,8 +9922,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif goto XI_OTHER; case XI_Motion: - /* First test if there is some kind of scroll event - here! */ states = &xev->valuators; values = states->values; @@ -9932,10 +9931,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, { if (XIMaskIsSet (states->mask, i)) { - block_input (); - struct xi_scroll_valuator_t *val; - double delta; + double delta, scroll_unit; delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, i, *values, &val); @@ -9943,6 +9940,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (delta != DBL_MAX) { f = mouse_or_wdesc_frame (dpyinfo, xev->event); + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); found_valuator = true; if (signbit (delta) != signbit (val->emacs_value)) @@ -9950,15 +9948,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, val->emacs_value += delta; + if (x_coalesce_scroll_events + && (fabs (val->emacs_value) < 1)) + continue; + if (!f) { f = x_any_window_to_frame (dpyinfo, xev->event); if (!f) - { - unblock_input (); - goto XI_OTHER; - } + goto XI_OTHER; } bool s = signbit (val->emacs_value); @@ -9975,13 +9974,26 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.modifiers |= x_x_to_emacs_modifiers (dpyinfo, xev->mods.effective); - inev.ie.arg = Qnil; + + if (val->horizontal) + { + inev.ie.arg + = list3 (Qnil, + make_float (val->emacs_value + * scroll_unit), + make_float (0)); + } + else + { + inev.ie.arg = list3 (Qnil, make_float (0), + make_float (val->emacs_value + * scroll_unit)); + } kbd_buffer_store_event_hold (&inev.ie, hold_quit); val->emacs_value = 0; } - unblock_input (); values++; } @@ -15048,4 +15060,11 @@ syms_of_xterm (void) consuming frame position adjustments. In newer versions of GTK, Emacs always uses gtk_window_move and ignores the value of this variable. */); x_gtk_use_window_move = true; + + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, + doc: /* Non-nil means to only send one wheel event for each scroll unit. +Otherwise, a wheel event will be sent every time the mouse wheel is +moved. This option is only effective when Emacs is built with XInput +2. */); + x_coalesce_scroll_events = true; } -- 2.31.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:05:51 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:05:51 +0000 Received: from localhost ([127.0.0.1]:38350 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3aR-00057K-5k for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:05:51 -0500 Received: from eggs.gnu.org ([209.51.188.92]:45874) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3aP-000574-H3 for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:05:50 -0500 Received: from [2001:470:142:3::e] (port=54112 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3aK-0003XG-B7; Fri, 19 Nov 2021 08:05:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=aBUaEo/4ChzQ3uCatgQx6K2qFkQpyswHM4Hr9hcz1rI=; b=k5OBCzi9mGee Im2y3vrHMH5hLbi3G02mXPHK3opXFBvP09YVt16FXbo4aUgumuyJ4doveN8g5hUN8TWmC5loNU6is i2kywrYG6qH3YqxoU2OxLmP9DBvLkLrTJL43+9aP0wYCrkpwhQDbyuTObU196MmG3mtGeiZSJ1WMd AHA4jrBb/8mYlMMdg8/sXfC7yT8uu+aToxObs1odWavrtzs7LsGUCTEqhFslpU6XVkgCG4NLK2Btp UREow/WpZuyEQkb2ea14YSooqxQlbGNPpxAUmW7sXCAOA5Dvv3K6qmvma1kqfcjVtgR9NIb+FGcYt siElYN0vX7Kxhdn24xPoDg==; Received: from [87.69.77.57] (port=3238 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3aG-000432-D0; Fri, 19 Nov 2021 08:05:44 -0500 Date: Fri, 19 Nov 2021 15:05:40 +0200 Message-Id: <83k0h4uwgr.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <87v90ppxlr.fsf@yahoo.com> (message from Po Lu on Thu, 18 Nov 2021 18:27:44 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <87v90ppxlr.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Thu, 18 Nov 2021 18:27:44 +0800 > > Po Lu writes: > > > That makes sense, I'll modify the change in a bit to report scroll > > deltas as a pair of (DELTA-X . DELTA-Y) instead. > > Here it is, and thanks in advance. Thanks, LGTM. But I wonder whether we should have some more prominent explanations in commands.texi about the significance of these wheel events, and also some index entry to allow to find this quickly. From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:09:52 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:09:52 +0000 Received: from localhost ([127.0.0.1]:38364 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3eK-0005EW-8y for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:09:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:47184) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3eI-0005EE-8m for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:09:50 -0500 Received: from [2001:470:142:3::e] (port=54708 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3eD-0004B1-3e; Fri, 19 Nov 2021 08:09:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=DqRwZ5gizIT3vPatkRAWRuP8bZX3ePTEDhS63TmQcJo=; b=auyLD7OgweY1 2cQFQGqV12B9wOCE4gQmmO70Azn72NplIMUBuThf7HcS4f1/tFptpnaV0+QqaMXZ2P4+rXqdU31OV d46Bn0I7SKoVbHgjzOvKPmEL0M7dGpV1AF4xMTC0iiuf4ZHNuhBat7wLxt4ONvx+FEiyv14eldCgt hDjEluvvUKMwgtJjBd9vFerk7HdaZzALJqyupONsIFvXzZ0ZE1R+OYn91j2W7E/dyfuPtlaoIk81J ZFlXVmWvaX63hLBtCV8JCzE3PqyVmGRTdGNiMwFySRGhBs1qaJvRhlKpMk5a1gVx2YDf5E6pfHA9H 5M8mkQ/MBGvdkIQEidwsLQ==; Received: from [87.69.77.57] (port=3483 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3eC-0003n2-Nh; Fri, 19 Nov 2021 08:09:45 -0500 Date: Fri, 19 Nov 2021 15:09:44 +0200 Message-Id: <83ilwouw9z.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <87zgq1q0uy.fsf@yahoo.com> (message from Po Lu on Thu, 18 Nov 2021 17:17:25 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Thu, 18 Nov 2021 17:17:25 +0800 > > >> An amount of scrolling that would previously generate a `mouse-4' or > >> `mouse-5' event. > > > That doesn't really answer my question. Let me ask it differently: > > how does "scroll unit" differ from "every time the wheel is moved"? > > Basically, even tiny movements of the scroll wheel will cause XInput 2 > to generate wheel events. This makes the behavior stay like the > original by default, where you have to scroll 96 or so pixels before a > wheel event is actually sent. (This is generally true, but certain mice > may behave differently.) Then the first sentence should probably be Non-nil means send a wheel event only for scrolling at least one screen line. From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:10:33 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:10:33 +0000 Received: from localhost ([127.0.0.1]:38369 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3ez-0005GA-IS for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:10:33 -0500 Received: from sonic317-32.consmr.mail.ne1.yahoo.com ([66.163.184.43]:39653) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3ey-0005Fu-At for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:10:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637327426; bh=brnjYqMHNLmRBgD2M4DoqYDbBHj2WCCLX6zWLTGH7W8=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=E+XdR2Nu4BnCt+zQ+NrluGA+S9Djhil4hpL7Xat3pH8A37yUggxy8g1ymc/J9LK+Xz201lkFXxgw0XkiFjZooOZWbi4hvf8aR+Yxm/dTJuryfwtcfDbW644NjPsB/vjdVfvGEem/Bq6EZMCS7JsQQ5uIRmJgGwFgLB7jt/G/YhL7SNyzk9ll/qrdtq6CGAT+yiKY5lm8GlIWBfakIeXqyQGtCah4iXSrKUxG+VMO9pFxvLXPJO5JLTvti0APrBK8ttj7IsOTZTmD0ehgamexX1I4DxydEmNCMCNriAY+VKMwzRsd4Xmd+6Hn2HgqcjvANRhbV44oXXHkzNBSh7xIuA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637327426; bh=12fBH2nQ4wk8c0gMrSR6vuqMMQQjfFfNO4liJt9f3NG=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=rOqVGWfcDE4IzLCfT0EUA4+y9NwFai7QPuYWeKIXuuD4M/Zqsewgv5UJXvVKs+pFBkqi/Ii7uPdYo8YN+jb2ikU6hPl0MV082u4UJDlNzEzrLEHSZhebkvUqxnLkGY9QYe69jp2HJQ7LkDKoNJVMmhddrmcduKjxFhkGhdsPmorqcAbCULQaPT/Kuk0QJf3E4FxyAsQN9A4hboQwbJ66GwndF7w541Hiuy/SKdeL9uA3LHVxl5gJ8UM0L8c0go8eT8SeCHKrRMxrvO7OEjPWeoX6JJiegQM64cdwehiUl9m7pGbtVHORjS/NRZKJdbvQEDYYz/NbmwD1hqJ9zPfCWw== X-YMail-OSG: DExNJ6wVM1mU4_Y2O7H7sQAsdZaBdiiDFgoHfbBy4Ua0jgwx6HPeIkZCpkACRcO iSsZJj2kh8b_lyMrpwlK_sMbB42fu73CFk3uwSL2McblYv9o2gCjJRsm2XMVc9sDyJra8bHL3hqD lCaC8HFZRbODWMP2YAj6xKVBzfQ5IpfrgS45YUnaG2yURk0UbzmMO6tPZyYUVfi7KkXBL.kscUhj 112RlW4Du66j3WXWN1tybxNxy6HlQuZDxObvh643U2kxEZ9pPDO_vkd09jpOGN3sbuETs.eg05FP QVIiUg.tHbuOFypTfS15BL.pQI6.UhFd_gN_bjBu2K1aQEySpGhQp5YIiliIEiLaQ_.pYQA1m.lx __nf9Cl1NBpte_ZOERZmhNeDVO5Iva9spAyvK3UvMPORIA4e_RcCpwo8l44mO3pptfkawFJEviux nIzc.Hzdr.lxJUAoqJAcldxkwf8_RKw7Epq26Ge.QaU68iLwiChlPpNDiz27yzvy8jS11qlHLyRj Opm8xMFbLtF5jx1_z8i9TFXXSbfbvZHhDQghrJLpmeMYO9CXl.Ksv7TvBXO8I_f_fk57VjdhN1WF fC3eZXUIvNY4NCjKq6cR.3zcEIFfXVzMX3aICeQ8C52RAlsOs9r0pv_P4chxt7xFJawzB95tAYBW 3PgAAh.eZp4NKC9flPqDP9MfUGO8nTLZm3S6Yn4zzlp_vnuWD8piBw_vQr.J0eQPwgqNEhT_bqb3 4AdKDoFI0Z0cAluFBnEslu0F8UCFf1Yw8GdjrH8xgJSl97GBoYSQVFwFdDIGwyntH2SEDRlLE3l_ AXAzHk4mq9zsgspCrBjGzAK9WkPuio88UN_s2f1SziFQf8ma3LZuRe5c_VQiPPNEmElyX1WO47Lb hS9ZF3af6VMNTYp5er8aQ3GHlm7ZjnEiHFkvlG1FcMSipuiUbZMkQnZ1MGLDzD2SzohT5m1Py1FM ly47mnVmMcdM75q7q8ehniBhCZtBlkaTadjIC0CxQ3duP8WgiFhXnwA0bnBqV4S0PjVaSqvsXz9f S3SD5KePGj25z0qkBpDxIX7ngixpq0aGnfy33EdrnAigJheAqmqVqQOlYPsc4fIBMuK5OdFxTcOc 6XQHWMO33oReT3JYQGpE9d3RUF3_IHthcA9UfVUsh9MNNI6fVEW_mT9iv6NFjw2ITjYhgW9EcJ3s kp2Ayfyu9PMTq9Fksj_s0naKiahcoJroCgmP02lM8LCfDvPrNI9PcZ9Jxrmt..ZDIq2W3xvWT.7j GPbDSBxpFMyJvjP3ytGqRgTEX1iw54uAhC1xp3CkbWUeYlWKjWwz2xZTh88b3mUT2DcZW3FHVUT3 R2K835cpgTCti5zDDfYS_DMiJDuAEbqcnyOPe7DIHJwaBbOsa6skCGSL6SarWVoxAOWDnjtm9o_7 UMG1kiWR4Gfej9.oQgQRYl_Bh0vTDdb55JiGppj9QvbcfsfE6sPgxOAACwoKYZGEwwFgCxZOIlCt k70n3ZgpvuLsEB4bQOHGbkQugWj4HV1DK0FwnfC8vzH2p3ks6sfPr1RfTgh7S7Zyo8ADewQ5mOMS Y2qlkEm05f7580WLQqaT0ekw1fnx4S.D4UxhOoJ0u9DDMNwxN9FbW1WvtJQCsj4Fd9YgN4hGXlHt _9pcmp9MnDhNh_1iZjkKyXUlGqTcT2KRx0nJC3S8aQHf821aRgRtWxPHwOTf8vJN8KPHzh0IzUf_ ybpMJtA1EPRvbrHKuRCWTDewUtUQessxXYbdNSkL_kgHJ9UEu.83efczqEvYAN0.zLaeYv.fwDc4 54uFlqWIGeqzomfOEdw5lqLwRMDxc.opwL0INJ9BHU6ycXwk8P.4RvqBfsiquZp0Y47.YJmxIgdC ckWyYgN7PuUZRUQW8a2aG20lUrxY0JPmCHIU3tAKiKJgp2nLJ82MwGkZwbGh_BBohssGs0KSCPwu bD.QWJt3V8OU0gHD5GBx2C7hjVQiUsjEbFw0WyAzdRe9dMDyBPCB9iG4kaPDWA0TrcJG54Zqbk_Q yNBQEWFhsZah4lrCu.av_PSYkAljZ1gLwjJosi8yJDa2.gFFTAt3PAbZDzIsQ4gkiFAQgkEpyk62 KK1FMA3kQBZ64RmvFLmJ58G1eqOzTL76HjHTHREF_DrP6T_QyzwWJwMe.V7p14D7jdUe6DvkPz2B c0xVTJIXnkqxegtWXZvWHEG3h0MBJ.9YD40XmUTtAknbx2pYZ0Ir0xStzv4WW2UyHvPH8NDU6oc4 cWoeHv43Md_hlK6vqwS5aXli8v3Qg_2uBx.iQA5aNMjU9SK2djFZktMZk.02krOw9 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 19 Nov 2021 13:10:26 +0000 Received: by kubenode516.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 2ac4f7831f7375933f71ab71f57d7eed; Fri, 19 Nov 2021 13:10:22 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <87v90ppxlr.fsf@yahoo.com> <83k0h4uwgr.fsf@gnu.org> Date: Fri, 19 Nov 2021 21:10:14 +0800 In-Reply-To: <83k0h4uwgr.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 19 Nov 2021 15:05:40 +0200") Message-ID: <871r3cmguh.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 412 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > Thanks, LGTM. But I wonder whether we should have some more prominent > explanations in commands.texi about the significance of these wheel > events, and also some index entry to allow to find this quickly. I have no idea what further explanation to put in commands.texi. As for an idex entry, how about "pixel wheel events" or "pixel deltas in wheel events"? Thanks. From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:24:00 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:24:00 +0000 Received: from localhost ([127.0.0.1]:38427 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3s0-0005hH-Hd for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:24:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:51620) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3ry-0005h3-Hu for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:23:58 -0500 Received: from [2001:470:142:3::e] (port=57532 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3rt-0002km-7W; Fri, 19 Nov 2021 08:23:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=ljlxVl1Bdzs63OUiKkBf2COoX8p70f5iQYmzLel6xjk=; b=AqqGywF3CinO Ov+u/mcsGCR9RrxSEU4fU5u83zuhThOBeyvwDcEDGeGSo4BcHTKuWcZcUidqAnQCJ3RDPhorExHUp gtbQtEdO5IM1eGw/5d9qbBCcV6MA1wVMgPsHlr9txu2rixZSG1eTQ3IgjQfBkJuMT+moORYEbjWCG 6V3lidc4CjeZ6XCD9Ap11nCzmz7hphaiqpsT0PeptF1WVUD8iyNJgOlQcJkbzHmBGVRM+kfvIm+++ TkT9NjJqu8g9CdIWkSknBQxVBbeQo9NH+XtfqO2lVn3E02bPf1RNZ/0uJJFoyrPHayM+BuiRA9c/C s489+DO4gX1p3hFpGLvUPQ==; Received: from [87.69.77.57] (port=4346 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo3rs-0003f0-J7; Fri, 19 Nov 2021 08:23:52 -0500 Date: Fri, 19 Nov 2021 15:23:52 +0200 Message-Id: <83czmwuvmf.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <871r3cmguh.fsf@yahoo.com> (message from Po Lu on Fri, 19 Nov 2021 21:10:14 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <87v90ppxlr.fsf@yahoo.com> <83k0h4uwgr.fsf@gnu.org> <871r3cmguh.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Fri, 19 Nov 2021 21:10:14 +0800 > > Eli Zaretskii writes: > > > Thanks, LGTM. But I wonder whether we should have some more prominent > > explanations in commands.texi about the significance of these wheel > > events, and also some index entry to allow to find this quickly. > > I have no idea what further explanation to put in commands.texi. Some text which makes it clear how these additional POSITION parameters could be used by Lisp programs. > As for an idex entry, how about "pixel wheel events" or "pixel > deltas in wheel events"? I think "pixel-resolution wheel events". From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:25:16 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:25:17 +0000 Received: from localhost ([127.0.0.1]:38432 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3t8-0005jt-Sd for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:25:16 -0500 Received: from sonic306-21.consmr.mail.ne1.yahoo.com ([66.163.189.83]:34064) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo3t4-0005j8-5n for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:25:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637328300; bh=gG6qn/w8CsFhh2BNxBvufPzVUUW1Nu/9VDuPsHpdjVw=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=hheSTAcUiSWqR8dj0l9YVwvkxLaXiMXYk0wWzXBzcASMmeor8HNBq5rm5In8jknG2M2kmaEp0b0kABbu8XO6A00DlN/o+7UsjUE1c/pAVhtIBYGtPQbq7b8PCMosm1ovuySgsWLJGO8muARkOoo6f8595/d5CQpDJBahPnR+iH3WvUrqgttjAmMyq9ByCRQwHFpF8SJulsbflZeZ7SxILJXiw0BDcxFm9BRKQoHoCatzYYxhphfwg2HQE6a7zO5JoCXJxzoOM1xBY4HRrpNcTQdOHC3Ye03dpjJuaZ0H9lpvcg348cwsNeORljqCfeYNCWirZKewzRYGS8or5wfVcA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637328300; bh=D4S5kJ3uiM+IeLof+S/O/rqJ7dau+8s2VV5zp0EBTiy=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=YzQE0BllIiysdaGXnGZav8N3+OfgRarizBmQDcr58yASwebMaytVnhtBvxadHfVqa0S3Zde7euE1om13ber+FnFb1lbLMN++qTXhFNEvwuRCgSsFCrYprjqKv0P/uw0+ISulE8ynOMk/H0WEilWz6WGY16hE3aVZiU94YzuZOv/j79tTSuGOENUkf9I6kpZDaYo4r3DxemOsG3xzg+Sf3SfroNjUp4f5ibywCSyc7e2aoFz0NdWz1auNSkwtX28245j2W9V20aV7xYPenNax/LNFmq3IV0iOdrU0oTHJFZTKq/MWEL5yCGCzFqRi/adfm8JXJ0aE7A6ZYO0mJ4MYQA== X-YMail-OSG: yETFXaMVM1m7bVy9PQCpg.rRNxJi7ylnZ9RIhd4XMw4tyL_EmtNO71dyBOtGLHY Lk4jPOdmOzGjO47C5N0hCc.b3vFE94vV_XsBd274kjUt9KqtYBvDdeJ8EpO5.KP9f47gafO.Q.Wf EO_eI_R6_yz33N.ag_2xDwTkO0eHE.5r8AzKFXusyyWvd4AbG7cWnsm5MPtSUXQaB.XDUSoO3Jd7 kXh3rmLvmpGdwXU12Td2jWtqMBy4m1W8Yulgp2CjcmUThUVf.7QJLEQroKCd6H4WoxKUb4IxEeuA mE4ilQRN81.9FdUGbptmmFs5WG6lx0ACVuVy7uZ52rJdgiVacGeIwdeq0Cn9e29Rd65NVHe15s0n yfElTvtX_Nond7yX.S9RRjJoztQGOG.CLVfnRhWexaSKVQFs1YL.5M5BWD5jACiahL1wq_.khg9L j0_riDNRRUTa4vEH4TtXZW8N31clRIe53840MTGg5aNrBcvI_3q1Y_ueNlzSdpasZAlQN5UCnuZV GyDlXtp_3EDf6jXKTKsGdqusMRygDkC0SvMVl5srSKlPOTN.A2S2i8zVTvAUhKg3s4X3KZzMlDV. H175QeUbO.S1KAt8o6SuTZajkWOSRIEDbCkOdp0WiKmVOmxwg61DB6JYPsnZcMj0g4yPYVW.NtAe L50X0GZNtf3M_HuyFRonyHFnPIBbQy4Wtuf1.WT9p6U8zU3wStTGk8Z8ZrBbMyiq4ktwIoe2NuQX D2ofDygoDXGTBPWO.eYpFk3RGF2_ryzQQiNNYuAw3NS25UhGY.qqAuU.zl_t_2jOTtNWqFy6yXxO qA4Gt8ggh9GxzM4MHRo1uHdcvNj945XlNL5CvB7FDngJaTd0De9DwyE5v0xyb..rRqr4fU6AT7ey srFTKTEwLCeVnGdFOyBKNkPnR4ArpFcLsmaZ1Hml3UYzkW0fq7mAtH5BpkB6DFd5Kgm7aqpZ8GRg PSg7IUPmS8Av5sF9k9Zxczquc7na7cwYt61DfTpgop9B7WwhyOVrmKGn..y3NLq1hZE.DG6tXT9Y SnhY_ac5kbWnYLhiezw6s1SfI2wmldE_6uQ._6uHCXVZ1haDMYt8YI2TAzLb4J5axsDEwF2YFFqg hdzN66qYN9N02oHTNdVZvl01pigkSxHFDakOTAZu2g7BgYssQN48OhUM6PzWzk8b_A2ErLB8bgWZ Xa_qjJYxQqG8mnImpuRw0twdldCBzNmy79ZZkjuo2qEtJPcm71fI0rRqG6k9rlVnBymgUiB_YrL8 C5S9YiQaVuLQtqBGBfdmSdfFcCYRJkzqYb1QNbBjf3aUNXYYSHdgz_tvzh78gk0XGzC2kmTeaBOI dYxab.V8PpNTG5O6Yaip_NO6Lwlu0DUUgw8bmyHrsOI54PnNUOV47Y0cfdnBC5KRwcI_UVvuCDzl CvGWRokotCRRrpWAdVO1zWfwblJEQoaaXWJOSAfE6fgJUHId5B0XV4aNOM8.DmJ6OxNFbUaUqwkW p0bQhWonlfwZiXSuPcNlv54lIRv5mmtS5jeb3uO_XdbRaIG8FMzLycuX2xjudF8esgaL9_u_BoR9 NJHVNblAMgS83YflbkvlnoXHA6vRDmhJqCVIufKYB8htdN3YgLiU5qU0gqbg37SUsbJnSrSr4PEL vpygkvqqm2L0dWXKsB4qIdtTR0mbpbwaFrLNjM8qDA7Xx6d1fheBXuzJsyiAz3jhOFd6oVIRk4sj jEb.cB7scsZ_Sy9JR2BNMBwddfmTqhr6OkadYvEznx.PQLTKw3B_upwLziVf4h8joAkfXwg3lcgY bWPuLgO1W2YkBwTdQFHJ2gdko9p_bvPwL7dFI.5jqWMZa76.TE0l09JiqBLR2nMygbdiEcRFcco_ tLLyFUJZ3fDVs91WCWsQkP6kcKtE2l6es0CkkXg83c0hNb_NSDjCXw3VabeKNv7AENEaP4aKFzgE Yva2pemxrmFYzVObPJhYL.c_d9SWVEiHe02flXHIn2Ce8USfs4bwSgdc5fwczbQKm2f8vLX17kts hY1wAM0JGXFafk1LFPbE6JqB2xHOSkv60CJCyf1B0p4J0_aEaZ4eY7WAqHvCzOt.CPYeuk_k4Z79 iT7wifXDPnvF8MX_tbNH7L1l8wU3AhE3.Cv.h55FezQiJCQwREwYiP_xg4EgfvxnT1DdwTZYW_9q Fd9atJQRTm9rMa7gZ.kFk5YCKg50bvlXMTnkTPxr7ruDBCBoxy5obxUyV8V6g29Jbz8f9m8bAr6X EegzgwnvCnBWC8ptnIi56GOdmsSU9aEWm4adtbd25J9W_RPbKAdTD3KCBCBPK13Q- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Fri, 19 Nov 2021 13:25:00 +0000 Received: by kubenode517.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ea020ceff7cbdc83c1e92cfeaabf39d3; Fri, 19 Nov 2021 13:24:54 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <83ilwouw9z.fsf@gnu.org> Date: Fri, 19 Nov 2021 21:24:49 +0800 In-Reply-To: <83ilwouw9z.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 19 Nov 2021 15:09:44 +0200") Message-ID: <87pmqwl1lq.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 64656 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Eli Zaretskii writes: > Then the first sentence should probably be > > Non-nil means send a wheel event only for scrolling at least one screen line. Thanks. Would it be OK for me to install this version of the change that has the changes you proposed made? --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Expose-pixel-wise-wheel-events-to-Lisp.patch >From 62285bb2debd7226110df94f8971df0e97efe672 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 16 Nov 2021 19:39:50 +0800 Subject: [PATCH] Expose pixel-wise wheel events to Lisp * doc/lispref/commands.texi (Misc Events): Document changes to wheel events. * src/keyboard.c (make_lispy_event): Handle wheel events with pixel delta data. * src/termhooks.h (WHEEL_EVENT): Document changes to WHEEL_EVENT args. * src/xfns.c (syms_of_xfns): Declare new symbols. * src/xterm.c (handle_one_xevent): Give wheel events pixel delta data. (x_coalesce_scroll_events): New user option. --- doc/lispref/commands.texi | 5 ++++- src/keyboard.c | 6 +++++- src/termhooks.h | 5 ++++- src/xfns.c | 1 + src/xterm.c | 41 ++++++++++++++++++++++++++++----------- 5 files changed, 44 insertions(+), 14 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 1509c200e0..a32548e9d5 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1985,7 +1985,10 @@ Misc Events These kinds of event are generated by moving a mouse wheel. The @var{position} element is a mouse position list (@pxref{Click Events}), specifying the position of the mouse cursor when the event -occurred. +occurred. The event may have additional arguments after +@var{position}. The third argument after @var{position}, if present, +is a pair of the form @w{@code{(@var{x} . @var{y})}}, where @var{x} +and @var{y} are the number of pixels to scroll by in each axis. @vindex mouse-wheel-up-event @vindex mouse-wheel-down-event diff --git a/src/keyboard.c b/src/keyboard.c index c3bc8307d7..0c48790ce8 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5980,7 +5980,11 @@ make_lispy_event (struct input_event *event) ASIZE (wheel_syms)); } - if (NUMBERP (event->arg)) + if (CONSP (event->arg)) + return list5 (head, position, make_fixnum (double_click_count), + XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)), + XCAR (XCDR (XCDR (event->arg))))); + else if (NUMBERP (event->arg)) return list4 (head, position, make_fixnum (double_click_count), event->arg); else if (event->modifiers & (double_modifier | triple_modifier)) diff --git a/src/termhooks.h b/src/termhooks.h index e7539bbce2..b274be9e3c 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -119,7 +119,10 @@ #define EMACS_TERMHOOKS_H .timestamp gives a timestamp (in milliseconds) for the event. .arg may contain the number of - lines to scroll. */ + lines to scroll, or a list of + the form (NUMBER-OF-LINES . (X Y)) where + X and Y are the number of pixels + on each axis to scroll by. */ HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ diff --git a/src/xfns.c b/src/xfns.c index b33b40b330..0ea43d1330 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -8085,6 +8085,7 @@ syms_of_xfns (void) #ifdef HAVE_XINPUT2 DEFSYM (Qxinput2, "xinput2"); + Fprovide (Qxinput2, Qnil); #endif diff --git a/src/xterm.c b/src/xterm.c index 63754a2cb6..ed3921f286 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -556,6 +556,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) { valuator = &device->valuators[i]; valuator->invalid_p = true; + valuator->emacs_value = 0.0; } return; @@ -9921,8 +9922,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif goto XI_OTHER; case XI_Motion: - /* First test if there is some kind of scroll event - here! */ states = &xev->valuators; values = states->values; @@ -9932,10 +9931,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, { if (XIMaskIsSet (states->mask, i)) { - block_input (); - struct xi_scroll_valuator_t *val; - double delta; + double delta, scroll_unit; delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, i, *values, &val); @@ -9943,6 +9940,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (delta != DBL_MAX) { f = mouse_or_wdesc_frame (dpyinfo, xev->event); + scroll_unit = pow (FRAME_PIXEL_HEIGHT (f), 2.0 / 3.0); found_valuator = true; if (signbit (delta) != signbit (val->emacs_value)) @@ -9950,15 +9948,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, val->emacs_value += delta; + if (x_coalesce_scroll_events + && (fabs (val->emacs_value) < 1)) + continue; + if (!f) { f = x_any_window_to_frame (dpyinfo, xev->event); if (!f) - { - unblock_input (); - goto XI_OTHER; - } + goto XI_OTHER; } bool s = signbit (val->emacs_value); @@ -9975,13 +9974,26 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.modifiers |= x_x_to_emacs_modifiers (dpyinfo, xev->mods.effective); - inev.ie.arg = Qnil; + + if (val->horizontal) + { + inev.ie.arg + = list3 (Qnil, + make_float (val->emacs_value + * scroll_unit), + make_float (0)); + } + else + { + inev.ie.arg = list3 (Qnil, make_float (0), + make_float (val->emacs_value + * scroll_unit)); + } kbd_buffer_store_event_hold (&inev.ie, hold_quit); val->emacs_value = 0; } - unblock_input (); values++; } @@ -15048,4 +15060,11 @@ syms_of_xterm (void) consuming frame position adjustments. In newer versions of GTK, Emacs always uses gtk_window_move and ignores the value of this variable. */); x_gtk_use_window_move = true; + + DEFVAR_BOOL ("x-coalesce-scroll-events", x_coalesce_scroll_events, + doc: /* Non-nil means send a wheel event only for scrolling at least one screen line. +Otherwise, a wheel event will be sent every time the mouse wheel is +moved. This option is only effective when Emacs is built with XInput +2. */); + x_coalesce_scroll_events = true; } -- 2.31.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-support-for-event-processing-via-XInput-2.patch >From 765b343f3fc92c55c7ca48360c4e09ca2793d44d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 16 Oct 2021 13:15:36 +0800 Subject: [PATCH 1/2] Add support for event processing via XInput 2 * configure.ac: Add an option to use XInput 2 if available. * src/Makefile.in (XINPUT_LIBS, XINPUT_CFLAGS): New variables. (EMACS_CFLAGS): Add Xinput CFLAGS. (LIBES): Add XInput libs. * src/xmenu.c (popup_activated_flag): Expose flag if XInput 2 is available. * src/xfns.c (x_window): Set XInput 2 event mask. (setup_xi_event_mask): New function. (syms_of_xfns): Provide XInput 2 feature. * src/xterm.c (x_detect_focus_change): Handle XInput 2 GenericEvents. (handle_one_xevent): Handle XInput 2 events. (x_term_init): Ask the server for XInput 2 support and set xkb_desc if available. (x_delete_terminal): Free XKB kb desc if it exists, and free XI2 devices if they exist. (xi_grab_or_ungrab_device) (xi_reset_scroll_valuators_for_device_id) (x_free_xi_devices, x_init_master_valuators): New functions. (x_get_scroll_valuator_delta): New function. (init_xterm): Don't tell GTK to only use Core Input when built with XInput 2 support. * src/xterm.h (struct x_display_info): Add fields for XKB and XI2 support. * src/gtkutil.c (xg_event_is_for_menubar): Handle XIDeviceEvents. (xg_is_menu_window): New function. (xg_event_is_for_scrollbar): Handle XIDeviceEvents. * etc/NEWS: Document changes. * lisp/mwheel.el (mouse-wheel-down-alternate-event) (mouse-wheel-up-alternate-event) (mouse-wheel-left-alternate-event) (mouse-wheel-right-alternate-event): New user options. (mouse-wheel-text-scale) (mwheel-scroll): Test for alternate events. (mouse-wheel--setup-bindings): Set up bindings for alternate buttons. --- configure.ac | 22 + etc/NEWS | 17 + lisp/mwheel.el | 66 ++- src/Makefile.in | 7 +- src/gtkutil.c | 72 ++- src/gtkutil.h | 4 + src/xfns.c | 50 +++ src/xmenu.c | 4 + src/xterm.c | 1107 ++++++++++++++++++++++++++++++++++++++++++++++- src/xterm.h | 44 ++ 10 files changed, 1372 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index c231c2ceae..239bf72f71 100644 --- a/configure.ac +++ b/configure.ac @@ -487,6 +487,7 @@ AC_DEFUN OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) OPTION_DEFAULT_OFF([native-compilation],[compile with Emacs Lisp native compiler support]) OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin]) +OPTION_DEFAULT_OFF([xinput2],[use version 2.0 the X Input Extension for input]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -4237,6 +4238,26 @@ AC_DEFUN AC_SUBST(XFIXES_CFLAGS) AC_SUBST(XFIXES_LIBS) +## Use XInput 2.0 if available +HAVE_XINPUT2=no +if test "${HAVE_X11}" = "yes" && test "${with_xinput2}" != "no"; then + EMACS_CHECK_MODULES([XINPUT], [xi]) + if test $HAVE_XINPUT = yes; then + # Now check for XInput2.h + AC_CHECK_HEADER(X11/extensions/XInput2.h, + [AC_CHECK_LIB(Xi, XIGrabButton, HAVE_XINPUT2=yes)]) + fi + if test $HAVE_XINPUT2 = yes; then + AC_DEFINE(HAVE_XINPUT2, 1, [Define to 1 if the X Input Extension version 2.0 is present.]) + if test "$USE_GTK_TOOLKIT" = "GTK2"; then + AC_MSG_WARN([You are building Emacs with GTK+ 2 and the X Input Extension version 2. +This might lead to problems if your version of GTK+ is not built with support for XInput 2.]) + fi + fi +fi +AC_SUBST(XINPUT_CFLAGS) +AC_SUBST(XINPUT_LIBS) + ### Use Xdbe (-lXdbe) if available HAVE_XDBE=no if test "${HAVE_X11}" = "yes"; then @@ -6011,6 +6032,7 @@ AC_DEFUN Does Emacs support legacy unexec dumping? ${with_unexec} Which dumping strategy does Emacs use? ${with_dumping} Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP} + Does Emacs use version 2 of the the X Input Extension? ${HAVE_XINPUT2} "]) if test -n "${EMACSDATA}"; then diff --git a/etc/NEWS b/etc/NEWS index 80be6c0e49..ca6b946843 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -30,6 +30,14 @@ The file is typically installed using a file name akin to If a constant file name is required, the file can be renamed to "emacs.pdmp", and Emacs will find it during startup anyway. +** Emacs now supports use of XInput 2 for input events. +If your X server has support and you have the XInput 2 development headers +installed, you can configure Emacs with the option '--with-xinput2' to enable +this support. + +The named feature `xinput2' can be used to test for the presence of +XInput 2 support from Lisp programs. + * Startup Changes in Emacs 29.1 @@ -217,6 +225,15 @@ The user option 'comint-terminfo-terminal' and variable 'system-uses-terminfo' can now be set as connection-local variables to change the terminal used on a remote host. +** Mwheel + +--- +*** New user options for alternate wheel events. +The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event', +'mouse-wheel-left-alternate-event', and 'mouse-wheel-right-alternate-event' have +been added to better support systems where two kinds of wheel events can be +received. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/mwheel.el b/lisp/mwheel.el index 51410e3ef4..3d0b8f07cb 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el @@ -63,6 +63,13 @@ mouse-wheel-down-event :type 'symbol :set 'mouse-wheel-change-button) +(defcustom mouse-wheel-down-alternate-event + (when (featurep 'xinput2) 'wheel-up) + "Alternative wheel down event to consider." + :group 'mouse + :type 'symbol + :set 'mouse-wheel-change-button) + (defcustom mouse-wheel-up-event (if (or (featurep 'w32-win) (featurep 'ns-win)) 'wheel-down @@ -72,6 +79,13 @@ mouse-wheel-up-event :type 'symbol :set 'mouse-wheel-change-button) +(defcustom mouse-wheel-up-alternate-event + (when (featurep 'xinput2) 'wheel-down) + "Alternative wheel up event to consider." + :group 'mouse + :type 'symbol + :set 'mouse-wheel-change-button) + (defcustom mouse-wheel-click-event 'mouse-2 "Event that should be temporarily inhibited after mouse scrolling. The mouse wheel is typically on the mouse-2 button, so it may easily @@ -226,12 +240,20 @@ mouse-wheel-left-event 'mouse-6) "Event used for scrolling left.") +(defvar mouse-wheel-left-alternate-event + (when (featurep 'xinput2) 'wheel-left) + "Alternative wheel left event to consider.") + (defvar mouse-wheel-right-event (if (or (featurep 'w32-win) (featurep 'ns-win)) 'wheel-right 'mouse-7) "Event used for scrolling right.") +(defvar mouse-wheel-right-alternate-event + (when (featurep 'xinput2) 'wheel-right) + "Alternative wheel right event to consider.") + (defun mouse-wheel--get-scroll-window (event) "Return window for mouse wheel event EVENT. If `mouse-wheel-follow-mouse' is non-nil, return the window that @@ -296,14 +318,16 @@ mwheel-scroll (condition-case nil (unwind-protect (let ((button (mwheel-event-button event))) - (cond ((and (eq amt 'hscroll) (eq button mouse-wheel-down-event)) + (cond ((and (eq amt 'hscroll) (memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event))) (when (and (natnump arg) (> arg 0)) (setq mouse-wheel-scroll-amount-horizontal arg)) (funcall (if mouse-wheel-flip-direction mwheel-scroll-left-function mwheel-scroll-right-function) mouse-wheel-scroll-amount-horizontal)) - ((eq button mouse-wheel-down-event) + ((memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event)) (condition-case nil (funcall mwheel-scroll-down-function amt) ;; Make sure we do indeed scroll to the beginning of ;; the buffer. @@ -318,23 +342,27 @@ mwheel-scroll ;; for a reason that escapes me. This problem seems ;; to only affect scroll-down. --Stef (set-window-start (selected-window) (point-min)))))) - ((and (eq amt 'hscroll) (eq button mouse-wheel-up-event)) + ((and (eq amt 'hscroll) (memq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event))) (when (and (natnump arg) (> arg 0)) (setq mouse-wheel-scroll-amount-horizontal arg)) (funcall (if mouse-wheel-flip-direction mwheel-scroll-right-function mwheel-scroll-left-function) mouse-wheel-scroll-amount-horizontal)) - ((eq button mouse-wheel-up-event) + ((memq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event)) (condition-case nil (funcall mwheel-scroll-up-function amt) ;; Make sure we do indeed scroll to the end of the buffer. (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) - ((eq button mouse-wheel-left-event) ; for tilt scroll + ((memq button (list mouse-wheel-left-event + mouse-wheel-left-alternate-event)) ; for tilt scroll (when mouse-wheel-tilt-scroll (funcall (if mouse-wheel-flip-direction mwheel-scroll-right-function mwheel-scroll-left-function) amt))) - ((eq button mouse-wheel-right-event) ; for tilt scroll + ((memq button (list mouse-wheel-right-event + mouse-wheel-right-alternate-event)) ; for tilt scroll (when mouse-wheel-tilt-scroll (funcall (if mouse-wheel-flip-direction mwheel-scroll-left-function @@ -378,9 +406,11 @@ mouse-wheel-text-scale (button (mwheel-event-button event))) (select-window scroll-window 'mark-for-redisplay) (unwind-protect - (cond ((eq button mouse-wheel-down-event) + (cond ((memq button (list mouse-wheel-down-event + mouse-wheel-down-alternate-event)) (text-scale-increase 1)) - ((eq button mouse-wheel-up-event) + ((eq button (list mouse-wheel-up-event + mouse-wheel-up-alternate-event)) (text-scale-decrease 1))) (select-window selected-window)))) @@ -432,15 +462,23 @@ mouse-wheel--setup-bindings (cond ;; Bindings for changing font size. ((and (consp binding) (eq (cdr binding) 'text-scale)) - (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event)) - (mouse-wheel--add-binding `[,(list (caar binding) event)] - 'mouse-wheel-text-scale))) + (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event + mouse-wheel-down-alternate-event + mouse-wheel-up-alternate-event)) + (when event + (mouse-wheel--add-binding `[,(list (caar binding) event)] + 'mouse-wheel-text-scale)))) ;; Bindings for scrolling. (t (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event - mouse-wheel-left-event mouse-wheel-right-event)) - (dolist (key (mouse-wheel--create-scroll-keys binding event)) - (mouse-wheel--add-binding key 'mwheel-scroll))))))) + mouse-wheel-left-event mouse-wheel-right-event + mouse-wheel-down-alternate-event + mouse-wheel-up-alternate-event + mouse-wheel-left-alternate-event + mouse-wheel-right-alternate-event)) + (when event + (dolist (key (mouse-wheel--create-scroll-keys binding event)) + (mouse-wheel--add-binding key 'mwheel-scroll)))))))) (when mouse-wheel-mode (mouse-wheel--setup-bindings)) diff --git a/src/Makefile.in b/src/Makefile.in index 4c5535f8ad..0aaaf91d39 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -258,6 +258,9 @@ XINERAMA_CFLAGS = XFIXES_LIBS = @XFIXES_LIBS@ XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XINPUT_LIBS = @XINPUT_LIBS@ +XINPUT_CFLAGS = @XINPUT_CFLAGS@ + XDBE_LIBS = @XDBE_LIBS@ XDBE_CFLAGS = @XDBE_CFLAGS@ @@ -374,7 +377,7 @@ EMACS_CFLAGS= $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \ $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ - $(WEBKIT_CFLAGS) $(WEBP_CFLAGS) $(LCMS2_CFLAGS) \ + $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \ $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \ @@ -524,7 +527,7 @@ LIBES = $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ - $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) + $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) ## FORCE it so that admin/unidata can decide whether this file is ## up-to-date. Although since charprop depends on bootstrap-emacs, diff --git a/src/gtkutil.c b/src/gtkutil.c index a9eabf47d8..9e676cd025 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -47,6 +47,10 @@ Copyright (C) 2003-2021 Free Software Foundation, Inc. #include +#ifdef HAVE_XINPUT2 +#include +#endif + #ifdef HAVE_XFT #include #endif @@ -839,6 +843,23 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, } #endif +#if defined HAVE_GTK3 && defined HAVE_XINPUT2 +bool +xg_is_menu_window (Display *dpy, Window wdesc) +{ + GtkWidget *gwdesc = xg_win_to_widget (dpy, wdesc); + + if (GTK_IS_WINDOW (gwdesc)) + { + GtkWidget *fw = gtk_bin_get_child (GTK_BIN (gwdesc)); + if (GTK_IS_MENU (fw)) + return true; + } + + return false; +} +#endif + /* Make a geometry string and pass that to GTK. It seems this is the only way to get geometry position right if the user explicitly asked for a position when starting Emacs. @@ -3589,6 +3610,18 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) if (! x->menubar_widget) return 0; +#ifdef HAVE_XINPUT2 + XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; + if (event->type == GenericEvent) /* XI_ButtonPress or XI_ButtonRelease */ + { + if (! (xev->event_x >= 0 + && xev->event_x < FRAME_PIXEL_WIDTH (f) + && xev->event_y >= 0 + && xev->event_y < FRAME_MENUBAR_HEIGHT (f))) + return 0; + } + else +#endif if (! (event->xbutton.x >= 0 && event->xbutton.x < FRAME_PIXEL_WIDTH (f) && event->xbutton.y >= 0 @@ -3597,7 +3630,12 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) return 0; gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); - gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); +#ifdef HAVE_XINPUT2 + if (event->type == GenericEvent) + gw = gdk_x11_window_lookup_for_display (gdpy, xev->event); + else +#endif + gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); if (! gw) return 0; gevent.any.window = gw; gevent.any.type = GDK_NOTHING; @@ -4244,7 +4282,20 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) { bool retval = 0; +#ifdef HAVE_XINPUT2 + XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; + if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 + && event->type == GenericEvent + && (event->xgeneric.extension + == FRAME_DISPLAY_INFO (f)->xi2_opcode) + && ((event->xgeneric.evtype == XI_ButtonPress + && xev->detail < 4) + || (event->xgeneric.evtype == XI_Motion))) + || (event->type == ButtonPress + && event->xbutton.button < 4))) +#else if (f && event->type == ButtonPress && event->xbutton.button < 4) +#endif /* HAVE_XINPUT2 */ { /* Check if press occurred outside the edit widget. */ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); @@ -4262,10 +4313,29 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL); #endif retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget); +#ifdef HAVE_XINPUT2 + GtkWidget *grab = gtk_grab_get_current (); + if (event->type == GenericEvent + && event->xgeneric.evtype == XI_Motion) + retval = retval || (grab && GTK_IS_SCROLLBAR (grab)); +#endif } +#ifdef HAVE_XINPUT2 + else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 + && event->type == GenericEvent + && (event->xgeneric.extension + == FRAME_DISPLAY_INFO (f)->xi2_opcode) + && ((event->xgeneric.evtype == XI_ButtonRelease + && xev->detail < 4) + || (event->xgeneric.evtype == XI_Motion))) + || ((event->type == ButtonRelease + && event->xbutton.button < 4) + || event->type == MotionNotify))) +#else else if (f && ((event->type == ButtonRelease && event->xbutton.button < 4) || event->type == MotionNotify)) +#endif /* HAVE_XINPUT2 */ { /* If we are releasing or moving the scroll bar, it has the grab. */ GtkWidget *w = gtk_grab_get_current (); diff --git a/src/gtkutil.h b/src/gtkutil.h index 31a12cd5d3..95dd75b7fa 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -192,6 +192,10 @@ #define XG_ITEM_DATA "emacs_menuitem" extern void xg_print_frames_dialog (Lisp_Object); #endif +#if defined HAVE_GTK3 && defined HAVE_XINPUT2 +extern bool xg_is_menu_window (Display *dpy, Window); +#endif + /* Mark all callback data that are Lisp_object:s during GC. */ extern void xg_mark_data (void); diff --git a/src/xfns.c b/src/xfns.c index 785ae3baca..b33b40b330 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -57,6 +57,10 @@ Copyright (C) 1989, 1992-2021 Free Software Foundation, Inc. #include #endif +#ifdef HAVE_XINPUT2 +#include +#endif + #ifdef USE_X_TOOLKIT #include @@ -2912,6 +2916,37 @@ initial_set_up_x_back_buffer (struct frame *f) unblock_input (); } +#if defined HAVE_XINPUT2 && !defined USE_GTK +static void +setup_xi_event_mask (struct frame *f) +{ + XIEventMask mask; + ptrdiff_t l = XIMaskLen (XI_LASTEVENT); + unsigned char *m; + + mask.mask = m = alloca (l); + memset (m, 0, l); + mask.mask_len = l; + mask.deviceid = XIAllMasterDevices; + + XISetMask (m, XI_ButtonPress); + XISetMask (m, XI_ButtonRelease); + XISetMask (m, XI_KeyPress); + XISetMask (m, XI_KeyRelease); + XISetMask (m, XI_Motion); + XISetMask (m, XI_Enter); + XISetMask (m, XI_Leave); + XISetMask (m, XI_FocusIn); + XISetMask (m, XI_FocusOut); + XISetMask (m, XI_PropertyEvent); + XISetMask (m, XI_HierarchyChanged); + XISetMask (m, XI_DeviceChanged); + XISelectEvents (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + &mask, 1); +} +#endif + #ifdef USE_X_TOOLKIT /* Create and set up the X widget for frame F. */ @@ -3074,6 +3109,11 @@ x_window (struct frame *f, long window_prompting) class_hints.res_class = SSDATA (Vx_resource_class); XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); +#ifdef HAVE_XINPUT2 + if (FRAME_DISPLAY_INFO (f)->supports_xi2) + setup_xi_event_mask (f); +#endif + #ifdef HAVE_X_I18N FRAME_XIC (f) = NULL; if (use_xim) @@ -3254,6 +3294,11 @@ x_window (struct frame *f) } #endif /* HAVE_X_I18N */ +#ifdef HAVE_XINPUT2 + if (FRAME_DISPLAY_INFO (f)->supports_xi2) + setup_xi_event_mask (f); +#endif + validate_x_resource_name (); class_hints.res_name = SSDATA (Vx_resource_name); @@ -8038,6 +8083,11 @@ syms_of_xfns (void) /* Tell Emacs about this window system. */ Fprovide (Qx, Qnil); +#ifdef HAVE_XINPUT2 + DEFSYM (Qxinput2, "xinput2"); + Fprovide (Qxinput2, Qnil); +#endif + #ifdef USE_X_TOOLKIT Fprovide (intern_c_string ("x-toolkit"), Qnil); #ifdef USE_MOTIF diff --git a/src/xmenu.c b/src/xmenu.c index ea2cbab203..07255911f9 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -105,7 +105,11 @@ Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2021 Free Software /* Flag which when set indicates a dialog or menu has been posted by Xt on behalf of one of the widget sets. */ +#ifndef HAVE_XINPUT2 static int popup_activated_flag; +#else +int popup_activated_flag; +#endif #ifdef USE_X_TOOLKIT diff --git a/src/xterm.c b/src/xterm.c index 816b6dc5a8..63754a2cb6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -42,6 +42,10 @@ Copyright (C) 1989, 1993-2021 Free Software Foundation, Inc. #include #endif +#ifdef HAVE_XINPUT2 +#include +#endif + /* Load sys/types.h if not already loaded. In some systems loading it twice is suicidal. */ #ifndef makedev @@ -223,9 +227,15 @@ #define XtNinitialState "initialState" static void x_check_fullscreen (struct frame *); static void x_check_expected_move (struct frame *, int, int); static void x_sync_with_move (struct frame *, int, int, bool); +#ifndef HAVE_XINPUT2 static int handle_one_xevent (struct x_display_info *, const XEvent *, int *, struct input_event *); +#else +static int handle_one_xevent (struct x_display_info *, + XEvent *, int *, + struct input_event *); +#endif #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK static int x_dispatch_event (XEvent *, Display *); #endif @@ -335,6 +345,224 @@ x_extension_initialize (struct x_display_info *dpyinfo) dpyinfo->ext_codes = ext_codes; } + +#ifdef HAVE_XINPUT2 + +/* Free all XI2 devices on dpyinfo. */ +static void +x_free_xi_devices (struct x_display_info *dpyinfo) +{ + block_input (); + + if (dpyinfo->num_devices) + { + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, + CurrentTime); + xfree (dpyinfo->devices[i].valuators); + } + + xfree (dpyinfo->devices); + dpyinfo->devices = NULL; + dpyinfo->num_devices = 0; + } + + unblock_input (); +} + +/* Setup valuator tracking for XI2 master devices on + DPYINFO->display. */ + +static void +x_init_master_valuators (struct x_display_info *dpyinfo) +{ + int ndevices; + XIDeviceInfo *infos; + + block_input (); + x_free_xi_devices (dpyinfo); + infos = XIQueryDevice (dpyinfo->display, + XIAllMasterDevices, + &ndevices); + + if (!ndevices) + { + XIFreeDeviceInfo (infos); + unblock_input (); + return; + } + + int actual_devices = 0; + dpyinfo->devices = xmalloc (sizeof *dpyinfo->devices * ndevices); + + for (int i = 0; i < ndevices; ++i) + { + XIDeviceInfo *device = &infos[i]; + + if (device->enabled) + { + int actual_valuator_count = 0; + struct xi_device_t *xi_device = &dpyinfo->devices[actual_devices++]; + xi_device->device_id = device->deviceid; + xi_device->grab = 0; + xi_device->valuators = + xmalloc (sizeof *xi_device->valuators * device->num_classes); + + for (int c = 0; c < device->num_classes; ++c) + { + switch (device->classes[c]->type) + { +#ifdef XIScrollClass /* XInput 2.1 */ + case XIScrollClass: + { + XIScrollClassInfo *info = + (XIScrollClassInfo *) device->classes[c]; + struct xi_scroll_valuator_t *valuator = + &xi_device->valuators[actual_valuator_count++]; + + valuator->horizontal + = (info->scroll_type == XIScrollTypeHorizontal); + valuator->invalid_p = true; + valuator->emacs_value = DBL_MIN; + valuator->increment = info->increment; + valuator->number = info->number; + break; + } +#endif + default: + break; + } + } + xi_device->scroll_valuator_count = actual_valuator_count; + } + } + + dpyinfo->num_devices = actual_devices; + XIFreeDeviceInfo (infos); + unblock_input (); +} + +/* Return the delta of the scroll valuator VALUATOR_NUMBER under + DEVICE_ID in the display DPYINFO with VALUE. The valuator's + valuator will be set to VALUE afterwards. In case no scroll + valuator is found, or if device_id is not known to Emacs, DBL_MAX + is returned. Otherwise, the valuator is returned in + VALUATOR_RETURN. */ +static double +x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id, + int valuator_number, double value, + struct xi_scroll_valuator_t **valuator_return) +{ + block_input (); + + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + struct xi_device_t *device = &dpyinfo->devices[i]; + + if (device->device_id == device_id) + { + for (int j = 0; j < device->scroll_valuator_count; ++j) + { + struct xi_scroll_valuator_t *sv = &device->valuators[j]; + + if (sv->number == valuator_number) + { + if (sv->invalid_p) + { + sv->current_value = value; + sv->invalid_p = false; + *valuator_return = sv; + + unblock_input (); + return 0.0; + } + else + { + double delta = (sv->current_value - value) / sv->increment; + sv->current_value = value; + *valuator_return = sv; + + unblock_input (); + return delta; + } + } + } + + unblock_input (); + return DBL_MAX; + } + } + + unblock_input (); + return DBL_MAX; +} + +static struct xi_device_t * +xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) +{ + for (int i = 0; i < dpyinfo->num_devices; ++i) + { + if (dpyinfo->devices[i].device_id == deviceid) + return &dpyinfo->devices[i]; + } + + return NULL; +} + +static void +xi_grab_or_ungrab_device (struct xi_device_t *device, + struct x_display_info *dpyinfo, + Window window) +{ + XIEventMask mask; + ptrdiff_t l = XIMaskLen (XI_LASTEVENT); + unsigned char *m; + mask.mask = m = alloca (l); + memset (m, 0, l); + mask.mask_len = l; + + XISetMask (m, XI_ButtonPress); + XISetMask (m, XI_ButtonRelease); + XISetMask (m, XI_Motion); + XISetMask (m, XI_Enter); + XISetMask (m, XI_Leave); + + if (device->grab) + { + XIGrabDevice (dpyinfo->display, device->device_id, window, + CurrentTime, None, GrabModeAsync, + GrabModeAsync, True, &mask); + } + else + { + XIUngrabDevice (dpyinfo->display, device->device_id, CurrentTime); + } +} + +static void +xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) +{ + struct xi_device_t *device = xi_device_from_id (dpyinfo, id); + struct xi_scroll_valuator_t *valuator; + + if (!device) + return; + + if (!device->scroll_valuator_count) + return; + + for (int i = 0; i < device->scroll_valuator_count; ++i) + { + valuator = &device->valuators[i]; + valuator->invalid_p = true; + } + + return; +} + +#endif + void x_cr_destroy_frame_context (struct frame *f) { @@ -4768,7 +4996,16 @@ x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc) x_menubar_window_to_frame (struct x_display_info *dpyinfo, const XEvent *event) { - Window wdesc = event->xany.window; + Window wdesc; +#ifdef HAVE_XINPUT2 + if (event->type == GenericEvent + && dpyinfo->supports_xi2 + && (event->xcookie.evtype == XI_ButtonPress + || event->xcookie.evtype == XI_ButtonRelease)) + wdesc = ((XIDeviceEvent *) event->xcookie.data)->event; + else +#endif + wdesc = event->xany.window; Lisp_Object tail, frame; struct frame *f; struct x_output *x; @@ -4871,6 +5108,29 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame, } break; +#ifdef HAVE_XINPUT2 + case GenericEvent: + { + XIEvent *xi_event = (XIEvent *) event; + + struct frame *focus_frame = dpyinfo->x_focus_event_frame; + int focus_state + = focus_frame ? focus_frame->output_data.x->focus_state : 0; + + if (!((xi_event->evtype == XI_Enter + || xi_event->evtype == XI_Leave) + && (focus_state & FOCUS_EXPLICIT))) + x_focus_changed ((xi_event->evtype == XI_Enter + || xi_event->evtype == XI_FocusIn + ? FocusIn : FocusOut), + (xi_event->evtype == XI_Enter + || xi_event->evtype == XI_Leave + ? FOCUS_IMPLICIT : FOCUS_EXPLICIT), + dpyinfo, frame, bufp); + break; + } +#endif + case FocusIn: case FocusOut: /* Ignore transient focus events from hotkeys, window manager @@ -7975,7 +8235,11 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc) static int handle_one_xevent (struct x_display_info *dpyinfo, +#ifndef HAVE_XINPUT2 const XEvent *event, +#else + XEvent *event, +#endif int *finish, struct input_event *hold_quit) { union buffered_input_event inev; @@ -8001,7 +8265,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, inev.ie.kind = NO_EVENT; inev.ie.arg = Qnil; - any = x_any_window_to_frame (dpyinfo, event->xany.window); +#ifdef HAVE_XINPUT2 + if (event->type != GenericEvent) +#endif + any = x_any_window_to_frame (dpyinfo, event->xany.window); +#ifdef HAVE_XINPUT2 + else + any = NULL; +#endif if (any && any->wait_event_type == event->type) any->wait_event_type = 0; /* Indicates we got it. */ @@ -8480,6 +8751,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case MapNotify: +#if defined HAVE_XINPUT2 && defined HAVE_GTK3 + if (xg_is_menu_window (dpyinfo->display, event->xmap.window)) + popup_activated_flag = 1; +#endif /* We use x_top_window_to_frame because map events can come for sub-windows and they don't mean that the frame is visible. */ @@ -9518,6 +9793,785 @@ handle_one_xevent (struct x_display_info *dpyinfo, case DestroyNotify: xft_settings_event (dpyinfo, event); break; +#ifdef HAVE_XINPUT2 + case GenericEvent: + { + if (!dpyinfo->supports_xi2) + goto OTHER; + if (event->xgeneric.extension != dpyinfo->xi2_opcode) + /* Not an XI2 event. */ + goto OTHER; + bool must_free_data = false; + XIEvent *xi_event = (XIEvent *) event->xcookie.data; + /* Sometimes the event is already claimed by GTK, which + will free its data in due course. */ + if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie)) + { + must_free_data = true; + xi_event = (XIEvent *) event->xcookie.data; + } + + XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; + XILeaveEvent *leave = (XILeaveEvent *) xi_event; + XIEnterEvent *enter = (XIEnterEvent *) xi_event; + XIFocusInEvent *focusin = (XIFocusInEvent *) xi_event; + XIFocusOutEvent *focusout = (XIFocusOutEvent *) xi_event; + XIValuatorState *states; + double *values; + bool found_valuator = false; + + /* A fake XMotionEvent for x_note_mouse_movement. */ + XMotionEvent ev; + /* A fake XButtonEvent for x_construct_mouse_click. */ + XButtonEvent bv; + + if (!xi_event) + { + eassert (!must_free_data); + goto OTHER; + } + + switch (event->xcookie.evtype) + { + case XI_FocusIn: + any = x_any_window_to_frame (dpyinfo, focusin->event); +#ifndef USE_GTK + /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap + minimized/iconified windows; thus, for those WMs we won't get + a MapNotify when unminimizing/deconifying. Check here if we + are deiconizing a window (Bug42655). + + But don't do that on GTK since it may cause a plain invisible + frame get reported as iconified, compare + https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. + That is fixed above but bites us here again. */ + f = any; + if (f && FRAME_ICONIFIED_P (f)) + { + SET_FRAME_VISIBLE (f, 1); + SET_FRAME_ICONIFIED (f, false); + f->output_data.x->has_been_visible = true; + inev.ie.kind = DEICONIFY_EVENT; + XSETFRAME (inev.ie.frame_or_window, f); + } +#endif /* USE_GTK */ + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + goto XI_OTHER; + case XI_FocusOut: + any = x_any_window_to_frame (dpyinfo, focusout->event); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + goto XI_OTHER; + case XI_Enter: + any = x_any_window_to_frame (dpyinfo, enter->event); + ev.x = lrint (enter->event_x); + ev.y = lrint (enter->event_y); + ev.window = leave->event; + + x_display_set_last_user_time (dpyinfo, xi_event->time); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_reset_scroll_valuators_for_device_id (dpyinfo, enter->deviceid); + f = any; + + if (f && x_mouse_click_focus_ignore_position) + ignore_next_mouse_click_timeout = xi_event->time + 200; + + /* EnterNotify counts as mouse movement, + so update things that depend on mouse position. */ + if (f && !f->output_data.x->hourglass_p) + x_note_mouse_movement (f, &ev); +#ifdef USE_GTK + /* We may get an EnterNotify on the buttons in the toolbar. In that + case we moved out of any highlighted area and need to note this. */ + if (!f && dpyinfo->last_mouse_glyph_frame) + x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); +#endif + goto XI_OTHER; + case XI_Leave: + ev.x = lrint (leave->event_x); + ev.y = lrint (leave->event_y); + ev.window = leave->event; + any = x_any_window_to_frame (dpyinfo, leave->event); + + x_display_set_last_user_time (dpyinfo, xi_event->time); + x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_reset_scroll_valuators_for_device_id (dpyinfo, leave->deviceid); + + f = x_top_window_to_frame (dpyinfo, leave->event); + if (f) + { + if (f == hlinfo->mouse_face_mouse_frame) + { + /* If we move outside the frame, then we're + certainly no longer on any text in the frame. */ + clear_mouse_face (hlinfo); + hlinfo->mouse_face_mouse_frame = 0; + } + + /* Generate a nil HELP_EVENT to cancel a help-echo. + Do it only if there's something to cancel. + Otherwise, the startup message is cleared when + the mouse leaves the frame. */ + if (any_help_event_p) + do_help = -1; + } +#ifdef USE_GTK + /* See comment in EnterNotify above */ + else if (dpyinfo->last_mouse_glyph_frame) + x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); +#endif + goto XI_OTHER; + case XI_Motion: + /* First test if there is some kind of scroll event + here! */ + states = &xev->valuators; + values = states->values; + + x_display_set_last_user_time (dpyinfo, xi_event->time); + + for (int i = 0; i < states->mask_len * 8; i++) + { + if (XIMaskIsSet (states->mask, i)) + { + block_input (); + + struct xi_scroll_valuator_t *val; + double delta; + + delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, + i, *values, &val); + + if (delta != DBL_MAX) + { + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + found_valuator = true; + + if (signbit (delta) != signbit (val->emacs_value)) + val->emacs_value = 0; + + val->emacs_value += delta; + + if (!f) + { + f = x_any_window_to_frame (dpyinfo, xev->event); + + if (!f) + { + unblock_input (); + goto XI_OTHER; + } + } + + bool s = signbit (val->emacs_value); + inev.ie.kind = (val->horizontal + ? HORIZ_WHEEL_EVENT + : WHEEL_EVENT); + inev.ie.timestamp = xev->time; + + XSETINT (inev.ie.x, lrint (xev->event_x)); + XSETINT (inev.ie.y, lrint (xev->event_y)); + XSETFRAME (inev.ie.frame_or_window, f); + + inev.ie.modifiers = !s ? up_modifier : down_modifier; + inev.ie.modifiers + |= x_x_to_emacs_modifiers (dpyinfo, + xev->mods.effective); + inev.ie.arg = Qnil; + + kbd_buffer_store_event_hold (&inev.ie, hold_quit); + + val->emacs_value = 0; + } + unblock_input (); + values++; + } + + inev.ie.kind = NO_EVENT; + } + + if (found_valuator) + goto XI_OTHER; + + ev.x = lrint (xev->event_x); + ev.y = lrint (xev->event_y); + ev.window = xev->event; + + previous_help_echo_string = help_echo_string; + help_echo_string = Qnil; + + if (hlinfo->mouse_face_hidden) + { + hlinfo->mouse_face_hidden = false; + clear_mouse_face (hlinfo); + } + + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + +#ifdef USE_GTK + if (f && xg_event_is_for_scrollbar (f, event)) + f = 0; +#endif + if (f) + { + /* Maybe generate a SELECT_WINDOW_EVENT for + `mouse-autoselect-window' but don't let popup menus + interfere with this (Bug#1261). */ + if (!NILP (Vmouse_autoselect_window) + && !popup_activated () + /* Don't switch if we're currently in the minibuffer. + This tries to work around problems where the + minibuffer gets unselected unexpectedly, and where + you then have to move your mouse all the way down to + the minibuffer to select it. */ + && !MINI_WINDOW_P (XWINDOW (selected_window)) + /* With `focus-follows-mouse' non-nil create an event + also when the target window is on another frame. */ + && (f == XFRAME (selected_frame) + || !NILP (focus_follows_mouse))) + { + static Lisp_Object last_mouse_window; + Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); + + /* A window will be autoselected only when it is not + selected now and the last mouse movement event was + not in it. The remainder of the code is a bit vague + wrt what a "window" is. For immediate autoselection, + the window is usually the entire window but for GTK + where the scroll bars don't count. For delayed + autoselection the window is usually the window's text + area including the margins. */ + if (WINDOWP (window) + && !EQ (window, last_mouse_window) + && !EQ (window, selected_window)) + { + inev.ie.kind = SELECT_WINDOW_EVENT; + inev.ie.frame_or_window = window; + } + + /* Remember the last window where we saw the mouse. */ + last_mouse_window = window; + } + + if (!x_note_mouse_movement (f, &ev)) + help_echo_string = previous_help_echo_string; + } + else + { +#ifndef USE_TOOLKIT_SCROLL_BARS + struct scroll_bar *bar + = x_window_to_scroll_bar (xi_event->display, xev->event, 2); + + if (bar) + x_scroll_bar_note_movement (bar, &ev); +#endif /* USE_TOOLKIT_SCROLL_BARS */ + + /* If we move outside the frame, then we're + certainly no longer on any text in the frame. */ + clear_mouse_face (hlinfo); + } + + /* If the contents of the global variable help_echo_string + has changed, generate a HELP_EVENT. */ + if (!NILP (help_echo_string) + || !NILP (previous_help_echo_string)) + do_help = 1; + goto XI_OTHER; + case XI_ButtonRelease: + case XI_ButtonPress: + { + /* If we decide we want to generate an event to be seen + by the rest of Emacs, we put it here. */ + Lisp_Object tab_bar_arg = Qnil; + bool tab_bar_p = false; + bool tool_bar_p = false; + struct xi_device_t *device; + + /* Ignore emulated scroll events when XI2 native + scroll events are present. */ + if (dpyinfo->xi2_version >= 1 && xev->detail >= 4 + && xev->detail <= 8) + goto XI_OTHER; + + device = xi_device_from_id (dpyinfo, xev->deviceid); + + bv.button = xev->detail; + bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; + bv.x = lrint (xev->event_x); + bv.y = lrint (xev->event_y); + bv.window = xev->event; + bv.state = xev->mods.base + | xev->mods.effective + | xev->mods.latched + | xev->mods.locked; + + memset (&compose_status, 0, sizeof (compose_status)); + dpyinfo->last_mouse_glyph_frame = NULL; + x_display_set_last_user_time (dpyinfo, xev->time); + + f = mouse_or_wdesc_frame (dpyinfo, xev->event); + + if (f && xev->evtype == XI_ButtonPress + && !popup_activated () + && !x_window_to_scroll_bar (xev->display, xev->event, 2) + && !FRAME_NO_ACCEPT_FOCUS (f)) + { + /* When clicking into a child frame or when clicking + into a parent frame with the child frame selected and + `no-accept-focus' is not set, select the clicked + frame. */ + struct frame *hf = dpyinfo->highlight_frame; + + if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf))) + { + block_input (); + XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + RevertToParent, CurrentTime); + if (FRAME_PARENT_FRAME (f)) + XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); + unblock_input (); + } + } + +#ifdef USE_GTK + if (f && xg_event_is_for_scrollbar (f, event)) + f = 0; +#endif + + if (f) + { + /* Is this in the tab-bar? */ + if (WINDOWP (f->tab_bar_window) + && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window))) + { + Lisp_Object window; + int x = bv.x; + int y = bv.y; + + window = window_from_coordinates (f, x, y, 0, true, true); + tab_bar_p = EQ (window, f->tab_bar_window); + + if (tab_bar_p) + tab_bar_arg = handle_tab_bar_click + (f, x, y, xev->evtype == XI_ButtonPress, + x_x_to_emacs_modifiers (dpyinfo, bv.state)); + } + +#if ! defined (USE_GTK) + /* Is this in the tool-bar? */ + if (WINDOWP (f->tool_bar_window) + && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window))) + { + Lisp_Object window; + int x = bv.x; + int y = bv.y; + + window = window_from_coordinates (f, x, y, 0, true, true); + tool_bar_p = EQ (window, f->tool_bar_window); + + if (tool_bar_p && xev->detail < 4) + handle_tool_bar_click + (f, x, y, xev->evtype == XI_ButtonPress, + x_x_to_emacs_modifiers (dpyinfo, bv.state)); + } +#endif /* !USE_GTK */ + + if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) + if (! popup_activated ()) +#endif + { + if (ignore_next_mouse_click_timeout) + { + if (xev->evtype == XI_ButtonPress + && xev->time > ignore_next_mouse_click_timeout) + { + ignore_next_mouse_click_timeout = 0; + x_construct_mouse_click (&inev.ie, &bv, f); + } + if (xev->evtype == XI_ButtonRelease) + ignore_next_mouse_click_timeout = 0; + } + else + x_construct_mouse_click (&inev.ie, &bv, f); + + if (!NILP (tab_bar_arg)) + inev.ie.arg = tab_bar_arg; + } + if (FRAME_X_EMBEDDED_P (f)) + xembed_send_message (f, xev->time, + XEMBED_REQUEST_FOCUS, 0, 0, 0); + } + + if (xev->evtype == XI_ButtonPress) + { + dpyinfo->grabbed |= (1 << xev->detail); + device->grab |= (1 << xev->detail); + dpyinfo->last_mouse_frame = f; + if (f && !tab_bar_p) + f->last_tab_bar_item = -1; +#if ! defined (USE_GTK) + if (f && !tool_bar_p) + f->last_tool_bar_item = -1; +#endif /* not USE_GTK */ + + } + else + { + dpyinfo->grabbed &= ~(1 << xev->detail); + device->grab &= ~(1 << xev->detail); + } + + xi_grab_or_ungrab_device (device, dpyinfo, xev->event); + + if (f) + f->mouse_moved = false; + +#if defined (USE_GTK) + /* No Xt toolkit currently available has support for XI2. + So the code here assumes use of GTK. */ + f = x_menubar_window_to_frame (dpyinfo, event); + if (f /* Gtk+ menus only react to the first three buttons. */ + && xev->detail < 3) + { + /* What is done with Core Input ButtonPressed is not + possible here, because GenericEvents cannot be saved. */ + bool was_waiting_for_input = waiting_for_input; + /* This hack was adopted from the NS port. Whether + or not it is actually safe is a different story + altogether. */ + if (waiting_for_input) + waiting_for_input = 0; + set_frame_menubar (f, true); + waiting_for_input = was_waiting_for_input; + } +#endif + goto XI_OTHER; + } + case XI_KeyPress: + { + int state = xev->mods.base + | xev->mods.effective + | xev->mods.latched + | xev->mods.locked; + Lisp_Object c; +#ifdef HAVE_XKB + unsigned int mods_rtrn; +#endif + int keycode = xev->detail; + KeySym keysym; + char copy_buffer[81]; + char *copy_bufptr = copy_buffer; + unsigned char *copy_ubufptr; +#ifdef HAVE_XKB + int copy_bufsiz = sizeof (copy_buffer); +#endif + ptrdiff_t i; + int nchars, len; + +#ifdef HAVE_XKB + if (dpyinfo->xkb_desc) + { + if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode, + state, &mods_rtrn, &keysym)) + goto XI_OTHER; + } + else + { +#endif + int keysyms_per_keycode_return; + KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1, + &keysyms_per_keycode_return); + if (!(keysym = ksms[0])) + { + XFree (ksms); + goto XI_OTHER; + } + XFree (ksms); +#ifdef HAVE_XKB + } +#endif + + if (keysym == NoSymbol) + goto XI_OTHER; + + x_display_set_last_user_time (dpyinfo, xev->time); + ignore_next_mouse_click_timeout = 0; + +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) + /* Dispatch XI_KeyPress events when in menu. */ + if (popup_activated ()) + goto XI_OTHER; +#endif + + f = x_any_window_to_frame (dpyinfo, xev->event); + + /* If mouse-highlight is an integer, input clears out + mouse highlighting. */ + if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight) + && (f == 0 +#if ! defined (USE_GTK) + || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) +#endif + || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) + ) + { + clear_mouse_face (hlinfo); + hlinfo->mouse_face_hidden = true; + } + + if (f != 0) + { +#ifdef USE_GTK + /* Don't pass keys to GTK. A Tab will shift focus to the + tool bar in GTK 2.4. Keys will still go to menus and + dialogs because in that case popup_activated is nonzero + (see above). */ + *finish = X_EVENT_DROP; +#endif + /* If not using XIM/XIC, and a compose sequence is in progress, + we break here. Otherwise, chars_matched is always 0. */ + if (compose_status.chars_matched > 0 && nbytes == 0) + goto XI_OTHER; + + memset (&compose_status, 0, sizeof (compose_status)); + + XSETFRAME (inev.ie.frame_or_window, f); + inev.ie.modifiers + = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state); + inev.ie.timestamp = xev->time; + + /* First deal with keysyms which have defined + translations to characters. */ + if (keysym >= 32 && keysym < 128) + /* Avoid explicitly decoding each ASCII character. */ + { + inev.ie.kind = ASCII_KEYSTROKE_EVENT; + inev.ie.code = keysym; + + goto xi_done_keysym; + } + + /* Keysyms directly mapped to Unicode characters. */ + if (keysym >= 0x01000000 && keysym <= 0x0110FFFF) + { + if (keysym < 0x01000080) + inev.ie.kind = ASCII_KEYSTROKE_EVENT; + else + inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; + inev.ie.code = keysym & 0xFFFFFF; + goto xi_done_keysym; + } + + /* Now non-ASCII. */ + if (HASH_TABLE_P (Vx_keysym_table) + && (c = Fgethash (make_fixnum (keysym), + Vx_keysym_table, + Qnil), + FIXNATP (c))) + { + inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c)) + ? ASCII_KEYSTROKE_EVENT + : MULTIBYTE_CHAR_KEYSTROKE_EVENT); + inev.ie.code = XFIXNAT (c); + goto xi_done_keysym; + } + + /* Random non-modifier sorts of keysyms. */ + if (((keysym >= XK_BackSpace && keysym <= XK_Escape) + || keysym == XK_Delete +#ifdef XK_ISO_Left_Tab + || (keysym >= XK_ISO_Left_Tab + && keysym <= XK_ISO_Enter) +#endif + || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */ + || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */ +#ifdef HPUX + /* This recognizes the "extended function + keys". It seems there's no cleaner way. + Test IsModifierKey to avoid handling + mode_switch incorrectly. */ + || (XK_Select <= keysym && keysym < XK_KP_Space) +#endif +#ifdef XK_dead_circumflex + || keysym == XK_dead_circumflex +#endif +#ifdef XK_dead_grave + || keysym == XK_dead_grave +#endif +#ifdef XK_dead_tilde + || keysym == XK_dead_tilde +#endif +#ifdef XK_dead_diaeresis + || keysym == XK_dead_diaeresis +#endif +#ifdef XK_dead_macron + || keysym == XK_dead_macron +#endif +#ifdef XK_dead_degree + || keysym == XK_dead_degree +#endif +#ifdef XK_dead_acute + || keysym == XK_dead_acute +#endif +#ifdef XK_dead_cedilla + || keysym == XK_dead_cedilla +#endif +#ifdef XK_dead_breve + || keysym == XK_dead_breve +#endif +#ifdef XK_dead_ogonek + || keysym == XK_dead_ogonek +#endif +#ifdef XK_dead_caron + || keysym == XK_dead_caron +#endif +#ifdef XK_dead_doubleacute + || keysym == XK_dead_doubleacute +#endif +#ifdef XK_dead_abovedot + || keysym == XK_dead_abovedot +#endif + || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ + || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */ + /* Any "vendor-specific" key is ok. */ + || (keysym & (1 << 28)) + || (keysym != NoSymbol && nbytes == 0)) + && ! (IsModifierKey (keysym) + /* The symbols from XK_ISO_Lock + to XK_ISO_Last_Group_Lock + don't have real modifiers but + should be treated similarly to + Mode_switch by Emacs. */ +#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock + || (XK_ISO_Lock <= keysym + && keysym <= XK_ISO_Last_Group_Lock) +#endif + )) + { + STORE_KEYSYM_FOR_DEBUG (keysym); + /* make_lispy_event will convert this to a symbolic + key. */ + inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; + inev.ie.code = keysym; + goto xi_done_keysym; + } + +#ifdef HAVE_XKB + int overflow = 0; + KeySym sym = keysym; + + if (dpyinfo->xkb_desc) + { + if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, + state & ~mods_rtrn, copy_bufptr, + copy_bufsiz, &overflow))) + goto XI_OTHER; + } + else +#else + { + block_input (); + char *str = XKeysymToString (keysym); + if (!str) + { + unblock_input (); + goto XI_OTHER; + } + nbytes = strlen (str) + 1; + copy_bufptr = alloca (nbytes); + strcpy (copy_bufptr, str); + unblock_input (); + } +#endif +#ifdef HAVE_XKB + if (overflow) + { + overflow = 0; + copy_bufptr = alloca (copy_bufsiz + overflow); + keysym = sym; + if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, + state & ~mods_rtrn, copy_bufptr, + copy_bufsiz + overflow, &overflow))) + goto XI_OTHER; + + if (overflow) + goto XI_OTHER; + } +#endif + + for (i = 0, nchars = 0; i < nbytes; i++) + { + if (ASCII_CHAR_P (copy_bufptr[i])) + nchars++; + STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]); + } + + if (nchars < nbytes) + { + /* Decode the input data. */ + + setup_coding_system (Vlocale_coding_system, &coding); + coding.src_multibyte = false; + coding.dst_multibyte = true; + /* The input is converted to events, thus we can't + handle composition. Anyway, there's no XIM that + gives us composition information. */ + coding.common_flags &= ~CODING_ANNOTATION_MASK; + + SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, + nbytes); + coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; + coding.mode |= CODING_MODE_LAST_BLOCK; + decode_coding_c_string (&coding, (unsigned char *) copy_bufptr, + nbytes, Qnil); + nbytes = coding.produced; + nchars = coding.produced_char; + copy_bufptr = (char *) coding.destination; + } + + copy_ubufptr = (unsigned char *) copy_bufptr; + + /* Convert the input data to a sequence of + character events. */ + for (i = 0; i < nbytes; i += len) + { + int ch; + if (nchars == nbytes) + ch = copy_ubufptr[i], len = 1; + else + ch = string_char_and_length (copy_ubufptr + i, &len); + inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch) + ? ASCII_KEYSTROKE_EVENT + : MULTIBYTE_CHAR_KEYSTROKE_EVENT); + inev.ie.code = ch; + kbd_buffer_store_buffered_event (&inev, hold_quit); + } + + inev.ie.kind = NO_EVENT; + goto xi_done_keysym; + } + goto XI_OTHER; + } + case XI_KeyRelease: + x_display_set_last_user_time (dpyinfo, xev->time); + goto XI_OTHER; + case XI_PropertyEvent: + case XI_HierarchyChanged: + case XI_DeviceChanged: + x_init_master_valuators (dpyinfo); + goto XI_OTHER; + default: + goto XI_OTHER; + } + xi_done_keysym: + if (must_free_data) + XFreeEventData (dpyinfo->display, &event->xcookie); + goto done_keysym; + XI_OTHER: + if (must_free_data) + XFreeEventData (dpyinfo->display, &event->xcookie); + goto OTHER; + } +#endif default: OTHER: @@ -13199,6 +14253,40 @@ #define NUM_ARGV 10 dpyinfo->supports_xdbe = true; #endif +#ifdef HAVE_XINPUT2 + dpyinfo->supports_xi2 = false; + int rc; + int major = 2; +#ifdef XI_BarrierHit /* XInput 2.3 */ + int minor = 3; +#elif defined XI_TouchBegin /* XInput 2.2 */ + int minor = 2; +#elif defined XIScrollClass /* XInput 1.1 */ + int minor = 1; +#else /* Some old version of XI2 we're not interested in. */ + int minor = 0; +#endif + int fer, fee; + + if (XQueryExtension (dpyinfo->display, "XInputExtension", + &dpyinfo->xi2_opcode, &fer, &fee)) + { + rc = XIQueryVersion (dpyinfo->display, &major, &minor); + if (rc == Success) + { + dpyinfo->supports_xi2 = true; + x_init_master_valuators (dpyinfo); + } + } + dpyinfo->xi2_version = minor; +#endif + +#ifdef HAVE_XKB + dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display, + XkbAllComponentsMask, + XkbUseCoreKbd); +#endif + #if defined USE_CAIRO || defined HAVE_XFT { /* If we are using Xft, the following precautions should be made: @@ -13631,6 +14719,14 @@ x_delete_terminal (struct terminal *terminal) XrmDestroyDatabase (dpyinfo->rdb); #endif +#ifdef HAVE_XKB + if (dpyinfo->xkb_desc) + XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); +#endif +#ifdef HAVE_XINPUT2 + if (dpyinfo->supports_xi2) + x_free_xi_devices (dpyinfo); +#endif #ifdef USE_GTK xg_display_close (dpyinfo->display); #else @@ -13790,9 +14886,12 @@ x_initialize (void) void init_xterm (void) { - /* Emacs can handle only core input events, so make sure - Gtk doesn't use Xinput or Xinput2 extensions. */ +#ifndef HAVE_XINPUT2 + /* Emacs can handle only core input events when built without XI2 + support, so make sure Gtk doesn't use Xinput or Xinput2 + extensions. */ xputenv ("GDK_CORE_DEVICE_EVENTS=1"); +#endif } #endif diff --git a/src/xterm.h b/src/xterm.h index 9d9534dd62..7abe168bc6 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -88,6 +88,10 @@ #define XSync(d, b) do { gdk_window_process_all_updates (); \ #include #endif +#ifdef HAVE_XKB +#include +#endif + #include "dispextern.h" #include "termhooks.h" @@ -163,6 +167,28 @@ #define MAX_CLIP_RECTS 2 char *name; }; +#ifdef HAVE_XINPUT2 +struct xi_scroll_valuator_t +{ + bool invalid_p; + double current_value; + double emacs_value; + double increment; + + int number; + int horizontal; +}; + +struct xi_device_t +{ + int device_id; + int scroll_valuator_count; + int grab; + + struct xi_scroll_valuator_t *valuators; +}; +#endif + Status x_parse_color (struct frame *f, const char *color_name, XColor *color); @@ -474,6 +500,19 @@ #define MAX_CLIP_RECTS 2 #ifdef HAVE_XDBE bool supports_xdbe; #endif + +#ifdef HAVE_XINPUT2 + bool supports_xi2; + int xi2_version; + int xi2_opcode; + + int num_devices; + struct xi_device_t *devices; +#endif + +#ifdef HAVE_XKB + XkbDescPtr xkb_desc; +#endif }; #ifdef HAVE_X_I18N @@ -481,6 +520,11 @@ #define MAX_CLIP_RECTS 2 extern bool use_xim; #endif +#ifdef HAVE_XINPUT2 +/* Defined in xmenu.c. */ +extern int popup_activated_flag; +#endif + /* This is a chain of structures for all the X displays currently in use. */ extern struct x_display_info *x_display_list; -- 2.31.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 08:55:31 2021 Received: (at 51891) by debbugs.gnu.org; 19 Nov 2021 13:55:31 +0000 Received: from localhost ([127.0.0.1]:38465 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo4MV-0000PE-5C for submit@debbugs.gnu.org; Fri, 19 Nov 2021 08:55:31 -0500 Received: from eggs.gnu.org ([209.51.188.92]:32992) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mo4MU-0000P0-5v for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 08:55:30 -0500 Received: from [2001:470:142:3::e] (port=34330 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo4MO-0001dK-SB; Fri, 19 Nov 2021 08:55:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=suaJo1BmW+MIIO/TGOXSJe4CqMMry3IQpeZWwvhqh3w=; b=P52AKX317Pff sxAejm8yGenwkAf+zSgioU/NcvIS5p1hRkGDY0bxEkxeCxHTkJhjZK3rBp38tArpoST+X5sAZQdw/ 19ZV+qCY2GQ7X9+6JHYskUo6dxD0C1DuWG7t8Sl9dKnIQ6N61bB+WcRovv8C/vnkHU/ETPv4Ktxsf 5whFIKuohl6BiV2uHKx8O4zjId/c494r3gVBDklYbBV9aJcYwkIMoOrQCZjEF9DfVMAcXwYghR0yC 2NalK+IgB/QC51G27ORA3A37XYyItnTmCEzFem7cHiKGJEO//hGJVTEI4mpbydFOhIYinYOn+zWqF vSs5nq4R6heT+ViNw2/c0g==; Received: from [87.69.77.57] (port=2301 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mo4MH-0006gI-VK; Fri, 19 Nov 2021 08:55:22 -0500 Date: Fri, 19 Nov 2021 15:55:17 +0200 Message-Id: <837dd4uu62.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <87pmqwl1lq.fsf@yahoo.com> (message from Po Lu on Fri, 19 Nov 2021 21:24:49 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <83ilwouw9z.fsf@gnu.org> <87pmqwl1lq.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Fri, 19 Nov 2021 21:24:49 +0800 > > > Non-nil means send a wheel event only for scrolling at least one screen line. > > Thanks. Would it be OK for me to install this version of the change > that has the changes you proposed made? Sure, why not? Thanks. From debbugs-submit-bounces@debbugs.gnu.org Fri Nov 19 19:30:23 2021 Received: (at 51891) by debbugs.gnu.org; 20 Nov 2021 00:30:23 +0000 Received: from localhost ([127.0.0.1]:40903 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moEGt-0000wN-5C for submit@debbugs.gnu.org; Fri, 19 Nov 2021 19:30:23 -0500 Received: from sonic308-10.consmr.mail.ne1.yahoo.com ([66.163.187.33]:41693) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moEGr-0000w6-NE for 51891@debbugs.gnu.org; Fri, 19 Nov 2021 19:30:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637368213; bh=OmUhkxgjOApgjGTMzHf7waB6uD0UUfbX05iNXq7R5pM=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=pEFKQa+p8pSCuEAOXnO+XGXrJdHs+fjs19lczZ8H6j3ry3fRpl1E2ANfseVVyD2+5FrMIR2YfJnJWptyZuUAG7pQfI7lEf3x3EHBZVP9JJGBwrU/d2lofb9Z2nRAjzDULY91MVPr70IPkR1kpAxgTGHFhpp3G14xehv3O1gHhOE3K7LRWn4/J+qgc4o2V3mG6ASE2Meob50rw6RzYrwYWfKN4p6oGT/XfIOeLCFnnRZCG7tgdsoBxtmOon9SOdngWRt/6f+OcNpXs1X2OQP+rVQU3Si8GTHdtFdf7wSczCwJGCcHpfhDC7qYzGKBAFXNigHZIcKoiw4weUuwxalWmg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637368213; bh=KpQ0eFf7OSyXU3r0MdLTs0q6cQZlkHjQfe0br9nJ/+U=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=TedEg3RVsRVGeStoUWTJX1S70q+66dxSReYJQe/VbaXVxM9rBFHgpyXa/qNiNj1Uakhu0TdkyznhmdCs6OyKRl5/mijvKPhSvdqwJg0/TB0bzJAgDZDYb8Fmfpx8Ura8owYxuTjBD4F845odHcKpyo5ZxXlfmdU61Y8taugPlFRh6rJLzkh+f6LF5zyslWGpcouZXvQn+W3R+VQbuAL0RWZNteaMXUM/4RJRrur2iqj2KZGo5Sgm0VIJ73hCb7k0qWL/Htvu+fi6DaDIcVd0W7Q65Bp7FycuHnJtyhQC0eT/KiBEokCl70c+o/elnd2vu9qgQ1QLWRIQukqJMvfgeQ== X-YMail-OSG: L.eIhm0VM1kVpGAzDtbN1ACwmEBvP1eIszOJJC6tb384P.jPRxw9CeI0cFnxcjw 8eFzP83BuQsQJ6yqIkyctGFFQyn5N2ydwMdBTcFOX8cSXOjkDxLZXuNV8AAZRse5KZ.ZQ4EBDtum _hMkYZERDKuCVLkdQGl8TwoPdw3xARkKmlbUcva6FbMoDwc6FOhUiJdYc11b9HkHH9lTedlT5sjo QVk_THXV.6a8Ox3HLvYb4Zmg5k4_0eOFfrGuARr0znndTTg_WI2vYmLivpgpKc1Zju7mWhAlAuXr FxYHsxajPcdOdw3NySMXubcxKZNxG8OMiqFC8M6hYg6HhFAa.z2PKbqY2nQUi_UwLN2RgOBRhmn2 zeFhlzCy5eq4YPmdjnnWcAPYfgJHtW.q6Vh5rfTZgB9hSG_5VkHZ3IkLHS9zssAOcw2lmgz_CQF5 IuhNxfrZJ8sVqzmkkMiXWw8AW9k7lvLFUeu6Gn9T0djSVN51pXkYSWl3lTKJQw6HZhzBKDIXeSPB F6YxznZ2PCUz9AnE.JBTasrpnpx5PwwF4s_sO.90ZvfYpHo.6LncZQ.fvbb.UG5kUquOT8IWEuXI 3xrQygNzIAVj57M0R6lzCNeo7JksuFP7gt8B6z9cDW2pB.TyHd9xgZEs3qECXdEV.w4F6dqiHL_W a5T_Obo3ve3Ik8SGSRGgKurtxr97pMSqqTPgcIVWN0FePUvZV2nK7aREgWe_5PMmeeVgBtQbjfbg aIusPqkj3kSw1pYed6Jn8ktXwCPpRzvpQCrErx3mFclIgwYgEnL8t.InRafIvos2jp5pIqhmlcl0 yUnWdTwyF0sHimMvkECDdmDrbVg_qL0CVwbt1HT_j5OG_m1cA5__q.Ws9n8FSsEV8b9G6xMl0KxC XKXgaAsx1tGLRQ2xNw7CuN51OfkW0Uvz4qrTg2vbptEyNyGmv5XfU_raScAjR4rzg9eS11vHRax7 cEpEZ_2t_2tpaWAVC6yWK5joB_Z.TeUb6fVAy7nsVdalpAPrvwtwEqE28fBQ5tbrbb7rjMi4dSdg w_3ossEVJok2y_TBE_qhhaUI98ea14KU8ELwo_KMZS.I2utHGddYGtCkdHX2.3u3dUMsd75D0R01 3M2v33B5tFUpX9bBbXNcsA8w8bKX34EuE8ef8Ixob6kCH6arQxW3o6HtymZo8xwM.SOlq6jLIoWS Po2thSSVduHmzX1av2jsebVRAbqbjrDDWgRbIRRjaTl9_Yeg.o9ZH6OfsagtwsbsrICtw_naY51b O9IqeA8_IUoV0mDGtq4frFmkISqCchEP6fxtpMM_vgvwd29cB4BGBf44EaH6QwwPAgP9Y7GKjJ8o 9Eola5xUgZHKoHGYJzF.TKFMJTMhIb_rwaBDjks.mJlI9nDvVexuhHRSepmErh6V_ei0xNuUVP2a R4nU6kKbMqKw_syOXGVWzLWRTRifBrY3cE9Hcho9TiPw184q2WB9HpSB1cK7mn7rA9_TMIooKg87 NP47y3OkNS_zzDGg9HV76UAank6P744FIL2J.FuPZIzLMYIydmzdXfDXk2NnIoTbv90GmouFYorW EMUYT3HlNEfX0yR4.wyuHGbDsyhfUJMGdMZteIa0fr9iYNFpjUgWFXE8uJfeSz1dbVTo4mCdsEFB 9RnXn4NXVMY2EJy342_uTtF1lir3M7RayqANizmf2RLdRjNUZzCxKOASXCvhblLrUu889K0PODtD wzx3TGNIx.Te_oxeFvhsr10VtqUBml_EBEoJ.OELPXVnxN.KyJz_LEajsHsLhxgzK3G1lITwCCZM DnFhyPKAToKp.dbZgtyTXrA.onEX45XkzMunCLvrhUM1UhplXdwnaTW_64LUIw4gbuNWO7EgSnAn 35kr3Z0EHTmXDxDxpD6DeOuX.zj5aq0W4N3zFPMULf96_3uNJjI4Y5vu0EDu3WOsPepjPOLSgf9g X9aM1Tl0uw5Fc6xzNAbWd8gManVBBW7YyfvxPfC63Egno49fCdvNipJlrM4nz8c0pXOaAMc7iCCU kw2iIQFrfyf1m_gHy1heDBxLBGlnYO3flUWoYxXx0JT8jJASMoBW9x9TaTX6Ozjzs89_gAPQyC72 1gnZvGr0zfLmBwoDZ_31c0Pmcnq2Ad8Eb3Y2Z7A7HxTKFV6O9fh6_fv.wqmXhiBl.tYbk49MZkya yvR4zL9IH7zb8X93CTWKMjoVDbQoFEuOknsVljt_0u07AIZqTZ0qic5SNGLdLLd9UL_f8RvAwIAd vZ6zIEkfEGdQTCUJj._VBUZ5JFGjfGowq1HkWKxY6TQbguRpEQuVjUGk- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Sat, 20 Nov 2021 00:30:13 +0000 Received: by kubenode519.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID cdd8b2e9bb79fa99c28de90873d53905; Sat, 20 Nov 2021 00:30:12 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <87v90ppxlr.fsf@yahoo.com> <83k0h4uwgr.fsf@gnu.org> <871r3cmguh.fsf@yahoo.com> <83czmwuvmf.fsf@gnu.org> Date: Sat, 20 Nov 2021 08:30:07 +0800 In-Reply-To: <83czmwuvmf.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 19 Nov 2021 15:23:52 +0200") Message-ID: <87czmvlldc.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 502 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > Some text which makes it clear how these additional POSITION > parameters could be used by Lisp programs. > I think "pixel-resolution wheel events". WDYT about the following passage? @cindex pixel-resolution wheel events You can use @var{x} and @var{y} to determine how much the mouse wheel has actually moved. Scrolling the screen by these pixel deltas allows to present movement that appears to follow the user's grip on the mouse wheel. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 20 02:06:38 2021 Received: (at 51891) by debbugs.gnu.org; 20 Nov 2021 07:06:38 +0000 Received: from localhost ([127.0.0.1]:41436 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moKSL-000466-P9 for submit@debbugs.gnu.org; Sat, 20 Nov 2021 02:06:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58724) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moKSH-00045r-MY for 51891@debbugs.gnu.org; Sat, 20 Nov 2021 02:06:36 -0500 Received: from [2001:470:142:3::e] (port=58062 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1moKSB-0007s1-6J; Sat, 20 Nov 2021 02:06:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=FCg3B5MT9ofFbZpKX3yfRHRM/gHzNb0OvtnE6aeAtdA=; b=BR2kAp7j32Tq Hl9YYbyka9/oh1TJy8fAVOm/zJTTYDfwmiq2q16KHReu5gw4Xihunk5jyxywkpE5D2FeUUIclmAwF Cx/UEJxcWZl3UFZ5nhm3EmH/8OF3LQeoaeF0o2meMOfzgWGrWwvUfMegwV6L2W5deyRLRCZ+E11t4 KCDkMKH3RA2iI2N0hnjveIjZvNIWnmIKF6UQeJxRBStBvnN8QlgwBv9GEjp1MLoA8fI24gWj88dBh R9dzHsY/4hHc7R2cULD8G6hvaA7Cd3fWQnihW2o6InDyixKNwRkEO4DYITTFavfVe7VK3jLDgiAto KsCeObbLUwn8fRJHT+5CsQ==; Received: from [87.69.77.57] (port=1761 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1moKSA-0002xa-O3; Sat, 20 Nov 2021 02:06:27 -0500 Date: Sat, 20 Nov 2021 09:06:28 +0200 Message-Id: <83r1bbtiff.fsf@gnu.org> From: Eli Zaretskii To: Po Lu In-Reply-To: <87czmvlldc.fsf@yahoo.com> (message from Po Lu on Sat, 20 Nov 2021 08:30:07 +0800) Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <87v90ppxlr.fsf@yahoo.com> <83k0h4uwgr.fsf@gnu.org> <871r3cmguh.fsf@yahoo.com> <83czmwuvmf.fsf@gnu.org> <87czmvlldc.fsf@yahoo.com> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51891 Cc: rpluim@gmail.com, 51891@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Po Lu > Cc: rpluim@gmail.com, 51891@debbugs.gnu.org > Date: Sat, 20 Nov 2021 08:30:07 +0800 > > Eli Zaretskii writes: > > > Some text which makes it clear how these additional POSITION > > parameters could be used by Lisp programs. > > I think "pixel-resolution wheel events". > > WDYT about the following passage? > > @cindex pixel-resolution wheel events > You can use @var{x} and @var{y} to determine how much the mouse wheel > has actually moved. Here I would say "... has actually moved at pixel resolution." > Scrolling the screen by these pixel deltas allows > to present movement that appears to follow the user's grip on the > mouse wheel. That's just an example of using this feature, so: For example, the pixelwise deltas could be used to scroll the display at pixel resolution, exactly according to the user's turning the mouse wheel. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 20 05:29:14 2021 Received: (at 51891-done) by debbugs.gnu.org; 20 Nov 2021 10:29:14 +0000 Received: from localhost ([127.0.0.1]:41809 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moNcQ-0006Mt-0R for submit@debbugs.gnu.org; Sat, 20 Nov 2021 05:29:14 -0500 Received: from sonic309-20.consmr.mail.ne1.yahoo.com ([66.163.184.146]:45194) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moNcO-0006Ma-Gh for 51891-done@debbugs.gnu.org; Sat, 20 Nov 2021 05:29:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637404147; bh=3PdUjfqVed8cU4vqTamB20mLWt7KnJAii0PxD57awiM=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=I/C6XuLyLD0vKkwZSz7tGuqkKbpYKrfTfEq/cfKFfXDjZdkEdVnHakK9EvHwy1IrJ/qe/nR0QIplpi5ZvBMT+PBoQqu7BKe6jIprpRI481DDDWdReRw4Qk09KLVpEfawVt/KThkX+xyCqMzca4SYIg4IUbb1RQ/6adRb5fKAEtuBicm/CDSMIbcGBjrot40jsYOTngK4Fovf0YlwZ1lDuzGdykebbMFqLkkuG0FPgWc6JaVI5QeNC1anzw8HNHN+O/uU7eM+fAzGaCKIeqdT9x45QweV8+GtZnmQjQ6p6m2Na3KWw3HdSNWY5IaGnqIy74LIIuCNWRoLbT8vizYPFA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637404147; bh=uWrr8y7WzBV7cJnTWo3TZNoPoKbfQ1fkHW8wboDC100=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=jEYs+LL85LR2wnonDOxMJL6vZ6LIe6REb6ZAKacxUEKY7gvRYvnIJNaidWds3lirSL2O3rDTyWX+frkbzdusVu+IvoutdnzJ5U73WAMI5GiRzo+/t7rYExNY0amUoxbeO67qWVDgfmxJ0Hu+1sJwU/KS3CUNrUvzL9NHlYsrVeq6DiQrojsVVU+tpNgoZrg8MkDNOvQRpqbuDUJlyJhLbZHAQIQw18sorecY2nkfqfw4aWPYjZXaZSKHtNhFdkWhGafdgcL3FYYxG6M6n4D7gZhlZAwlmxgdUcN1PIQk/OntYBO8mJAqZWONx2l7FsQ75ThUVIgdLvVPeUqEvinang== X-YMail-OSG: TUEIfoYVM1l3Zp2sBfqNGNR5Q9B1PZY2f6keTfCb7TfEjNrcmMAgAdRL18tHPoV kaaal.MVhX6rG2lEryjzflIId8L.OjTiQlbE2wJgU4p2uCbpNlaubCuADESvS2u_8eAmP2FQU4fM 9qTo8PkYbHW5j9mren6HHm.bUEG0.mq6QpbAEzTKt_X8aspWn5S6RKm31Ew.dONfBiA9mQYAx9zW YxpOM6QGWpbEj.N4gXnPgL.1133OL58bxomWfsRQzMIsnNKzb60_dC6NEK2Yqphoj2WpPRD5C1He wR10L.l65YUtKK7CZdA8T20kCw5JaBznfI2qXxADHWfOTQ20XUMHIrlD12_i5b37K_vBqgxft0OD 9jsXyPSi9SeDiiPsbjeMhLJQPYZCHUDUK4yXObVGtbgPat.JckgoLG5Rk_eIw7j4Kk41x88Z4Wck .cUGvotwFm2wmgVbXf6vrqeHJSLjo5hkVAsGnDhxa2wtSxmbbfM7w3QEwpzoVEDWhJMJ9NxfOmbK agpGp5bYqVrO6nTMeSr3HDpQq_7eL.t1iScYZoo3dLp5GfCLPcHVA9f5eXslzpoDCjUQoSUJU0aL QdG5jcdAfiWz0t2R1eC7ovVF.86e.H2dP0MzASv51NKbVxpgJJwFDK_Mj31OingLmY5UzsuRm_2P sWEMa8DNKBPNC4lPXNpDsnNfwPjxAJL5UwDwo0r.HfzKcvIZ6UXAyJRshJ0zK6iYNDzfmjIP4K0d egEBvIwPslqn..MOJXTM5cWUHsSrp0SmhfOowIEJnIU2SvMuIoFNL0fLWN9ne16e7cQHxoj9RByn Mkt.RDIvh8NoULY2e72gjqPgVplbcjsbcNe_YHa0rRDKvW_PKUYF48CVjyMQ7E9CrrpeoIBmH8BN blsv9HBEcHStOIrMBHH4O6z6RO2HAiUBuqgVv0usRuweRkqTT1ykABNWjrtliA7fyvEYI8.r2hIb 67qaO5zXAqpj_dYGuj_g8NrtyzG82ciV4ZSH1s8coiE1gLfJoqxw2S7knHTGiPhMu6VV9C1BrRhJ 3etipSoqy3pl9ZilsWEWW4WdU9.SgSJQ.1Emh6nFOgbZyxbDSo2NEJSKF_lQJrk8.OfwsChJEvkz xRIT8F3Ld9ozfVSugmmoIFONv90tbNTaY6QZBCpOXEjMBbrPoxxUwwZlXgxI3V831rHqcBRutT5M 7fJnErbGx914_lrUqSSn9WycsEbODK_vQQ_K7sYDtsBqB3qWr_IEbBT_Q7GzKgncYfmhETCh5iqy rx8i0DvkGGffU5.4RDR0CVBzR3V_s.jP9l27mhdWBH_GM4KBILd9UP9yuFRF10LE..DdVTmF1ZWL YprPpskULgB.szp6a5LRTTZ5yGPsNbs5PD08ZYvO.LtCHiqWu0wfXKi6dK9JVJl8Rxa4QTEnhQ52 gbV3HxywKKCVeCc8hZ4Gzq.o25P9keaVC80qM0jic1UDWrHCHHpx0tWpzkXMU9isfvm4VVhsU9Xy 5YJnUNzaOTQ6oMBDGwJ7tJYd5eRNOf0Q6Zvi4p5U5qMxSsHYbnQn_YqNX6T6g1IhY0ZxXWSwhpJ4 7AVeeaf0zrOSiOXbc2O5Mq3hR1ZevuGL8iTXt7O4.hiAHdgih1dd8eeGP1SunzxLaKOJBX.6Vlsz DB0Iu8uDp6ehenbOotYRMxKR7SJiOTlDokMUDwai7bxZua0cmfbhEX7D6LLvDFK3P6lYEtqNfZlf Irzu11Fe1QjH1s5VCd.R2CPpXjQYDz0QraoTWOxTIjwvEw6Ne_38wvkyDvLNO42MPh7sXYpHQEQU pLsATOZ_r_fGTEbdeatg9ncFOrQvAPpi0d4EHyVsxB3_Ie3Eih2edri1efjDJTAEo3umjKZysnpg _K4MycPGElzdlmHlw45lHzX6AN.Zy9nawuzjfad6ihCwwSTFNw1pXTgM9FqA_9WFTqvpiMmVOLBE ZafYWRVfhoKYqKsKrL_biYIVKZcDEDKcb2DXJkK1uTLDsb1sbmdj0Wx3dL6wsTp90AJqD.EZmvZr boFIMwCw5ZcooRN7wI0vmzN0wMLSpk6hNl4gGvPIgYsAQzDz5q6Fm5ISwB37z4mJh3k1MQiXIMKB 91fLHiSMphtLHImzWEnH8I.pLHg83CA.D8xC7UJjBDPCArWJeBwL1NSbhwox_q.t8VNTkDLEylmm w3I7AZHBiEwXGTW9ph221Oz9osbPozZlPEkGBoMGHWf2X9igzW4MOkf5tmcTUVUpNmKUtrQYgTmP xHDtUiRZq6a.MnZAfjC6rVL3e5pK41HToPhEgaTl5vr0N5o9MHrOqlG_rkdRW X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Sat, 20 Nov 2021 10:29:07 +0000 Received: by kubenode519.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 78430d874ad6bb54e318066e2a23fa11; Sat, 20 Nov 2021 10:28:59 +0000 (UTC) From: Po Lu To: Eli Zaretskii Subject: Re: bug#51891: 29.0.50; [PATCH] Pixel delta support for wheel events on X References: <87zgq4uvh0.fsf.ref@yahoo.com> <87zgq4uvh0.fsf@yahoo.com> <871r3gnrrn.fsf@gmail.com> <875ysrtyak.fsf@yahoo.com> <871r3ftsjy.fsf@yahoo.com> <83r1bezz2u.fsf@gnu.org> <87r1beqpy8.fsf@yahoo.com> <83tug9yl28.fsf@gnu.org> <87zgq1q0uy.fsf@yahoo.com> <83ilwouw9z.fsf@gnu.org> <87pmqwl1lq.fsf@yahoo.com> <837dd4uu62.fsf@gnu.org> Date: Sat, 20 Nov 2021 18:28:54 +0800 In-Reply-To: <837dd4uu62.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 19 Nov 2021 15:55:17 +0200") Message-ID: <87mtlzp1cp.fsf@yahoo.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Mailer: WebService/1.1.19306 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 160 X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 51891-done Cc: rpluim@gmail.com, 51891-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > Sure, why not? > > Thanks. Thanks, installed with the improvement to documentation you suggested in the other message. From unknown Tue Jun 17 01:43:50 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sat, 18 Dec 2021 12:24:12 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator