From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Po Lu Newsgroups: gmane.emacs.devel Subject: Re: master 3b41141708: Expose the name of an event's input device to Lisp Date: Sat, 09 Apr 2022 19:44:57 +0800 Message-ID: <87zgkulbuu.fsf@yahoo.com> References: <164933858147.29834.15050766441005536059@vcs2.savannah.gnu.org> <20220407133623.9C209C009A8@vcs2.savannah.gnu.org> <87ee28xyg2.fsf@yahoo.com> <83ee28az95.fsf@gnu.org> <87fsmow1hz.fsf@yahoo.com> <83a6cway59.fsf@gnu.org> <87tub4uivu.fsf@yahoo.com> <83y20fakwn.fsf@gnu.org> <87o81bu7zj.fsf@yahoo.com> <83v8vjai4s.fsf@gnu.org> <87bkxbsqfl.fsf@yahoo.com> <835yniah0u.fsf@gnu.org> <8735impqw4.fsf@yahoo.com> <83v8vi8uyu.fsf@gnu.org> <871qy6o9p3.fsf@yahoo.com> <83o81a8qnd.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11048"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.91 (gnu/linux) Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Apr 09 13:46:43 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nd9Y8-0002fT-GZ for ged-emacs-devel@m.gmane-mx.org; Sat, 09 Apr 2022 13:46:40 +0200 Original-Received: from localhost ([::1]:38188 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nd9Y7-0003OI-Bi for ged-emacs-devel@m.gmane-mx.org; Sat, 09 Apr 2022 07:46:39 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43730) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nd9Wj-0002Vp-7z for emacs-devel@gnu.org; Sat, 09 Apr 2022 07:45:13 -0400 Original-Received: from sonic315-20.consmr.mail.ne1.yahoo.com ([66.163.190.146]:45712) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nd9Wf-0001GD-RS for emacs-devel@gnu.org; Sat, 09 Apr 2022 07:45:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649504707; bh=b5RmTn+KrAcI8U6r6PwvAUM/HXSZgwUzxfUfr5Lx0es=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=MhDzPbSmwCAPAnqn17fEmucnzkdaz8ua4Y/VNfRZOGUXUVcvFIBNDcP0jHqDBrmVePdus7pas2VlwFNwPQu0bpjDPsxG6yLo5AI81CmmOwBIi6doMe18xDUUc7RQOZPHk+NQKXiEjQhBJlsGhWK0McoYP/nj1n9qG2FovdZRBPKTTnNY1hm+LMUKQcG0PhTF9pR7Ie0xMNouXJ+L/6nKVMhgUuUesBYtJNC2u42EmUl+z+W2xZDd8f3XPhxjMcU2CptB6wRmixuhDQGPvZMeabG0grlQG8IfnLYjtwM2vqILNct0jOa3+HQ6mZx0Idtf1qrnAy7KOcem3MEh7UZyAw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649504707; bh=p4F55jUrWivIebuSDnqgkTOXTGSW9qemIgrF8Yhar6N=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=OXGVyGRac32rW/l52bu7bVm1AcgfBY+BgDUEJqd1YSpz5i2apr7v6DJwfKiJ//895y87MXH7vWExEalzINx3c/VZibAiXs2g4anq/1B8MBLQEbnANPz1kY1LY05xfYJ/jb7XnPwt1ih8qQmsHVOqUFG8Cj9OHJX6eIooGPtFYvpCxOHUtwxFcN4AXZg3gEb2zX279P+ykFo6iDLK7weh5v9PSTrFhKrkHpxxAY5C7pEwOF0ckwyl84yqlR+i+acTvBYebWLE3AS6JUdqtjx+b5iwLIGTxKxSLPxecnlom7sR6AEmGpdBxWevcpteEfchPf5NsdwK3urw9ZBlNhY7cg== X-YMail-OSG: QJkWiuMVM1meCipnR1YGX.h.0bItmSPLSZkszlraD1x0.APQk8m_L43rV7gdHf7 UJ10Aqxs7tkb9yxoxGapKSo7p7eDH8IocOwsfQOSYiqpSPRJ6ayKFI4CGt4KKSSIbU.t2IRumg5D ikby6nUjBnmJiSrI3EFVjeTecPOppXMvzoamrUUuZcv4EyF7qfgBqKLcamCRGifyHKig6VZnfEOC gMdzU1w4jmul6aV7mzME5npqkt8Kc7YlnUowJdsZ8sfNiFJtZjjNow7IGjB8ADERteFe6w3eC4dc N_xir6Xez6MIg_aay46D33FkZiQKPIrf7vS0RiUIPlfOXsc8Y7syJJ2elD7ad_dMdGh104iEIJWJ MLc1lRBIEbUxePpQyNatE3jq0hru5ueGVK_7KgthbeBOdF9wnj89xJVELffm0TjyFvP77bFye4vT QLfyWW7ZJYv9IqLxE5HgxwJJ_RwthzCWwVpcEfnL9L5Nt6HVJOCvdg0YUTenMvyzeFrKN.U0w8LM OpzFdzH76r0rvY3kBqScF9npQVb0YrBPzDG.zRX95GPCPcWtavPV2DNjtKyY.Kwg0.e5JHrOm9cd HZpLEdXquY29yeAAW.0qPW5_FJwhiKCE43xjypKTbR8ujQOfqs7fVycW5UzynIdZv09tPlBIRZPX VAJYu.xzA2FSPWEEDJvKlogBrrmpXEFsdCmVJInRneR4KnCXSM2AZyA8GuxKTvuFP_P.4vV7uE.1 vTMx6jt4NvgY3ZuaUIWp3bkuL9CulBdHoEB1Q884TNUOTbWbIvvGDIEsFKbnKHqdEaIezfl71jLv hPA5VWoJQdBKLBhS9_0bvvb3n5wqmdlYZmZ61onf4Y X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic315.consmr.mail.ne1.yahoo.com with HTTP; Sat, 9 Apr 2022 11:45:07 +0000 Original-Received: by hermes--canary-production-sg3-65d7bd97b5-gqv44 (VZM Hermes SMTP Server) with ESMTPA ID a03c068430d810215784adb8b0630c01; Sat, 09 Apr 2022 11:45:02 +0000 (UTC) In-Reply-To: <83o81a8qnd.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 09 Apr 2022 14:03:50 +0300") X-Mailer: WebService/1.1.20048 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Received-SPF: pass client-ip=66.163.190.146; envelope-from=luangruo@yahoo.com; helo=sonic315-20.consmr.mail.ne1.yahoo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:288022 Archived-At: Eli Zaretskii writes: > No, only for events that are specific to the device and not available > in other devices. But the point is that they aren't specific to the device. The device will in the general case behave like any other device (a touchpad will scroll just like a mouse, and an eraser will move the pointer like any other stylus), but inside specific use cases, such as precision scrolling and artist-mode, they will have to behave differently. > So, with your current design and implementation, what level will deal > with the device type and decide how to handle each event with the > device type in mind? Events are bound to commands in Emacs, so does > this mean each command will need to know about the device to DTRT? The default events (i.e. button and motion events from an eraser) is usually enough to DTRT, but a command can also chose to treat it as an eraser instead of an ordinary pointing device. The individual command will have to know about the device to treat it correctly, just as elsewhere: web browsers, programs using GTK, Qt, etc. > And what would happen instead under your design and implementation? > won't we need to add code to recognize the new device? We would not. The user could write code to recognize the device based on its name (or other identifiers.) > I don't see how can you so sure about this. A name is just a string. > With devices development these days, chances are what is a unique name > today will cease to be that tomorrow. The X server and Wayland compositor guarantee that the name is unique to each device. The developers of the low-level libraries and drivers used on those display servers also treat the names of devices as something permanent that should not be changed, since not only applications and toolkits rely on them, but also many kinds of hardware database files and "quirks". > In general, I have hard time imagining that modern systems let you > access the precise and detailed device information, because (AFAIK) > modern systems typically hide this information from applications. IME, that trend has been reversed as of late. Major toolkits which previously preferred to define special event types ("scroll" events for wheel mice, and "smooth scroll" events for touchpads) are now exposing the device directly. I hear that a similar thing is happening to web browsers, but I didn't look at the web browser APIs in that much detail. Especially on GNU/Linux, where the input drivers and window server shove many details of relevance into the device itself. Some other Emacs APIs will probably have to change also: `set-mouse-position' will have to be changed to accept a device, so that multi-pointer X can work correctly. Otherwise, the fallback "client pointer" will be moved, which is not always the pointer that the user is using to interact with Emacs. > How will this different behavior implemented, under your current > proposals? Which code will deal with the device information, and how > will that eventually affect behavior? Please show code examples if > possible. My idea is that the commands that want device-specific behavior will behave specially. For example, the following change to artist-mode causes erasers to erase characters instead of drawing them: diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index e37b0d988a..47dd70e4f1 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -4786,7 +4786,11 @@ artist-down-mouse-1 (artist-mode-line-show-curr-operation t) =20 (cond ((eq draw-how 'artist-do-continously) - (artist-mouse-draw-continously ev)) + (artist-mouse-draw-continously ev + (when (eq (device-class la= st-event-frame + la= st-event-device) + 'eraser) + 'erase-char))) ((eq draw-how 'artist-do-poly) (artist-mouse-draw-poly ev)) ((and (numberp draw-how) (=3D draw-how 1)) @@ -4897,14 +4901,16 @@ artist--adjust-x x (- x adjust 2)))) =20 -(defun artist-mouse-draw-continously (ev) +(defun artist-mouse-draw-continously (ev &optional override-op) "Generic function for shapes that require 1 point as input. -Operation is done continuously while the mouse button is hold down. -The event, EV, is the mouse event." +Operation is done continuously while the mouse button is hold +down. The event, EV, is the mouse event. OVERRIDE-OP is another +operation to use, or nil." (let* ((unshifted (artist-go-get-symbol-shift artist-curr-go nil)) (shifted (artist-go-get-symbol-shift artist-curr-go t)) (shift-state (artist-event-is-shifted ev)) - (op (if shift-state shifted unshifted)) + (op (or override-op + (if shift-state shifted unshifted))) (draw-how (artist-go-get-draw-how-from-symbol op)) (init-fn (artist-go-get-init-fn-from-symbol op)) (prep-fill-fn (artist-go-get-prep-fill-fn-from-symbol op)) And this change would allow clicking the first button on a graphics tablet (or a user-specified mouse) to select the "circle" drawing operation instead of drawing something underneath the mouse pointer: diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index e37b0d988a..a8f5586ddf 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -4741,75 +4741,84 @@ artist-compute-up-event-key (defun artist-down-mouse-1 (ev) "Perform drawing action for event EV." (interactive "@e") - (let* ((real (artist-go-get-symbol-shift - artist-curr-go (artist-event-is-shifted ev))) - (draw-how (artist-go-get-draw-how-from-symbol real)) - ;; Remember original values for draw-region-min-y and max-y - ;; in case we are interrupting a key-draw operation. - (orig-draw-region-min-y artist-draw-region-min-y) - (orig-draw-region-max-y artist-draw-region-max-y) - (orig-pointer-shape (if (eq window-system 'x) x-pointer-shape nil)) - (echo-keystrokes 0) ; Don't echo unfinished commands. - ;; Remember original binding for the button-up event to this - ;; button-down event. - (key (artist-compute-up-event-key ev)) - (orig-button-up-binding (lookup-key (current-global-map) key))) + (if (or (eq (device-class last-event-frame + last-event-device) + 'pad) + (equal last-event-device ; Or in the future, (device-name + ; last-event-device) + ;; A mouse the user wants to treat specially. In the + ;; real code this would be customizable, of course. + "USB Optical Mouse (2)")) + (artist-select-op-circle) + (let* ((real (artist-go-get-symbol-shift + artist-curr-go (artist-event-is-shifted ev))) + (draw-how (artist-go-get-draw-how-from-symbol real)) + ;; Remember original values for draw-region-min-y and max-y + ;; in case we are interrupting a key-draw operation. + (orig-draw-region-min-y artist-draw-region-min-y) + (orig-draw-region-max-y artist-draw-region-max-y) + (orig-pointer-shape (if (eq window-system 'x) x-pointer-shape nil)) + (echo-keystrokes 0) ; Don't echo unfinished commands. + ;; Remember original binding for the button-up event to this + ;; button-down event. + (key (artist-compute-up-event-key ev)) + (orig-button-up-binding (lookup-key (current-global-map) key))) =20 - (unwind-protect - (progn - (if (eq window-system 'x) - (artist-set-pointer-shape artist-pointer-shape)) - - ;; Redefine the button-up binding temporarily (the original - ;; binding is restored in the unwind-forms below). This is to - ;; avoid the phenomenon outlined in this scenario: - ;; - ;; 1. A routine which reads something from the mini-buffer (such - ;; as the text renderer) is called from below. - ;; 2. Meanwhile, the users releases the mouse button. - ;; 3. As a (funny :-) coincidence, the binding for the - ;; button-up event is often mouse-set-point, so Emacs - ;; sets the point to where the button was released, which is - ;; in the buffer where the user wants to place the text. - ;; 4. The user types C-x o (or uses the mouse once again) - ;; until he reaches the mini-buffer which is still prompting - ;; for some text to render. - ;; - ;; To do this foolproof, all local and minor-mode maps should - ;; be searched and temporarily changed as well, since they - ;; too might have some binding for the button-up event, - ;; but I hope dealing with the global map will suffice. - (define-key (current-global-map) key 'artist-do-nothing) + (unwind-protect + (progn + (if (eq window-system 'x) + (artist-set-pointer-shape artist-pointer-shape)) + + ;; Redefine the button-up binding temporarily (the original + ;; binding is restored in the unwind-forms below). This is to + ;; avoid the phenomenon outlined in this scenario: + ;; + ;; 1. A routine which reads something from the mini-buffer (such + ;; as the text renderer) is called from below. + ;; 2. Meanwhile, the users releases the mouse button. + ;; 3. As a (funny :-) coincidence, the binding for the + ;; button-up event is often mouse-set-point, so Emacs + ;; sets the point to where the button was released, which is + ;; in the buffer where the user wants to place the text. + ;; 4. The user types C-x o (or uses the mouse once again) + ;; until he reaches the mini-buffer which is still prompting + ;; for some text to render. + ;; + ;; To do this foolproof, all local and minor-mode maps should + ;; be searched and temporarily changed as well, since they + ;; too might have some binding for the button-up event, + ;; but I hope dealing with the global map will suffice. + (define-key (current-global-map) key 'artist-do-nothing) =20 - (artist-draw-region-reset) + (artist-draw-region-reset) =20 - (artist-mode-line-show-curr-operation t) + (artist-mode-line-show-curr-operation t) =20 - (cond ((eq draw-how 'artist-do-continously) - (artist-mouse-draw-continously ev)) - ((eq draw-how 'artist-do-poly) - (artist-mouse-draw-poly ev)) - ((and (numberp draw-how) (=3D draw-how 1)) - (artist-mouse-draw-1point ev)) - ((and (numberp draw-how) (=3D draw-how 2)) - (artist-mouse-draw-2points ev)) - (t (message "Drawing \"%s\"s is not yet implemented" - draw-how))) + (cond ((eq draw-how 'artist-do-continously) + (artist-mouse-draw-continously ev)) + ((eq draw-how 'artist-do-poly) + (artist-mouse-draw-poly ev)) + ((and (numberp draw-how) (=3D draw-how 1)) + (artist-mouse-draw-1point ev)) + ((and (numberp draw-how) (=3D draw-how 2)) + (artist-mouse-draw-2points ev)) + (t (message "Drawing \"%s\"s is not yet implemented" + draw-how))) =20 - (if artist-trim-line-endings - (artist-draw-region-trim-line-endings artist-draw-region-min-y - artist-draw-region-max-y)) - (setq artist-draw-region-min-y orig-draw-region-min-y) - (setq artist-draw-region-max-y orig-draw-region-max-y)) + (if artist-trim-line-endings + (artist-draw-region-trim-line-endings artist-draw-region-min-y + artist-draw-region-max-y)) + (setq artist-draw-region-min-y orig-draw-region-min-y) + (setq artist-draw-region-max-y orig-draw-region-max-y)) =20 - ; This is protected - (if (eq window-system 'x) - (artist-set-pointer-shape orig-pointer-shape)) + ; This is protected + (if (eq window-system 'x) + (artist-set-pointer-shape orig-pointer-shape)) =20 - (if orig-button-up-binding - (define-key (current-global-map) key orig-button-up-binding)) + (if orig-button-up-binding + (define-key (current-global-map) key orig-button-up-binding)) =20 - (artist-mode-line-show-curr-operation artist-key-is-drawing)))) + (artist-mode-line-show-curr-operation artist-key-is-drawing))))) =20 >> >> And what if the user has two ordinary mice connected, and wants one to >> >> behave differently from the other, in effect giving him an extra set = of >> >> mouse buttons? >> > >> > What about it? Why does this require to know about the device, and >> > cannot be expressed as special events? >>=20 >> How would you decide from which mice ordinary button events should come, >> and what others without knowing their names? > > By appropriate numbering of their buttons, for example? How would you number the buttons of a specific device without knowing its name? Besides, window systems have a limit on the largest button that can be reported. > Instead of doing this on the level of input methods, why not do this > where we produce keyboard key events, by converting the keys to what > they are supposed to mean from the user's POV? Then none of the > higher-level code will need to change, and moreover, users will be > able to use these different keyboards with input methods unrelated to > the keyboard type handling, whereas if this is done in an input > method, one cannot have another input method active at the same time > to use the characters that come from the "translation" input method. Actually, I think it would be even better to have the existing input method system work well with multiple devices. IOW, we could add a new variable `input-method-functions', an alist of (DEVICE . ACTUAL-FUNCTION), where ACTUAL-FUNCTION is called on keyboard events from DEVICE, and only if none of that is found do we default to `input-method-function'. But we will still need to expose a way to identify individual input devices, which on GNU/Linux happens to be the name of the device. > No, we just need a mapping from this event to an Emacs command that > will do whatever is needed for the event. And users can customize > that command if they need. But if I press the key labeled "=D1=8F", and the system keyboard layout is = on US International, the event Emacs gets is "z", and vice versa. The only difference between that and pressing "z" on the US International keyboard is that the device reported as the source of the event is different, and those separate devices can be identified by their names. Thanks.