* Re: master 3b41141708: Expose the name of an event's input device to Lisp [not found] ` <20220407133623.9C209C009A8@vcs2.savannah.gnu.org> @ 2022-04-07 14:05 ` Stefan Monnier 2022-04-07 23:31 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-07 14:05 UTC (permalink / raw) To: emacs-devel; +Cc: Po Lu > +@defvar last-event-device > +This variable records the name of the input device from which the last > +input event read was generated. It is @code{nil} if no such device > +exists, i.e., the last input event was read from > +@code{unread-command-events}, or it came from a keyboard macro. > + > +When the X Input Extension is being used on X Windows, the device name > +is a string that is unique to each physical keyboard, pointing device > +and touchscreen attached to the X server. Otherwise, it is either the > +string @samp{"Virtual core pointer"} or @samp{"Virtual core > +keyboard"}, depending on whether the event was generated by a pointing > +device (such as a mouse) or a keyboard. > +@end defvar Any chance we could attach this info to the events rather than storing them in some global var making it unclear to which event it applies? Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-07 14:05 ` master 3b41141708: Expose the name of an event's input device to Lisp Stefan Monnier @ 2022-04-07 23:31 ` Po Lu 2022-04-07 23:41 ` Stefan Monnier 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-07 23:31 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >> +@defvar last-event-device >> +This variable records the name of the input device from which the last >> +input event read was generated. It is @code{nil} if no such device >> +exists, i.e., the last input event was read from >> +@code{unread-command-events}, or it came from a keyboard macro. >> + >> +When the X Input Extension is being used on X Windows, the device name >> +is a string that is unique to each physical keyboard, pointing device >> +and touchscreen attached to the X server. Otherwise, it is either the >> +string @samp{"Virtual core pointer"} or @samp{"Virtual core >> +keyboard"}, depending on whether the event was generated by a pointing >> +device (such as a mouse) or a keyboard. >> +@end defvar > > Any chance we could attach this info to the events rather than storing > them in some global var making it unclear to which event it applies? We can't put it in the event list, i.e. key events are mostly just characters, and can't be extended. Which event the global variable applies to is also perfectly clear: it applies to the last event that was read, either by the command loop or read-event. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-07 23:31 ` Po Lu @ 2022-04-07 23:41 ` Stefan Monnier 2022-04-08 0:07 ` Po Lu ` (2 more replies) 0 siblings, 3 replies; 86+ messages in thread From: Stefan Monnier @ 2022-04-07 23:41 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel >> Any chance we could attach this info to the events rather than storing >> them in some global var making it unclear to which event it applies? > > We can't put it in the event list, i.e. key events are mostly just > characters, and can't be extended. I thought we only need it for events like scroll events, i.e. not for plain character events. > Which event the global variable applies to is also perfectly clear: it > applies to the last event that was read, either by the command loop or > read-event. Yeah, it works, but relying on state is ugly and better avoided if we can. Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-07 23:41 ` Stefan Monnier @ 2022-04-08 0:07 ` Po Lu 2022-04-08 6:02 ` Eli Zaretskii 2022-04-08 14:27 ` Stefan Monnier 2 siblings, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-08 0:07 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> Any chance we could attach this info to the events rather than storing >>> them in some global var making it unclear to which event it applies? >> >> We can't put it in the event list, i.e. key events are mostly just >> characters, and can't be extended. > > I thought we only need it for events like scroll events, i.e. not for > plain character events. It applies to any event generated by an input deviec, including keyboard events. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-07 23:41 ` Stefan Monnier 2022-04-08 0:07 ` Po Lu @ 2022-04-08 6:02 ` Eli Zaretskii 2022-04-08 6:08 ` Po Lu 2022-04-08 14:27 ` Stefan Monnier 2 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-08 6:02 UTC (permalink / raw) To: Stefan Monnier; +Cc: luangruo, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: emacs-devel@gnu.org > Date: Thu, 07 Apr 2022 19:41:29 -0400 > > >> Any chance we could attach this info to the events rather than storing > >> them in some global var making it unclear to which event it applies? > > > > We can't put it in the event list, i.e. key events are mostly just > > characters, and can't be extended. > > I thought we only need it for events like scroll events, i.e. not for > plain character events. > > > Which event the global variable applies to is also perfectly clear: it > > applies to the last event that was read, either by the command loop or > > read-event. > > Yeah, it works, but relying on state is ugly and better avoided if > we can. Can we make a step back and discuss why do we need this information in Emacs, and how it is supposed to be used? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 6:02 ` Eli Zaretskii @ 2022-04-08 6:08 ` Po Lu 2022-04-08 6:26 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-08 6:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Can we make a step back and discuss why do we need this information in > Emacs, and how it is supposed to be used? I thought it was described in the commit message: different devices can generate the same events, but commands (such as pixel-scroll-precision) might want to act differently depending on the device that generated it. (I'm still getting the device detection right, though it already works for most hardware: on X, the only way to find out the "device class" of a device is to look at its name.) There are use cases other than precision pixel scrolling as well. For example, different keyboards could be configured to behave differently, which is useful for people who have multiple keyboards lying around. Tetris might also want to treat mouse movement from a joystick differently from that of an ordinary pointing device. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 6:08 ` Po Lu @ 2022-04-08 6:26 ` Eli Zaretskii 2022-04-08 7:36 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-08 6:26 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org > Date: Fri, 08 Apr 2022 14:08:40 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Can we make a step back and discuss why do we need this information in > > Emacs, and how it is supposed to be used? > > I thought it was described in the commit message I wouldn't have asked if the commit message explained this enough for me to understand. I see no rationale in the commit message. > different devices can generate the same events, but commands (such > as pixel-scroll-precision) might want to act differently depending > on the device that generated it. What for? Why do we care in Emacs which device generated a scroll event? Emacs was always transparent regarding that, and did the same regardless of the particular device which caused the event. Why do we suddenly need to distinguish between them? This could add complexity to Emacs's application level that we don't particularly want. So if we do add this, it had better be a very good reason. > (I'm still getting the device detection right, though it already works > for most hardware: on X, the only way to find out the "device class" of > a device is to look at its name.) But what is a "device" for this purpose? Most input events nowadays come from the window-system, which typically hides the device level from the application. For example, there are programs that allow you to inject mouse events by typing on the keyboard, and vice versa. There are also programs that inject keyboard events programmatically. Etc. etc. Why would we want to know or care exactly what device generated an event? > There are use cases other than precision pixel scrolling as well. For > example, different keyboards could be configured to behave differently, > which is useful for people who have multiple keyboards lying around. The question is why it is useful for Emacs to know which keyboard device generated a key sequence. > Tetris might also want to treat mouse movement from a joystick > differently from that of an ordinary pointing device. Why? In any case, if we do agree to have this information in Emacs, the definition of a "device" should be abstract enough to allow its implementation on systems other than X. And then I will ask a question similar to that Stefan asked: why not make the device part of event object we have on the event queue? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 6:26 ` Eli Zaretskii @ 2022-04-08 7:36 ` Po Lu 2022-04-08 11:12 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-08 7:36 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I wouldn't have asked if the commit message explained this enough for > me to understand. I see no rationale in the commit message. Sorry, I will try to be more clear on that next time. > What for? Why do we care in Emacs which device generated a scroll > event? Emacs was always transparent regarding that, and did the same > regardless of the particular device which caused the event. Why do we > suddenly need to distinguish between them? This could add complexity > to Emacs's application level that we don't particularly want. So if > we do add this, it had better be a very good reason. Basically, precision scrolling comes in two forms: the first immediately scrolls the screen by the deltas given, while the second "animates" a scroll from the original position to the position with the deltas. All the major programs and toolkits today seem to be converging on using the first strategy for touchpad devices and tablets, and the second for mice. The ability to distinguish between different input devices is important to be able to implement that behavior according to what users expect. > Most input events nowadays come from the window-system, which > typically hides the device level from the application. For example, > there are programs that allow you to inject mouse events by typing on > the keyboard, and vice versa. There are also programs that inject > keyboard events programmatically. Etc. etc. Why would we want to > know or care exactly what device generated an event? That's not hidden under X Windows and GTK, where we see that many other applications are relying on that information as well. For example, Firefox-based browsers and WebKit both use it to determine which form of "precise scrolling" strategy to use. NS doesn't expose the device name, but it does expose the kind of device which generated the event. On macOS, GTK uses that information to compute an artificial device name, which works well enough. > The question is why it is useful for Emacs to know which keyboard > device generated a key sequence. I can imagine an input method behaving differently depending on which keyboard is being used, since individual keyboards can have different layouts convenient for typing in separate languages. > In any case, if we do agree to have this information in Emacs, the > definition of a "device" should be abstract enough to allow its > implementation on systems other than X. It has already been implemented on Wayland, and the implementation on NS is waiting for a machine on which it can be tested. (I don't have access to a real Mac, and GNUstep doesn't even try to implement what I talked about correctly, to it everything is a mouse.) > And then I will ask a question similar to that Stefan asked: why not > make the device part of event object we have on the event queue? It's already part of the `struct input_event', but compatibility requirements prevent it from being made part of the Lisp events itself, so we store it as one of the last-event-* variables instead. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 7:36 ` Po Lu @ 2022-04-08 11:12 ` Eli Zaretskii 2022-04-08 11:31 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-08 11:12 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Fri, 08 Apr 2022 15:36:05 +0800 > > > What for? Why do we care in Emacs which device generated a scroll > > event? Emacs was always transparent regarding that, and did the same > > regardless of the particular device which caused the event. Why do we > > suddenly need to distinguish between them? This could add complexity > > to Emacs's application level that we don't particularly want. So if > > we do add this, it had better be a very good reason. > > Basically, precision scrolling comes in two forms: the first immediately > scrolls the screen by the deltas given, while the second "animates" a > scroll from the original position to the position with the deltas. > > All the major programs and toolkits today seem to be converging on using > the first strategy for touchpad devices and tablets, and the second for > mice. That suggests a different strategy: produce different input event types from each such device. That'd leave the device dependency to low-level code, and let the application level deal with event kinds and not with device types. I think this is a better abstraction, if it's possible/feasible. > > Most input events nowadays come from the window-system, which > > typically hides the device level from the application. For example, > > there are programs that allow you to inject mouse events by typing on > > the keyboard, and vice versa. There are also programs that inject > > keyboard events programmatically. Etc. etc. Why would we want to > > know or care exactly what device generated an event? > > That's not hidden under X Windows and GTK, where we see that many other > applications are relying on that information as well. For example, > Firefox-based browsers and WebKit both use it to determine which form of > "precise scrolling" strategy to use. We have been burned by modeling the application-level features on the particular X implementation and low-level details. It took us literally decades to get rid of X-specific code and features, let alone API names, and move to exposing more general and more adaptable APIs to applications. I was there when this hard lesson was learned, and I'd rather we didn't repeat those mistakes. Let's see from the get-go how this kind of functionality can be expressed in device-independent and window-system independent ways, and design the APIs accordingly. For that, we need to define what are the aspects that applications would like to know about when dealing with these input events, and then see how this could be abstracted or generalized to any input system we support now and can envision to support in the future. E.g., what about GPM and xt-mouse on TTYs? what about window-systems that aren't based on X? etc. etc. > NS doesn't expose the device name, but it does expose the kind of device > which generated the event. On macOS, GTK uses that information to > compute an artificial device name, which works well enough. Works very well for whom? for GTK? That's not a criterion I'd expect us to apply here. We need to do what will work well for Emacs. > > The question is why it is useful for Emacs to know which keyboard > > device generated a key sequence. > > I can imagine an input method behaving differently depending on which > keyboard is being used, since individual keyboards can have different > layouts convenient for typing in separate languages. That doesn't mean you want to know about the device, it rather means you want to know the keyboard layout: an entirely different aspect, and not specific to any OS. > > In any case, if we do agree to have this information in Emacs, the > > definition of a "device" should be abstract enough to allow its > > implementation on systems other than X. > > It has already been implemented on Wayland, and the implementation on NS > is waiting for a machine on which it can be tested. IMNSHO, it's too bad we rush into implementing such features without any discussion. See above about the alternatives that, at least at this time, seem much better to me than dragging the low-level device type information to the application level, and in global stateful variables on top of that. > > And then I will ask a question similar to that Stefan asked: why not > > make the device part of event object we have on the event queue? > > It's already part of the `struct input_event', but compatibility > requirements prevent it from being made part of the Lisp events itself, > so we store it as one of the last-event-* variables instead. Which once again favors the alternative that would work by defining new kinds of events. That alternative has no compatibility issues. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 11:12 ` Eli Zaretskii @ 2022-04-08 11:31 ` Po Lu 2022-04-08 12:12 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-08 11:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > That suggests a different strategy: produce different input event > types from each such device. That'd leave the device dependency to > low-level code, and let the application level deal with event kinds > and not with device types. I think this is a better abstraction, if > it's possible/feasible. I don't think it's feasible, especially since there are too many different kinds of events, and with some of them those dfferent kinds of events simply cannot work. (Think single character keyboard events.) > We have been burned by modeling the application-level features on the > particular X implementation and low-level details. It took us > literally decades to get rid of X-specific code and features, let > alone API names, and move to exposing more general and more adaptable > APIs to applications. I was there when this hard lesson was learned, > and I'd rather we didn't repeat those mistakes. This API is not X specific at all; in contrast, an X-specific API would be to expose the list of device valuators and "classes", containing various flags. > Let's see from the get-go how this kind of functionality can be > expressed in device-independent and window-system independent ways, > and design the APIs accordingly. For that, we need to define what are > the aspects that applications would like to know about when dealing > with these input events, and then see how this could be abstracted or > generalized to any input system we support now and can envision to > support in the future. E.g., what about GPM and xt-mouse on TTYs? > what about window-systems that aren't based on X? etc. etc. When designing this feature, and why I purposely didn't design it based on the X concepts of device axises and classes, I worked from two directions: it should be possible to extract the type of a device (i.e. tell between a touchpad, a keyboard, a pointer, and a piano), and when possible (i.e. supported by the window system), it should be able to tell individual devices apart. The current API achieves the first goal by giving each device a "name", which contains enough information to determine the device type, and it also achieves the second goal by guaranteeing that the device names are unique to each device on window systems which support that, such as X and Wayland. Each window system can then define a function for `device-class', which returns the type of a device based on the name given to it. This feature was already implemented not just on X, but also on PGTK, which means it also works well with the very different input subsystems of Wayland and Broadway. I also wrote the code to make it work with NS, but it hasn't been tested yet. As for gpm-mouse and xt-mouse, their mouse movement is simply reported as the "core pointer" device, which tells any code that might want to perform a specific action based on the device type that the type could not be determined. > That doesn't mean you want to know about the device, it rather means > you want to know the keyboard layout: an entirely different aspect, > and not specific to any OS. You would still need to be able to identify the keyboard in order to know its keyboard layout, at least on X. > IMNSHO, it's too bad we rush into implementing such features without > any discussion. See above about the alternatives that, at least at > this time, seem much better to me than dragging the low-level device > type information to the application level, and in global stateful > variables on top of that. > Which once again favors the alternative that would work by defining > new kinds of events. That alternative has no compatibility issues. IMHO we cannot simply define new kinds of wheel events that purposely separate touchpads from mice, or mouse-movement events which separate trackpoints from mice. That would mean, from the perspective of the user, mice would continue to "work as before", but trackpads would not. Or a keyboard with a Greek layout would not work as it used to, while a keyboard with an English one would. It's also not possible to consistently give an individual keyboard a different keyboard layout under X, since the part of the keyboard extension for that only works with the obsolete version of the input extension, not the new one that some programs such as Emacs and most of the modern toolkits now support. I'm sorry if I rushed things, and I'd be happy to listen to any suggestions you might have. Hopefully, your concerns have also been addressed. Thanks in advance! ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 11:31 ` Po Lu @ 2022-04-08 12:12 ` Eli Zaretskii 2022-04-08 12:35 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-08 12:12 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Fri, 08 Apr 2022 19:31:28 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > That suggests a different strategy: produce different input event > > types from each such device. That'd leave the device dependency to > > low-level code, and let the application level deal with event kinds > > and not with device types. I think this is a better abstraction, if > > it's possible/feasible. > > I don't think it's feasible, especially since there are too many > different kinds of events, and with some of them those dfferent kinds of > events simply cannot work. (Think single character keyboard events.) We were talking about pixel-scroll events, not about character events. If keyboard events also depend on the device, that's a separate discussion. Let's not make the issue harder than it must be by lumping together all the possible complications. > > We have been burned by modeling the application-level features on the > > particular X implementation and low-level details. It took us > > literally decades to get rid of X-specific code and features, let > > alone API names, and move to exposing more general and more adaptable > > APIs to applications. I was there when this hard lesson was learned, > > and I'd rather we didn't repeat those mistakes. > > This API is not X specific at all; in contrast, an X-specific API would > be to expose the list of device valuators and "classes", containing > various flags. It is X-specific in that it's modeled on what X exposes. > When designing this feature, and why I purposely didn't design it based > on the X concepts of device axises and classes, I worked from two > directions: it should be possible to extract the type of a device > (i.e. tell between a touchpad, a keyboard, a pointer, and a piano), and > when possible (i.e. supported by the window system), it should be able > to tell individual devices apart. The current API achieves the first > goal by giving each device a "name", which contains enough information > to determine the device type, and it also achieves the second goal by > guaranteeing that the device names are unique to each device on window > systems which support that, such as X and Wayland. > > Each window system can then define a function for `device-class', which > returns the type of a device based on the name given to it. I'm not sure I agree with this design, sorry. E.g., having a name for a device doesn't necessarily mean we can know its type. More importantly, as I already said, I'm not sure Emacs should care about the type of the device that produced an event. We need to discuss what kinds of decisions a Lisp program would want to make that depend on the device information, and design the information based on those decisions. > This feature was already implemented not just on X, but also on PGTK, > which means it also works well with the very different input subsystems > of Wayland and Broadway. I also wrote the code to make it work with NS, > but it hasn't been tested yet. I appreciate the hard work, but I still think the design principles should be discussed. They should have been discussed before you started working, for such a non-trivial new feature, but that's water under the bridge. > > That doesn't mean you want to know about the device, it rather means > > you want to know the keyboard layout: an entirely different aspect, > > and not specific to any OS. > > You would still need to be able to identify the keyboard in order to > know its keyboard layout, at least on X. I'm talking about what kind of information is exposed to the application level, where we interpret the events. That on X and maybe other platforms we'll need to have low-level code that looks at the device is secondary. The current code exposes the device type/name to the application level, and that is what worries me. > > IMNSHO, it's too bad we rush into implementing such features without > > any discussion. See above about the alternatives that, at least at > > this time, seem much better to me than dragging the low-level device > > type information to the application level, and in global stateful > > variables on top of that. > > > Which once again favors the alternative that would work by defining > > new kinds of events. That alternative has no compatibility issues. > > IMHO we cannot simply define new kinds of wheel events that purposely > separate touchpads from mice, or mouse-movement events which separate > trackpoints from mice. That would mean, from the perspective of the > user, mice would continue to "work as before", but trackpads would not. That's easy to fix: we can add entries in relevant maps to remap trackpad events to mouse event by default, or when some minor mode is in effect. > Or a keyboard with a Greek layout would not work as it used to, while a > keyboard with an English one would. ??? As long as Emacs reads characters, I don't see how this could happen. Please elaborate. > It's also not possible to consistently give an individual keyboard a > different keyboard layout under X, since the part of the keyboard > extension for that only works with the obsolete version of the input > extension, not the new one that some programs such as Emacs and most of > the modern toolkits now support. Sorry, I cannot understand what this means in practice. Please tell more. In particular, what are those "keyboard extensions" that you mention, and how are they relevant to the issue at hand? > I'm sorry if I rushed things, and I'd be happy to listen to any > suggestions you might have. Well, I did suggest several things. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 12:12 ` Eli Zaretskii @ 2022-04-08 12:35 ` Po Lu 2022-04-09 6:48 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-08 12:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > We were talking about pixel-scroll events, not about character > events. If keyboard events also depend on the device, that's a > separate discussion. > > Let's not make the issue harder than it must be by lumping together > all the possible complications. Okay, but please keep in mind that this feature was developed to work with all events, not just pixel-scroll events. > It is X-specific in that it's modeled on what X exposes. But it's also exposed by every other window system (or at least can be trivially synthesized from the information they expose.) > I'm not sure I agree with this design, sorry. E.g., having a name for > a device doesn't necessarily mean we can know its type. The type should either be inherent in the name (as on X), or the name should be computed to include the type (as on Wayland). Otherwise, the device should just be set to the special value which says "I don't know what the device is". IOW, the platform-specific code is responsible for ensuring that `device-class' works correctly by defining the meaning of "name". > More importantly, as I already said, I'm not sure Emacs should care > about the type of the device that produced an event. We need to > discuss what kinds of decisions a Lisp program would want to make that > depend on the device information, and design the information based on > those decisions. I listed several: the pixel-scroll events are one such example, and Tetris is another. ThinkPads come with these funny joysticks that normally scroll or move the mouse pointer, but inside Tetris they might be used to control the blocks instead. Let's skip the keyboard-related discussion for now, since they're a somewhat special case. > I'm talking about what kind of information is exposed to the > application level, where we interpret the events. That on X and maybe > other platforms we'll need to have low-level code that looks at the > device is secondary. The current code exposes the device type/name to > the application level, and that is what worries me. I don't think giving too much information to the Lisp level is that big of a problem, as long as its use cases are carefully evaluated, and recommended procedures documented. Basically, there are two situations in which this information should be available: when we want some feature to behave differently based on the type of device, and when the user wants something to behave differently based on the device that is being used. The user could, for example, have a graphics tablet with buttons and an ordinary mouse connected to Emacs at the same time, and want the buttons on those two devices to behave differently. Writing such a customization would be impossible without exposing the device type and/or name to Lisp code. For the former situation, I think it's not a good idea to have code that might be used by other Lisp programs to depend on the type or name of the input device used. But it should be fine for interactive commands like pixel-scroll-precision to depend on that information, and perhaps even input methods. > That's easy to fix: we can add entries in relevant maps to remap > trackpad events to mouse event by default, or when some minor mode is > in effect. Hmm... I will try that. > ??? As long as Emacs reads characters, I don't see how this could > happen. Please elaborate. Sorry, I misunderstood what you said there. >> It's also not possible to consistently give an individual keyboard a >> different keyboard layout under X, since the part of the keyboard >> extension for that only works with the obsolete version of the input >> extension, not the new one that some programs such as Emacs and most of >> the modern toolkits now support. > > Sorry, I cannot understand what this means in practice. Please tell > more. In particular, what are those "keyboard extensions" that you > mention, and how are they relevant to the issue at hand? The X Keyboard Extension (Xkb) is the component of modern X servers that handles keymaps, and how it couples with other server extensions is orthogonal to having different keyboard layouts for different physical keyboards implemented on the server-side. In other words, if Emacs is to support such configurations, it will have to learn to understand them by itself. >> I'm sorry if I rushed things, and I'd be happy to listen to any >> suggestions you might have. > > Well, I did suggest several things. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 12:35 ` Po Lu @ 2022-04-09 6:48 ` Eli Zaretskii 2022-04-09 9:06 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 6:48 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Fri, 08 Apr 2022 20:35:58 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > We were talking about pixel-scroll events, not about character > > events. If keyboard events also depend on the device, that's a > > separate discussion. > > > > Let's not make the issue harder than it must be by lumping together > > all the possible complications. > > Okay, but please keep in mind that this feature was developed to work > with all events, not just pixel-scroll events. And you never explained in enough detail why we would need to know about "devices" when we use other event types. You said something about keyboards, but I still don't understand why we would care about the type of a keyboard. What other kinds of input could need this information, and why? > > It is X-specific in that it's modeled on what X exposes. > > But it's also exposed by every other window system (or at least can be > trivially synthesized from the information they expose.) That was not yet demonstrated. Though every system has some notion of "input device", the information they expose could be utterly different and not necessarily appropriate for us. Your additions express devices as strings, and strings don't necessarily carry any useful information to explain the significance. And I don't think you have explained anywhere what aspects of the "devices" we'd want to know about, and why. That is why I maintain that we should first think about the functionality we'd like to implement, and then see how best to allow Emacs to do that, instead of designing that bottom-up from the hardware level. > > I'm not sure I agree with this design, sorry. E.g., having a name for > > a device doesn't necessarily mean we can know its type. > > The type should either be inherent in the name (as on X), or the name > should be computed to include the type (as on Wayland). Otherwise, the > device should just be set to the special value which says "I don't know > what the device is". IOW, the platform-specific code is responsible for > ensuring that `device-class' works correctly by defining the meaning of > "name". I'm sorry, but this just repeats what you said already, and what I see in the code you installed. It doesn't get me closer to understanding the real issues. What is the "device type" and what is its significance? Are you again thinking only about regular mice vs touchpad? if so, I already suggested an alternative way to implement that. If "device type" is about something more general, please describe those more general aspects, and please try making that description as close to exhaustive as possible, because we need to see the general picture, not just its few isolated corners. > > More importantly, as I already said, I'm not sure Emacs should care > > about the type of the device that produced an event. We need to > > discuss what kinds of decisions a Lisp program would want to make that > > depend on the device information, and design the information based on > > those decisions. > > I listed several: the pixel-scroll events are one such example, and > Tetris is another. ThinkPads come with these funny joysticks that > normally scroll or move the mouse pointer, but inside Tetris they might > be used to control the blocks instead. And I suggested an alternative for dealing with these differences: new kinds of input events. AFAIU, going that way will completely avoid introducing the notion of a "device" into input events. > > I'm talking about what kind of information is exposed to the > > application level, where we interpret the events. That on X and maybe > > other platforms we'll need to have low-level code that looks at the > > device is secondary. The current code exposes the device type/name to > > the application level, and that is what worries me. > > I don't think giving too much information to the Lisp level is that big > of a problem, as long as its use cases are carefully evaluated, and > recommended procedures documented. I cannot disagree more. This leaky abstraction will soon enough be all over the place, just like with colors or mouse decades ago, where Lisp programs ended up testing for X as the only condition to assume support for mouse or colors or multiple frames. Telling Emacs Lisp programmers not to do something is not a good way of preventing them from doing that. They will do what's easy and possible, disregarding our advice as they see fit. We will be unable to control that efficiently, not even in core, because we cannot be omnipresent and omniscient. > Basically, there are two situations in which this information should be > available: when we want some feature to behave differently based on the > type of device, and when the user wants something to behave differently > based on the device that is being used. I'm still waiting for enough examples of this to even agree that it's an issue, let alone an issue we want to solve in Emacs. > The user could, for example, have a graphics tablet with buttons and an > ordinary mouse connected to Emacs at the same time, and want the buttons > on those two devices to behave differently. We do? why? I think we definitely DON'T. Emacs is not a GUI toolkit, it is a client of such toolkits. We use toolkits because we do NOT want to deal with device-dependent behavior, we want to use device-independent abstractions. If some device is unable to do something, it will not produce events that express that functionality, and the corresponding Emacs commands will not be invoked. That is all I think Emacs needs to support each input device as appropriate. > The X Keyboard Extension (Xkb) is the component of modern X servers that > handles keymaps, and how it couples with other server extensions is > orthogonal to having different keyboard layouts for different physical > keyboards implemented on the server-side. In other words, if Emacs is > to support such configurations, it will have to learn to understand them > by itself. I don't think I understand. What would you like Emacs to support in conjunction with Xkb, and what will Emacs have to learn about that for it to "understand" those "configurations" (and what are those "configurations", btw, i.e. what discerns one "configuration" from another?). ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 6:48 ` Eli Zaretskii @ 2022-04-09 9:06 ` Po Lu 2022-04-09 9:09 ` Lars Ingebrigtsen 2022-04-09 9:30 ` Eli Zaretskii 0 siblings, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-09 9:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > And you never explained in enough detail why we would need to know > about "devices" when we use other event types. You said something > about keyboards, but I still don't understand why we would care about > the type of a keyboard. > > What other kinds of input could need this information, and why? Well as another example, artist-mode might want to behave differently with an "eraser" pointer, removing pixels from the picture instead of adding them. Different keyboard might have different layouts (and input methods want to behave differently), or lilypond-mode might want to insert notes directly from a MIDI keyboard while allowing typing from a normal keyboard. > That was not yet demonstrated. Though every system has some notion of > "input device", the information they expose could be utterly different > and not necessarily appropriate for us. Your additions express > devices as strings, and strings don't necessarily carry any useful > information to explain the significance. And I don't think you have > explained anywhere what aspects of the "devices" we'd want to know > about, and why. We want to know whether a device is a mouse, trackpoint, eraser, pen, puck, device control, keyboard, touchscreen, touchpad or MIDI keyboard, and whether or not it's a different device from some other device, and also tell apart a single device from anotherq whenever possible. What would you think about allowing the device structure to be something other than a string (i.e. window-system dependent, like the argument to drag-n-drop events), that should be treated as opaque except when passed to functions like `device-class', and probably `device-equal'? > I'm sorry, but this just repeats what you said already, and what I see > in the code you installed. It doesn't get me closer to understanding > the real issues. What is the "device type" and what is its > significance? Are you again thinking only about regular mice vs > touchpad? if so, I already suggested an alternative way to implement > that. If "device type" is about something more general, please > describe those more general aspects, and please try making that > description as close to exhaustive as possible, because we need to see > the general picture, not just its few isolated corners. No, I was thinking of different kinds of devices as well. The list I chose to document in `device-class' should be a fairly exhaustive union of what the window systems we currently support have. They are (in no particular order) keyboards, mice, joysticks, erasers, styluses, pucks, device controls, touchscreens, tablet buttons, MIDI keyboards and test devices. Emacs currently doesn't have support on the C level for getting events from devices outside those categories, at least on X and PGTK. > And I suggested an alternative for dealing with these differences: new > kinds of input events. AFAIU, going that way will completely avoid > introducing the notion of a "device" into input events. That won't be very flexible, and it'll be very difficult for the user to write customizations for some new kind of device (or just a different device) without adding an entirely new kind of input event for it. > I'm still waiting for enough examples of this to even agree that it's > an issue, let alone an issue we want to solve in Emacs. > >> The user could, for example, have a graphics tablet with buttons and an >> ordinary mouse connected to Emacs at the same time, and want the buttons >> on those two devices to behave differently. > > We do? why? I think we definitely DON'T. Emacs is not a GUI toolkit, > it is a client of such toolkits. We use toolkits because we do NOT > want to deal with device-dependent behavior, we want to use > device-independent abstractions. If some device is unable to do > something, it will not produce events that express that functionality, > and the corresponding Emacs commands will not be invoked. That is all > I think Emacs needs to support each input device as appropriate. To most programs, the graphics tablet buttons are just mouse buttons. In Emacs, they will just send mouse-1 through 8 when clicked. 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? > I don't think I understand. What would you like Emacs to support in > conjunction with Xkb, and what will Emacs have to learn about that for > it to "understand" those "configurations" (and what are those > "configurations", btw, i.e. what discerns one "configuration" from > another?). The simple use case of having two different keyboards behave differently. In my own specific case, they are printed with different layouts (one is US International, the other is Russian), but X only allows one keyboard layout for both the keyboards to be active. So to me, it would be nice to have different input methods for each individual keyboard, in order to not have to manually switch input methods each time. But I'm sure this feature will be much more generally useful as well. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 9:06 ` Po Lu @ 2022-04-09 9:09 ` Lars Ingebrigtsen 2022-04-09 9:30 ` Eli Zaretskii 1 sibling, 0 replies; 86+ messages in thread From: Lars Ingebrigtsen @ 2022-04-09 9:09 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, monnier, emacs-devel Po Lu <luangruo@yahoo.com> writes: > We want to know whether a device is a mouse, trackpoint, eraser, pen, > puck, device control, keyboard, touchscreen, touchpad or MIDI keyboard, > and whether or not it's a different device from some other device, and > also tell apart a single device from anotherq whenever possible. Yes, this would be very, very useful. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 9:06 ` Po Lu 2022-04-09 9:09 ` Lars Ingebrigtsen @ 2022-04-09 9:30 ` Eli Zaretskii 2022-04-09 10:03 ` Po Lu 1 sibling, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 9:30 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 17:06:35 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > And you never explained in enough detail why we would need to know > > about "devices" when we use other event types. You said something > > about keyboards, but I still don't understand why we would care about > > the type of a keyboard. > > > > What other kinds of input could need this information, and why? > > Well as another example, artist-mode might want to behave differently > with an "eraser" pointer, removing pixels from the picture instead of > adding them. Why cannot this be handled by producing special events that erase pixels? > Different keyboard might have different layouts (and input > methods want to behave differently) I don't think I understand why, see below. > or lilypond-mode might want to insert notes directly from a MIDI > keyboard while allowing typing from a normal keyboard. Again, why not implement this as special events? > > That was not yet demonstrated. Though every system has some notion of > > "input device", the information they expose could be utterly different > > and not necessarily appropriate for us. Your additions express > > devices as strings, and strings don't necessarily carry any useful > > information to explain the significance. And I don't think you have > > explained anywhere what aspects of the "devices" we'd want to know > > about, and why. > > We want to know whether a device is a mouse, trackpoint, eraser, pen, > puck, device control, keyboard, touchscreen, touchpad or MIDI keyboard, > and whether or not it's a different device from some other device, and > also tell apart a single device from anotherq whenever possible. I still don't understand why special-purpose events cannot solve the same problems. Maybe even specialized mode with the same events. > What would you think about allowing the device structure to be something > other than a string (i.e. window-system dependent, like the argument to > drag-n-drop events), that should be treated as opaque except when passed > to functions like `device-class', and probably `device-equal'? If we must. But I'm not yet convinced we must have this information. > > And I suggested an alternative for dealing with these differences: new > > kinds of input events. AFAIU, going that way will completely avoid > > introducing the notion of a "device" into input events. > > That won't be very flexible, and it'll be very difficult for the user to > write customizations for some new kind of device (or just a different > device) without adding an entirely new kind of input event for it. Please explain these two counter-arguments in more detail. Why "not very flexible" and why it will make customizations more difficult? > > We do? why? I think we definitely DON'T. Emacs is not a GUI toolkit, > > it is a client of such toolkits. We use toolkits because we do NOT > > want to deal with device-dependent behavior, we want to use > > device-independent abstractions. If some device is unable to do > > something, it will not produce events that express that functionality, > > and the corresponding Emacs commands will not be invoked. That is all > > I think Emacs needs to support each input device as appropriate. > > To most programs, the graphics tablet buttons are just mouse buttons. > In Emacs, they will just send mouse-1 through 8 when clicked. And why is that a problem? We already interpret mouse-4 and mouse-5 as the wheel, so why not have mouse-8 be interpreted in some special way? > 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? > > I don't think I understand. What would you like Emacs to support in > > conjunction with Xkb, and what will Emacs have to learn about that for > > it to "understand" those "configurations" (and what are those > > "configurations", btw, i.e. what discerns one "configuration" from > > another?). > > The simple use case of having two different keyboards behave > differently. In my own specific case, they are printed with different > layouts (one is US International, the other is Russian), but X only > allows one keyboard layout for both the keyboards to be active. Please tell more: how do they behave differently? If you press a key that is labeled with some character, doesn't Emacs receive a keyboard input event with that character? > So to me, it would be nice to have different input methods for each > individual keyboard, in order to not have to manually switch input > methods each time. We could have a keyboard-layout switch event, which would change input methods automatically. (On MS-Windows, we already have such an event.) Once again, low-level code does know about these details, and that is not a problem IMO; it is exposing that to Lisp as "device" that I don't like. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 9:30 ` Eli Zaretskii @ 2022-04-09 10:03 ` Po Lu 2022-04-09 11:03 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-09 10:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Well as another example, artist-mode might want to behave differently >> with an "eraser" pointer, removing pixels from the picture instead of >> adding them. > > Why cannot this be handled by producing special events that erase > pixels? Because this puts us on the very inflexible path of adding special events for every single input device that users might want. Besides, the erasers send ordinary button and motion events, specifically so that programs can better consume input they generate without needing to handle a special new kind of event. > I still don't understand why special-purpose events cannot solve the > same problems. Maybe even specialized mode with the same events. >> That won't be very flexible, and it'll be very difficult for the user to >> write customizations for some new kind of device (or just a different >> device) without adding an entirely new kind of input event for it. > > Please explain these two counter-arguments in more detail. Why "not > very flexible" and why it will make customizations more difficult? Let's say the developers come up with a special input device for entering notes. Such a device would have a special name, and send either key or button presses. Without exposing slightly low level information about the device itself to Lisp code, users of such a device would be forced to ask us to add an event specifically for that device, in order to use it in Emacs simultaneously with other keyboards or mice. We would have to add events for every device users want to use with Emacs (and there are many, ranging from electronic keyboards to foot pedals), or we could simply expose the information necessary for their own customizations to identify the device. The device names are guaranteed to reliably identify a device on GNU/Linux and other systems that run X Windows or Wayland. If the feature does not completely work on other systems, too bad, but I think it can be made to work on NS with sufficient coaxing, and probably on MS Windows too, via the "wintab" and "winpointer" APIs that GTK and Firefox seem to be using. > And why is that a problem? We already interpret mouse-4 and mouse-5 > as the wheel, so why not have mouse-8 be interpreted in some special > way? Because mouse-8 is already the horizontal scroll wheel on normal mice. The point is, the graphics tablet buttons send the exact same events that ordinary mice do, but users might want them to behave differently. So there has to be a way to identify each device connected to the computer. And with some use cases, we simply want different devices of the same type (ordinary computer mice) to behave differently. >> 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? How would you decide from which mice ordinary button events should come, and what others without knowing their names? Or some other unique identifier, A.K.A a name? > Please tell more: how do they behave differently? If you press a key > that is labeled with some character, doesn't Emacs receive a keyboard > input event with that character? Let's say I want to insert "завод" from the Russian keyboard. If I don't manually switch the active keyboard layout on the X server-side when I start typing, the characters the X server sends to Emacs are in the US International keymap, so that becomes "pfdjl". Similarly, if I want to type "factory" in English, I have to switch the active keyboard layout to US International, or otherwise what is sent to Emacs is "афсещкн". While with the feature to retrieve device information as it is currently implemented, I could eventually configure the input method to be `russian-computer' when the device which sent the keyboard input is named "Innovation HID usb keyboard" instead of "AT Translated Set 2 keyboard", the built-in US International keyboard on my laptop. > We could have a keyboard-layout switch event, which would change input > methods automatically. (On MS-Windows, we already have such an > event.) Once again, low-level code does know about these details, and > that is not a problem IMO; it is exposing that to Lisp as "device" > that I don't like. That would still have to expose some way to uniquely identify each keyboard to the user. At the very least, we would need an alist of keyboard device names to the correct keyboard layout. Thanks in advance. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 10:03 ` Po Lu @ 2022-04-09 11:03 ` Eli Zaretskii 2022-04-09 11:44 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 11:03 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 18:03:20 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> Well as another example, artist-mode might want to behave differently > >> with an "eraser" pointer, removing pixels from the picture instead of > >> adding them. > > > > Why cannot this be handled by producing special events that erase > > pixels? > > Because this puts us on the very inflexible path of adding special > events for every single input device that users might want. No, only for events that are specific to the device and not available in other devices. > Besides, > the erasers send ordinary button and motion events, specifically so that > programs can better consume input they generate without needing to > handle a special new kind of event. 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? > >> That won't be very flexible, and it'll be very difficult for the user to > >> write customizations for some new kind of device (or just a different > >> device) without adding an entirely new kind of input event for it. > > > > Please explain these two counter-arguments in more detail. Why "not > > very flexible" and why it will make customizations more difficult? > > Let's say the developers come up with a special input device for > entering notes. Such a device would have a special name, and send > either key or button presses. > > Without exposing slightly low level information about the device itself > to Lisp code, users of such a device would be forced to ask us to add an > event specifically for that device, in order to use it in Emacs > simultaneously with other keyboards or mice. And what would happen instead under your design and implementation? won't we need to add code to recognize the new device? > The device names are guaranteed to reliably identify a device on > GNU/Linux and other systems that run X Windows or Wayland. 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. 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. > > And why is that a problem? We already interpret mouse-4 and mouse-5 > > as the wheel, so why not have mouse-8 be interpreted in some special > > way? > > Because mouse-8 is already the horizontal scroll wheel on normal mice. > The point is, the graphics tablet buttons send the exact same events > that ordinary mice do, but users might want them to behave differently. 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. > >> 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? > > 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? > > Please tell more: how do they behave differently? If you press a key > > that is labeled with some character, doesn't Emacs receive a keyboard > > input event with that character? > > Let's say I want to insert "завод" from the Russian keyboard. If I > don't manually switch the active keyboard layout on the X server-side > when I start typing, the characters the X server sends to Emacs are in > the US International keymap, so that becomes "pfdjl". Similarly, if I > want to type "factory" in English, I have to switch the active keyboard > layout to US International, or otherwise what is sent to Emacs is > "афсещкн". > > While with the feature to retrieve device information as it is currently > implemented, I could eventually configure the input method to be > `russian-computer' when the device which sent the keyboard input is > named "Innovation HID usb keyboard" instead of "AT Translated Set 2 > keyboard", the built-in US International keyboard on my laptop. 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. > > We could have a keyboard-layout switch event, which would change input > > methods automatically. (On MS-Windows, we already have such an > > event.) Once again, low-level code does know about these details, and > > that is not a problem IMO; it is exposing that to Lisp as "device" > > that I don't like. > > That would still have to expose some way to uniquely identify each > keyboard to the user. 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. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 11:03 ` Eli Zaretskii @ 2022-04-09 11:44 ` Po Lu 2022-04-09 14:04 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-09 11:44 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> 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) (cond ((eq draw-how 'artist-do-continously) - (artist-mouse-draw-continously ev)) + (artist-mouse-draw-continously ev + (when (eq (device-class last-event-frame + last-event-device) + 'eraser) + 'erase-char))) ((eq draw-how 'artist-do-poly) (artist-mouse-draw-poly ev)) ((and (numberp draw-how) (= draw-how 1)) @@ -4897,14 +4901,16 @@ artist--adjust-x x (- x adjust 2)))) -(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))) - (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) - (artist-draw-region-reset) + (artist-draw-region-reset) - (artist-mode-line-show-curr-operation t) + (artist-mode-line-show-curr-operation t) - (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) (= draw-how 1)) - (artist-mouse-draw-1point ev)) - ((and (numberp draw-how) (= 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) (= draw-how 1)) + (artist-mouse-draw-1point ev)) + ((and (numberp draw-how) (= draw-how 2)) + (artist-mouse-draw-2points ev)) + (t (message "Drawing \"%s\"s is not yet implemented" + draw-how))) - (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)) - ; 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)) - (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)) - (artist-mode-line-show-curr-operation artist-key-is-drawing)))) + (artist-mode-line-show-curr-operation artist-key-is-drawing))))) >> >> 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? >> >> 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 "я", 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. ^ permalink raw reply related [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 11:44 ` Po Lu @ 2022-04-09 14:04 ` Eli Zaretskii 2022-04-09 16:33 ` Stefan Monnier 2022-04-10 0:48 ` Po Lu 0 siblings, 2 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 14:04 UTC (permalink / raw) To: Po Lu, Richard Stallman, Lars Ingebrigtsen; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 19:44:57 +0800 > > Eli Zaretskii <eliz@gnu.org> 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. If the events are to be interpreted as usual in some situations and differently in others, we could have a special mode or variable to change the produced events only when we want that to be. Alternatively, we could always produce special kinds of events, and have them mapped to the same commands as the "normal" events. For example, touchpad-button-1 could be mapped to the same command as mouse-1 in most cases, but when we want to treat those touchpad events specially, we could rebind them to other commands. Similar to how we usually make shifted keys to invoke the same commands as unshifted keys, unless there's actually a binding for the shifted key. > > 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. That's exactly what I was afraid of: that commands will need to care about devices. Next we will have N devices for X Windows, M different devices for NS, Y devices for MS-Windows (some of them similar to X, others similar to NS), etc. -- and commands will have to dispatch on all those devices, right? Does this really sound clean and maintainable? Am I really the only one who's worried by that kind of design? Stefan, Lars, Richard? > > 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.) What does it matter who personally will write the code -- it will need to be written, and sooner or later will find its way into the core. "Please accept this patch that adds the device I have here and would like to be able to use with Emacs, but it is not yet in the list of devices Emacs supports." Sounds familiar? > > 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. Yes, and then someone develops another compositor and provides names that are identical to Wayland for different devices, or different names for the same devices. Each team of toolkit developers might be consistent with itself, but why should we believe they are consistent with each other? > (cond ((eq draw-how 'artist-do-continously) > - (artist-mouse-draw-continously ev)) > + (artist-mouse-draw-continously ev > + (when (eq (device-class last-event-frame > + last-event-device) > + 'eraser) > + 'erase-char))) Do you really believe this is how Emacs's application code should be written? We don't distinguish between different devices in file I/O, although different filesystem definitely support different features. Instead, where abstractions could be devised that could express different underlying implementations, we have such abstractions in Emacs. Example: file-extended-attributes, which allow us to transparently support several variants of Posix-style and NTFS-style ACLs. And where no such abstractions can be made or make sense, we have specific features supported only by some filesystems, while others just error out or return trivial values. But we never-ever ask the filesystem what is its type and use that to change application code. Why should input event be any different? > >> 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? I don't need the name, I only need its number. > Besides, window systems have a limit on the largest button that can > be reported. I'm not talking about the raw event that we receive from the window-system, I'm talking about a lispy event we insert into the event queue. There we can support any number of mouse buttons and any number of mice. > > 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'. There are many ways to wrap your ideas into Lisp data structures. However, being able to do so doesn't yet make the idea right; I consider all of those ways not the best design, to say the least. Having the low-level information about the devices at that level is simply wrong, IMO. It is definitely to be avoided as much as we can, so I urge you to try alternative ideas that hide this information on lower levels without hampering the features we can build on them. > > 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 "я", and the system keyboard layout is on > US International, the event Emacs gets is "z", and vice versa. Yes, and where we produce the lispy keystroke event, we can convert that to "я", given the low-level information about the keyboard which emitted the key. This way, no Lisp will need to know anything about the device. I think I have said in this thread everything I have to say about this, more than once. To summarize: I think this design is wrong, and it is generally undesirable to have the device type information at the command level, forcing high-level application code to deal with such low-level information. Emacs has enough features and paradigms to conceal this low-level information below the event queue level, in a way that will allow the same features to be developed, without exposing the device type to Lisp. So I object to the design you presented and are already implementing. I sincerely hope that I'm not the only one to think that this design is sub-optimal, and that we should use a different one, whose basic aspects I described. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 14:04 ` Eli Zaretskii @ 2022-04-09 16:33 ` Stefan Monnier 2022-04-09 16:41 ` Lars Ingebrigtsen 2022-04-10 0:48 ` Po Lu 1 sibling, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-09 16:33 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Po Lu, Richard Stallman, Lars Ingebrigtsen, emacs-devel > If the events are to be interpreted as usual in some situations and > differently in others, we could have a special mode or variable to > change the produced events only when we want that to be. I'd prefer we don't do that. This is the kind of thing we do for `keyboard-coding-system` (the (sequence of) events we generate depends on that variable) and it causes real problems for all those places in the code that want to peek at the next event without consuming it (starting with `sit-for`). > Alternatively, we could always produce special kinds of events, and > have them mapped to the same commands as the "normal" events. For > example, touchpad-button-1 could be mapped to the same command as > mouse-1 in most cases, but when we want to treat those touchpad events > specially, we could rebind them to other commands. This behaves better, indeed. The downside is that we currently don't have a good way to define remapping like `touchpad-button-1` to `mouse-1` (the mechanism we have works for that exact event but you then need to add N other mappings for the cases where it's combined with control, meta, meta+control, hyper+control, shift+control+double, ...). >> The individual command will have to know about the device to treat it >> correctly, just as elsewhere: web browsers, programs using GTK, Qt, etc. Elsewhere tells us that the behavior depends on the device, but not that the choice is made within their equivalent of "individual commands" nor that this place would be the better choice. I don't know where's the better place in general but if it can be made via keymaps it might be preferable since we usually don't like commands to behave differently for different events, we prefer instead to have the keymaps decide which command to use for which event and then have the command be oblivious to the event. [ There are some notable exceptions to this general design, admittedly. E.g. `self-insert-command` looks at the event to know which char to insert, or the commands which obey `use-dialog-box` of those that obey `shift-select-mode`. ] > Does this really sound clean and maintainable? Am I really the only > one who's worried by that kind of design? Stefan, Lars, Richard? I agree that we'll usually want to hide those issues from commands. I don't think the current code which exposes the device name to ELisp is wrong, OTOH (after all, I like to keep the C code to a minimum). But it's just not sufficient in the sense that we want to add to it some abstraction layer so individual commands don't need to know about the various possible input devices. Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 16:33 ` Stefan Monnier @ 2022-04-09 16:41 ` Lars Ingebrigtsen 2022-04-09 17:06 ` Eli Zaretskii 2022-04-10 0:37 ` Po Lu 0 siblings, 2 replies; 86+ messages in thread From: Lars Ingebrigtsen @ 2022-04-09 16:41 UTC (permalink / raw) To: Stefan Monnier; +Cc: Po Lu, Eli Zaretskii, Richard Stallman, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > I don't know where's the better place in general but if it can be made > via keymaps it might be preferable since we usually don't like commands > to behave differently for different events, we prefer instead to have > the keymaps decide which command to use for which event and then have > the command be oblivious to the event. I haven't followed this thread closely, but yes, that's the design I hope we can end up with. For instance, I have a pedal that's a USB HID thingie. Amusingly enough, stomping on the pedal gives me a "b" event. The key "b", indistinguishable from a "b" from the keyboard. So if I could somehow say (keymap-set global-mode-map "[device footpad]-b" 'do-something) that would be ideal. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 16:41 ` Lars Ingebrigtsen @ 2022-04-09 17:06 ` Eli Zaretskii 2022-04-09 17:16 ` Eli Zaretskii 2022-04-09 17:52 ` Brian Cully 2022-04-10 0:37 ` Po Lu 1 sibling, 2 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 17:06 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: luangruo, emacs-devel, monnier, rms > From: Lars Ingebrigtsen <larsi@gnus.org> > Cc: Eli Zaretskii <eliz@gnu.org>, Po Lu <luangruo@yahoo.com>, Richard > Stallman <rms@gnu.org>, emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 18:41:52 +0200 > > For instance, I have a pedal that's a USB HID thingie. Amusingly > enough, stomping on the pedal gives me a "b" event. The key "b", > indistinguishable from a "b" from the keyboard. > > So if I could somehow say > > (keymap-set global-mode-map "[device footpad]-b" 'do-something) > > that would be ideal. I would hope that such an event could be called just 'footpad-b', so that any device capable of such events could be implemented as emitting it, regardless of the device name/type/etc. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 17:06 ` Eli Zaretskii @ 2022-04-09 17:16 ` Eli Zaretskii 2022-04-09 17:52 ` Brian Cully 1 sibling, 0 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 17:16 UTC (permalink / raw) To: larsi; +Cc: luangruo, monnier, rms, emacs-devel > Date: Sat, 09 Apr 2022 20:06:00 +0300 > From: Eli Zaretskii <eliz@gnu.org> > Cc: luangruo@yahoo.com, emacs-devel@gnu.org, monnier@iro.umontreal.ca, > rms@gnu.org > > > From: Lars Ingebrigtsen <larsi@gnus.org> > > Cc: Eli Zaretskii <eliz@gnu.org>, Po Lu <luangruo@yahoo.com>, Richard > > Stallman <rms@gnu.org>, emacs-devel@gnu.org > > Date: Sat, 09 Apr 2022 18:41:52 +0200 > > > > For instance, I have a pedal that's a USB HID thingie. Amusingly > > enough, stomping on the pedal gives me a "b" event. The key "b", > > indistinguishable from a "b" from the keyboard. > > > > So if I could somehow say > > > > (keymap-set global-mode-map "[device footpad]-b" 'do-something) > > > > that would be ideal. > > I would hope that such an event could be called just 'footpad-b', so > that any device capable of such events could be implemented as > emitting it, regardless of the device name/type/etc. Actually, '[footpad b] would even be better, i.e. a key sequence that consists of 'footpad; followed by 'b'. This way we will be able to express many possible keys produced by such devices using just one prefix key. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 17:06 ` Eli Zaretskii 2022-04-09 17:16 ` Eli Zaretskii @ 2022-04-09 17:52 ` Brian Cully 2022-04-09 19:18 ` Eli Zaretskii 2022-04-10 0:54 ` Po Lu 1 sibling, 2 replies; 86+ messages in thread From: Brian Cully @ 2022-04-09 17:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: luangruo, Lars Ingebrigtsen, emacs-devel, monnier, rms Eli Zaretskii <eliz@gnu.org> writes: >> From: Lars Ingebrigtsen <larsi@gnus.org> >> (keymap-set global-mode-map "[device footpad]-b" 'do-something) >> >> that would be ideal. > > I would hope that such an event could be called just 'footpad-b', so > that any device capable of such events could be implemented as > emitting it, regardless of the device name/type/etc. I may have missed this earlier in the thread, but where would these mappings of device identifier (name, USB VID:PID, whatever) to device classes come from? How would that work for devices that can be made to look like a *lot* of different input types? I’ve got a Steam Controller I can set up as a joystick, keyboard (HID report and boot protocols), relative and absolute mouse, all at the same time, and I can swap its functions on the fly. I’ve got a mouse that can send both “pixel” scroll events as well as normal line-based ones depending on how it’s configured. I have a programmable keyboard that I can make look like any USB device I want. Is Emacs going to be responsible for mapping thousands of device identifiers to device classes (which may change at runtime?) I just don’t understand what this looks like from a user’s perspective. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 17:52 ` Brian Cully @ 2022-04-09 19:18 ` Eli Zaretskii 2022-04-10 0:54 ` Po Lu 1 sibling, 0 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 19:18 UTC (permalink / raw) To: Brian Cully; +Cc: luangruo, larsi, emacs-devel, monnier, rms > From: Brian Cully <bjc@spork.org> > Cc: Lars Ingebrigtsen <larsi@gnus.org>, luangruo@yahoo.com, > monnier@iro.umontreal.ca, rms@gnu.org, emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 13:52:52 -0400 > > > I would hope that such an event could be called just 'footpad-b', so > > that any device capable of such events could be implemented as > > emitting it, regardless of the device name/type/etc. > > I may have missed this earlier in the thread, but where would > these mappings of device identifier (name, USB VID:PID, whatever) to > device classes come from? How would that work for devices that can be > made to look like a *lot* of different input types? The same way any other input event works: Emacs generates a Lisp form of each event in low-level C code. > I’ve got a Steam Controller I can set up as a joystick, keyboard > (HID report and boot protocols), relative and absolute mouse, all at the > same time, and I can swap its functions on the fly. I’ve got a mouse > that can send both “pixel” scroll events as well as normal line-based > ones depending on how it’s configured. I have a programmable keyboard > that I can make look like any USB device I want. > > Is Emacs going to be responsible for mapping thousands of device > identifiers to device classes (which may change at runtime?) I just > don’t understand what this looks like from a user’s perspective. When your device behaves like a joystick, it will emit events that joysticks produce, and Emacs will treat that as a joystick. If this still doesn't help, my suggestion is to follow the code that produces existing events in Emacs, for example mouse events. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 17:52 ` Brian Cully 2022-04-09 19:18 ` Eli Zaretskii @ 2022-04-10 0:54 ` Po Lu 2022-04-10 1:46 ` Brian Cully 1 sibling, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 0:54 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, Lars Ingebrigtsen, emacs-devel, monnier, rms Brian Cully <bjc@spork.org> writes: > I may have missed this earlier in the thread, but where would > these mappings of device identifier (name, USB VID:PID, whatever) to > device classes come from? How would that work for devices that can be > made to look like a *lot* of different input types? We look at the device name provided by the X input extension. It is not calculated based on any USB identifiers. > I’ve got a Steam Controller I can set up as a joystick, keyboard > (HID report and boot protocols), relative and absolute mouse, all at the > same time, and I can swap its functions on the fly. I’ve got a mouse > that can send both “pixel” scroll events as well as normal line-based > ones depending on how it’s configured. I have a programmable keyboard > that I can make look like any USB device I want. That can be identified by the kind of event it is currently sending. When it sends "smooth" scroll events, Emacs gets a wheel event with the right valuators. When it sends line-based scroll events, Emacs gets one without. If it's configured as a relative mouse, Emacs will get mouse movement events; as an absolute mouse, touch events (I think). > Is Emacs going to be responsible for mapping thousands of device > identifiers to device classes (which may change at runtime?) I just > don’t understand what this looks like from a user’s perspective. The input driver is responsible to name the devices and to set the appropriate properties. Otherwise the devices will not work correctly with any other program either. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 0:54 ` Po Lu @ 2022-04-10 1:46 ` Brian Cully 2022-04-10 2:11 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-10 1:46 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, Lars Ingebrigtsen, rms, monnier Po Lu <luangruo@yahoo.com> writes: > Brian Cully <bjc@spork.org> writes: > >> I may have missed this earlier in the thread, but where would >> these mappings of device identifier (name, USB VID:PID, whatever) to >> device classes come from? How would that work for devices that can be >> made to look like a *lot* of different input types? > > We look at the device name provided by the X input extension. It is not > calculated based on any USB identifiers. I did not mean to imply it was, just that there was some way of obtaining a unique name for a device. >> Is Emacs going to be responsible for mapping thousands of device >> identifiers to device classes (which may change at runtime?) I just >> don’t understand what this looks like from a user’s perspective. > > The input driver is responsible to name the devices and to set the > appropriate properties. Otherwise the devices will not work correctly > with any other program either. But my input driver is, for instance, a USB HID driver, and only cares about the usage tables my device is using. I can plug whatever device I want in, regardless of any kind of unique or stable identifier, by virtue of it responding correctly to probes from the USB layer describing its capabilities. Everything built on top of this stack Just Works, no matter how I name the device. I see very much the value in being able to differentiate similar or identical events based on their source, but my worry has been about having Emacs somehow decide for me that because my device is named “X” it has capabilities w, y, and z. In a previous email, it seems as though your thoughts are around having the user specify capabilities or event mappings themselves based on the device name. I don’t know nearly enough about the specifics to comment on any particular approach, but I am reasonably sure I don’t want Emacs making those decisions for me. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 1:46 ` Brian Cully @ 2022-04-10 2:11 ` Po Lu 2022-04-10 2:45 ` Brian Cully 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 2:11 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, Lars Ingebrigtsen, rms, monnier Brian Cully <bjc@spork.org> writes: > But my input driver is, for instance, a USB HID driver, and only > cares about the usage tables my device is using. I can plug whatever > device I want in, regardless of any kind of unique or stable identifier, > by virtue of it responding correctly to probes from the USB layer > describing its capabilities. Everything built on top of this stack Just > Works, no matter how I name the device. Then the input driver will set the right properties depending on which events are currently being sent, and Emacs will also take into account which events are being generated to decide how it behaves. > I see very much the value in being able to differentiate similar > or identical events based on their source, but my worry has been about > having Emacs somehow decide for me that because my device is named “X” > it has capabilities w, y, and z. No, Lisp code will decide based on the class of your device (on X, that's calculated based on the name) _and_ the events it is currently generating that it has capabilities x, y and z. > In a previous email, it seems as though your thoughts are around > having the user specify capabilities or event mappings themselves based > on the device name. I don’t know nearly enough about the specifics to > comment on any particular approach, but I am reasonably sure I don’t > want Emacs making those decisions for me. That was specifically referring to user customisations. Either way, I severely doubt this is a real problem, since such a device would be fairly useless if it couldn't work with other programs such as Firefox, LibreOffice, etc. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 2:11 ` Po Lu @ 2022-04-10 2:45 ` Brian Cully 2022-04-10 3:30 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-10 2:45 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, monnier, Lars Ingebrigtsen, rms, emacs-devel Po Lu <luangruo@yahoo.com> writes: > No, Lisp code will decide based on the class of your device (on X, > that's calculated based on the name) _and_ the events it is currently > generating that it has capabilities x, y and z. This is what’s not clear to me. Is Lisp code that’s shipping as part of the standard Emacs distribution making this classification, or am I doing it in my user customizations? My understanding is that X (and Wayland) pull their classification from evdev/libinput, which itself pulls from the HID descriptors. The name of the device doesn’t figure, except for things like desktop input settings panels, as a way to differentiate devices. I can (and do!) change how some of my USB devices present themselves without changing their names. I’ve never had any kind of issue, so I’m not sure why the name would be considered important information in terms of classification. I /do/ see the value for user customization, similar to how desktop input settings also differentiate devices based on their name to customize behavior, but this seems to me to be a user-level concern, as long as there is machinery to support it. If that’s what you’ve been suggesting, I apologize, as I haven’t read it as such (perhaps I’ve missed the forest for the trees here). -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 2:45 ` Brian Cully @ 2022-04-10 3:30 ` Po Lu 0 siblings, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-10 3:30 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, monnier, Lars Ingebrigtsen, rms, emacs-devel Brian Cully <bjc@spork.org> writes: > This is what’s not clear to me. Is Lisp code that’s shipping as > part of the standard Emacs distribution making this classification, or > am I doing it in my user customizations? Your user customizations and hopefully some of the standard code as well (pixel-scroll-precision-mode comes to mind.) Let me try to explain: your adaptable USB mouse might be configured to send coarse wheel events. In that case, Emacs gets an ordinary wheel-down/wheel-up event without any precision scrolling information. Now, the device class will probably show up as a "mouse" as well, so Emacs knows it is configured as a mouse that is configured to scroll by lines. But if you set it up to send detailed valuator information, then Emacs will know it's a mouse configured with precision scrolling information, and then scroll in an interpolated fashion. > My understanding is that X (and Wayland) pull their > classification from evdev/libinput, which itself pulls from the HID > descriptors. The name of the device doesn’t figure, except for things > like desktop input settings panels, as a way to differentiate devices. X doesn't "pull" its classifications from anything. The individual input drivers are supposed to put it in the name and device properties, and then toolkits are determine what it is based on that. Since device properties are very input driver dependent and don't help to uniquely identify a device, we use the name instead. Wayland is different: it includes the classification inside the devices in each seat. So Emacs simply includes that classification in the name, and `device-class' returns that directly. (But it's too early to talk about how exactly Wayland will end up doing things, since aside from keyboards, mice and touchscreens the rest of the required protocol extensions are not stable yet.) > I can (and do!) change how some of my USB devices present > themselves without changing their names. I’ve never had any kind of > issue, so I’m not sure why the name would be considered important > information in terms of classification. You don't have to change their names, the device drivers and input extension do whenever appropriate. But I suspect that your device does not cause a change in any sort of "classification", instead it just generates different input events based on what it is currently configured to do, in which case you should see above. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 16:41 ` Lars Ingebrigtsen 2022-04-09 17:06 ` Eli Zaretskii @ 2022-04-10 0:37 ` Po Lu 2022-04-10 5:49 ` Eli Zaretskii 2022-04-10 11:41 ` Lars Ingebrigtsen 1 sibling, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-10 0:37 UTC (permalink / raw) To: Lars Ingebrigtsen Cc: Stefan Monnier, Eli Zaretskii, Richard Stallman, emacs-devel Lars Ingebrigtsen <larsi@gnus.org> writes: > For instance, I have a pedal that's a USB HID thingie. Amusingly > enough, stomping on the pedal gives me a "b" event. The key "b", > indistinguishable from a "b" from the keyboard. Exactly. This is partly the sort of use case I designed this feature for. > So if I could somehow say > > (keymap-set global-mode-map "[device footpad]-b" 'do-something) > > that would be ideal. Oh yes, that would be good as well. We could have the ability to bind keys to individual devices. I could imagine a different API that didn't put the device name into the name of the key, though: there could be a system for making keymaps "device-local", or even better device-specific bindings in a keymap: (keymap-set global-mode-map "b" #'do-something "name of footpad") And the "name of footpad" can reasonably be system dependent, since the user will be making such a customization, and he can look in the output of `xinput list' (or the system's input preferences.) We could also have a system like: (keymap-set global-mode-map "<wheel-down>" #'pixel-scroll-precision-interpolate 'mouse) Where the last part doesn't have to be window system dependent, as long as it's one of the values documented in `device-class'. This is likely to make some things mysterious, so it will probably need adjustment to the `describe-keymap' output. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 0:37 ` Po Lu @ 2022-04-10 5:49 ` Eli Zaretskii 2022-04-10 6:09 ` Po Lu 2022-04-10 11:41 ` Lars Ingebrigtsen 1 sibling, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 5:49 UTC (permalink / raw) To: Po Lu; +Cc: larsi, emacs-devel, monnier, rms > From: Po Lu <luangruo@yahoo.com> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, Eli Zaretskii > <eliz@gnu.org>, Richard Stallman <rms@gnu.org>, emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 08:37:31 +0800 > > Lars Ingebrigtsen <larsi@gnus.org> writes: > > > So if I could somehow say > > > > (keymap-set global-mode-map "[device footpad]-b" 'do-something) > > > > that would be ideal. > > Oh yes, that would be good as well. We could have the ability to bind > keys to individual devices. I think the usual Emacs abstraction centers on the events, not on devices that emitted them. So we should be able to have devices emit events regardless of the device type/nature/name, and then the usual Emacs machinery of binding commands to key sequence will do the rest, and will do it according to user expectations. > I could imagine a different API that didn't put the device name into the > name of the key The key doesn't have to be a device name, it should rather describe the general type of the event/functionality. For example, all the devices that have foot pedals could emit events that begin with the same pseudo-function key 'foot-pedal'. Even if the device is called something else, and even if the device is simulated by some software that takes input from the keyboard or the mouse. > And the "name of footpad" can reasonably be system dependent It shouldn't be. > since the user will be making such a customization Users cannot customize the low-level layers of event production in Emacs, that level must be coded by us. We shouldn't try aiming for this goal, because it is basically unattainable, certainly as long as we use the window-system messages as triggers for producing events eventually exposed to Lisp. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 5:49 ` Eli Zaretskii @ 2022-04-10 6:09 ` Po Lu 2022-04-10 6:44 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 6:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, emacs-devel, monnier, rms Eli Zaretskii <eliz@gnu.org> writes: > I think the usual Emacs abstraction centers on the events, not on > devices that emitted them. So we should be able to have devices emit > events regardless of the device type/nature/name, and then the usual > Emacs machinery of binding commands to key sequence will do the rest, > and will do it according to user expectations. It seems to me that abstraction was built around text terminals and legacy X windows behavior, which changed with the wide adoption of multiple instances of different kinds of input devices in X and elsewhere. > The key doesn't have to be a device name, it should rather describe > the general type of the event/functionality. For example, all the > devices that have foot pedals could emit events that begin with the > same pseudo-function key 'foot-pedal'. Even if the device is called > something else, and even if the device is simulated by some software > that takes input from the keyboard or the mouse. But we cannot determine whether a given device is a foot pedal without the help of the user. It's not one of the types of devices whose naming is well established (see the list in the doc string of `device-class'.) That fact doesn't apply to all devices, though, so why not have both options? There could be a "puck" or "touchpad" prefix for the devices that we can classify, and a way to name the devices (or assign prefixes to those devices) that we can not. > Users cannot customize the low-level layers of event production in > Emacs, that level must be coded by us. We shouldn't try aiming for > this goal, because it is basically unattainable, certainly as long as > we use the window-system messages as triggers for producing events > eventually exposed to Lisp. Then we won't be able to know what a foot pedal is, because presumably foot pedals just name itself something we cannot guess, like "USB USB Keyboard (1)" or "FlexMatrix HID Keyboard Controller", since it's pretending to be a keyboard. The user must determine that information from the relevant tools on his own system, i.e. by watching the output of the `xinput list' command. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:09 ` Po Lu @ 2022-04-10 6:44 ` Eli Zaretskii 2022-04-10 7:31 ` Po Lu 2022-04-10 11:46 ` Lars Ingebrigtsen 0 siblings, 2 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 6:44 UTC (permalink / raw) To: Po Lu; +Cc: larsi, monnier, rms, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, emacs-devel@gnu.org, monnier@iro.umontreal.ca, > rms@gnu.org > Date: Sun, 10 Apr 2022 14:09:32 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > I think the usual Emacs abstraction centers on the events, not on > > devices that emitted them. So we should be able to have devices emit > > events regardless of the device type/nature/name, and then the usual > > Emacs machinery of binding commands to key sequence will do the rest, > > and will do it according to user expectations. > > It seems to me that abstraction was built around text terminals and > legacy X windows behavior, which changed with the wide adoption of > multiple instances of different kinds of input devices in X and > elsewhere. Slapping a derogatory label on some idea or code doesn't provide any real content for intelligent and flame-free discussion of the issue. An idea doesn't magically become invalid by calling it obsolete. Let's try to avoid such "techniques" of argument as much as possible. As things stand, I still don't see why keeping our abstraction in this matter somehow doesn't fit the modern input device technologies. Please try to explain why it doesn't, by describing practical use cases where the extant abstractions and infrastructures in Emacs cannot handle some situations or features, whereas your proposed design (or some alternative design) can. So far, every example you have given can amply be handled by the existing machinery, AFAICT. > > The key doesn't have to be a device name, it should rather describe > > the general type of the event/functionality. For example, all the > > devices that have foot pedals could emit events that begin with the > > same pseudo-function key 'foot-pedal'. Even if the device is called > > something else, and even if the device is simulated by some software > > that takes input from the keyboard or the mouse. > > But we cannot determine whether a given device is a foot pedal without > the help of the user. Who is "we" in this context? What level of Emacs input processing does this "we" allude to? My point is that the level on which devices could be important is below the code which inserts the events into the main Emacs event queue from which we read events as part of our main loop. If we agree on that, we can stop arguing about making Emacs aware of the device types, because the only aspect that worries me in your design is that the device type should be exposed to, known by, and actively acted upon on much higher levels, like the commands bound to respective input events. That is something we should IMO try hard to avoid. > > Users cannot customize the low-level layers of event production in > > Emacs, that level must be coded by us. We shouldn't try aiming for > > this goal, because it is basically unattainable, certainly as long as > > we use the window-system messages as triggers for producing events > > eventually exposed to Lisp. > > Then we won't be able to know what a foot pedal is, because presumably > foot pedals just name itself something we cannot guess, like "USB USB > Keyboard (1)" or "FlexMatrix HID Keyboard Controller", since it's > pretending to be a keyboard. I don't yet understand why we _should_ know or care about that. If a device pretends to be a keyboard, but emits events that "normal" keyboards cannot, we can still process such a device by pretending those additional events are some special function keys. Like we do with several window-system messages already, and even with SIGUSR2 signal. Is anything wrong with doing the same for those devices you are talking about? If so, what exactly is wrong and why? Once again, please reply by presenting specific use cases where this paradigm cannot work well. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:44 ` Eli Zaretskii @ 2022-04-10 7:31 ` Po Lu 2022-04-10 8:28 ` Eli Zaretskii 2022-04-10 11:46 ` Lars Ingebrigtsen 1 sibling, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 7:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, monnier, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Who is "we" in this context? What level of Emacs input processing > does this "we" allude to? The input processing at the C level: everything between and including handle_one_xevent to make_lispy_event. > My point is that the level on which devices could be important is > below the code which inserts the events into the main Emacs event > queue from which we read events as part of our main loop. If we agree > on that, we can stop arguing about making Emacs aware of the device > types, because the only aspect that worries me in your design is that > the device type should be exposed to, known by, and actively acted > upon on much higher levels, like the commands bound to respective > input events. That is something we should IMO try hard to avoid. [...] > I don't yet understand why we _should_ know or care about that. If a > device pretends to be a keyboard, but emits events that "normal" > keyboards cannot, we can still process such a device by pretending > those additional events are some special function keys. Like we do > with several window-system messages already, and even with SIGUSR2 > signal. Is anything wrong with doing the same for those devices you > are talking about? If so, what exactly is wrong and why? Once again, > please reply by presenting specific use cases where this paradigm > cannot work well. They emit the same events that "normal" keyboards do. The foot pedal for example will insert "b" just the same as a "normal" keyboard will. If you open a text editor window and press the foot pedal, the letter "b" is inserted. If you turn on "xinput test-xi2" and press the foot pedal, you will probably get something like this: EVENT type 3 (KeyRelease) device: 3 (10) <----- this is the device ID of the foot pedal detail: 56 <--------- this is the keycode corresponding to the keysym "b" flags: root: 996.00/568.00 event: 136.00/94.00 buttons: modifiers: locked 0 latched 0 base 0 effective: 0 group: locked 0 latched 0 base 0 effective: 0 valuators: windows: root 0x79a event 0x4c00001 child 0x0 And if you press "b" on your keyboard, you get the same thing: EVENT type 3 (KeyRelease) device: 3 (4) <------ this is the device ID of the "normal" keyboard detail: 56 <--------- this is the keycode corresponding to the keysym "b" flags: root: 996.00/568.00 event: 136.00/94.00 buttons: modifiers: locked 0 latched 0 base 0 effective: 0 group: locked 0 latched 0 base 0 effective: 0 valuators: windows: root 0x79a event 0x4c00001 child 0x0 Since device IDs are not in any particular order or guaranteed to always be the same for each device, we use the name of the device to identify devices instead. The relationship is similar to that of file descriptors and file names. But presumably the program for which the foot pedal was designed for presents the user with a dropdown from which the device that is actually the foot pedal is chosen. That way, if an input with the character "b" is registered and comes from the foot pedal, it treats that as a press of the pedal. Otherwise, it treats it as the user pressing the character "b" on the keyboard. I hope this explanation makes things clearer. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 7:31 ` Po Lu @ 2022-04-10 8:28 ` Eli Zaretskii 2022-04-10 8:50 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 8:28 UTC (permalink / raw) To: Po Lu; +Cc: larsi, emacs-devel, monnier, rms > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, monnier@iro.umontreal.ca, rms@gnu.org, > emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 15:31:50 +0800 > > > I don't yet understand why we _should_ know or care about that. If a > > device pretends to be a keyboard, but emits events that "normal" > > keyboards cannot, we can still process such a device by pretending > > those additional events are some special function keys. Like we do > > with several window-system messages already, and even with SIGUSR2 > > signal. Is anything wrong with doing the same for those devices you > > are talking about? If so, what exactly is wrong and why? Once again, > > please reply by presenting specific use cases where this paradigm > > cannot work well. > > They emit the same events that "normal" keyboards do. The foot pedal > for example will insert "b" just the same as a "normal" keyboard will. > > If you open a text editor window and press the foot pedal, the letter > "b" is inserted. If you turn on "xinput test-xi2" and press the foot > pedal, you will probably get something like this: > > EVENT type 3 (KeyRelease) > device: 3 (10) <----- this is the device ID of the foot pedal > detail: 56 <--------- this is the keycode corresponding to the keysym "b" > flags: > root: 996.00/568.00 > event: 136.00/94.00 > buttons: > modifiers: locked 0 latched 0 base 0 effective: 0 > group: locked 0 latched 0 base 0 effective: 0 > valuators: > windows: root 0x79a event 0x4c00001 child 0x0 > > And if you press "b" on your keyboard, you get the same thing: > > EVENT type 3 (KeyRelease) > device: 3 (4) <------ this is the device ID of the "normal" keyboard > detail: 56 <--------- this is the keycode corresponding to the keysym "b" > flags: > root: 996.00/568.00 > event: 136.00/94.00 > buttons: > modifiers: locked 0 latched 0 base 0 effective: 0 > group: locked 0 latched 0 base 0 effective: 0 > valuators: > windows: root 0x79a event 0x4c00001 child 0x0 > > Since device IDs are not in any particular order or guaranteed to always > be the same for each device, we use the name of the device to identify > devices instead. The relationship is similar to that of file > descriptors and file names. My point is: Emacs should use the information about the device where it generates the Lispy event. At that point, we should generate a different Lispy event for a device whose events we want to handle differently. On the higher levels, the device information should not be necessary for processing those Lispy events. How does my point above contradict the data you show about these two devices? > But presumably the program for which the foot pedal was designed for > presents the user with a dropdown from which the device that is actually > the foot pedal is chosen. That way, if an input with the character "b" > is registered and comes from the foot pedal, it treats that as a press > of the pedal. Otherwise, it treats it as the user pressing the > character "b" on the keyboard. > > I hope this explanation makes things clearer. I hope my response above explains why I think the need to know the device info can and should stop at the level where we produce the Lispy event objects. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 8:28 ` Eli Zaretskii @ 2022-04-10 8:50 ` Po Lu 2022-04-10 9:17 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 8:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, emacs-devel, monnier, rms Eli Zaretskii <eliz@gnu.org> writes: > My point is: Emacs should use the information about the device where > it generates the Lispy event. At that point, we should generate a > different Lispy event for a device whose events we want to handle > differently. On the higher levels, the device information should not > be necessary for processing those Lispy events. > > How does my point above contradict the data you show about these two > devices? > I hope my response above explains why I think the need to know the > device info can and should stop at the level where we produce the > Lispy event objects. Hmm... how about a variable `device-function-key-alist', which maps device names and classes to the corresponding function key? The code to read events could then be changed to add such a function key when an event is received for the suitable type of device. For example, pixel-scroll-precision-mode could add ((class mouse) . coarse-mouse) to that list, which would make events coming from a mouse report themselves with the fake function key `coarse-mouse'. Then, the command to scroll with interpolation could be bound to [coarse-mouse wheel-down]. Or Lars could specify ("Name of footpad device" . footpad), and bind the appropriate commands to [footpad a], [footpad b] and so on? WDYT? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 8:50 ` Po Lu @ 2022-04-10 9:17 ` Eli Zaretskii 2022-04-10 9:25 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 9:17 UTC (permalink / raw) To: Po Lu; +Cc: larsi, monnier, rms, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, emacs-devel@gnu.org, monnier@iro.umontreal.ca, > rms@gnu.org > Date: Sun, 10 Apr 2022 16:50:40 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > My point is: Emacs should use the information about the device where > > it generates the Lispy event. At that point, we should generate a > > different Lispy event for a device whose events we want to handle > > differently. On the higher levels, the device information should not > > be necessary for processing those Lispy events. > > > > How does my point above contradict the data you show about these two > > devices? > > > I hope my response above explains why I think the need to know the > > device info can and should stop at the level where we produce the > > Lispy event objects. > > Hmm... how about a variable `device-function-key-alist', which maps > device names and classes to the corresponding function key? The low-level code which generates Lispy events can, of course, use some Lisp data structures, including user-defined data structures. > The code to read events could then be changed to add such a function key > when an event is received for the suitable type of device. > > For example, pixel-scroll-precision-mode could add ((class mouse) > . coarse-mouse) to that list, which would make events coming from a > mouse report themselves with the fake function key `coarse-mouse'. Yes, but what does the "class" part in "class mouse" signify? Why not just "mouse"? > Then, the command to scroll with interpolation could be bound to > [coarse-mouse wheel-down]. > > Or Lars could specify ("Name of footpad device" . footpad), and bind the > appropriate commands to [footpad a], [footpad b] and so on? > > WDYT? That's fine, but such a data structure, and/or the API for setting it, should be designed to be "safe", in that users cannot too easily shoot themselves in the foot by making mistakes in their data. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 9:17 ` Eli Zaretskii @ 2022-04-10 9:25 ` Po Lu 2022-04-10 11:15 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 9:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, monnier, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > The low-level code which generates Lispy events can, of course, use > some Lisp data structures, including user-defined data structures. [...] > Yes, but what does the "class" part in "class mouse" signify? Why not > just "mouse"? Sure, that would work too. I will start working on the feature along those lines. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 9:25 ` Po Lu @ 2022-04-10 11:15 ` Po Lu 2022-04-10 15:16 ` Stefan Monnier 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 11:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, monnier, rms, emacs-devel Po Lu <luangruo@yahoo.com> writes: > Eli Zaretskii <eliz@gnu.org> writes: > >> The low-level code which generates Lispy events can, of course, use >> some Lisp data structures, including user-defined data structures. > > [...] > >> Yes, but what does the "class" part in "class mouse" signify? Why not >> just "mouse"? > > Sure, that would work too. I will start working on the feature along > those lines. > > Thanks. I found out that only having an alist-of-items doesn't really work. For example, there is no sensible behavior if two packages bind different function keys to the same device or device class. So the new design I've been toying with involves two functions, `register-device-function-key' and `delete-device-function-key'. `register-device-function-key' takes a device or device class, and a recommended function key. If no function key was previously registered for that device, it associates the function key with the device. Otherwise, it returns the function key that was previously registered. Either way, it increments the reference counter of that device or device class. `delete-device-function-key' the device or device class, subtracts from its reference counter. If there are no references left, it deletes the function key from the alist. The benefit is that multiple pieces of code can reliably bind to the same device or class, but binding then becomes weird. I have to call this when pixel-scroll-precision is being activated. (define-key pixel-scroll-precision-mode-map (vector (register-device-function-key 'mouse 'coarse-mouse) 'wheel-down) #'pixel-scroll-precision-interpolate) And when the minor mode is deactivated, I have to call (delete-device-function-key 'mouse) then remove the previous binding from pixel-scroll-precision-mode-map. What do you think? Is that a reasonable design? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 11:15 ` Po Lu @ 2022-04-10 15:16 ` Stefan Monnier 2022-04-11 1:02 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-10 15:16 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, larsi, rms, emacs-devel > `register-device-function-key' takes a device or device class, and a > recommended function key. If no function key was previously registered > for that device, it associates the function key with the device. > Otherwise, it returns the function key that was previously registered. That means all users of `register-device-function-key` need to write their code under the assumption that the actual "function key" (I'd call it a "prefix event" rather than a "function key") is not the one they asked for but the one returned, which ends up being the same as dynamically-generated "function keys". It makes it rather inconvenient to use for the end user who wants to (define-key map [foot-pedal ?b] 'foo) and has to do (define-key map (vector (register-device-function-key <blabla>) ?b) 'foo) instead. I hope we will settle over time on some naming convention so that conflicting names almost never happen and `register-device-function-key` can presume the caller knows what it does, so instead of returning the previously chosen name, it doesn't return anything and overrides the old name instead. Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 15:16 ` Stefan Monnier @ 2022-04-11 1:02 ` Po Lu 0 siblings, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-11 1:02 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, larsi, rms, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > That means all users of `register-device-function-key` need to write > their code under the assumption that the actual "function key" (I'd > call it a "prefix event" rather than a "function key") is not the one > they asked for but the one returned, which ends up being the same as > dynamically-generated "function keys". > > It makes it rather inconvenient to use for the end user who wants to > > (define-key map [foot-pedal ?b] 'foo) > > and has to do > > (define-key map (vector (register-device-function-key <blabla>) ?b) 'foo) > > instead. > > I hope we will settle over time on some naming convention so that > conflicting names almost never happen and `register-device-function-key` > can presume the caller knows what it does, so instead of returning the > previously chosen name, it doesn't return anything and overrides the old > name instead. Or alternatively we could allow the function key/prefix event to be something other than a symbol: (define-key map ["Lars' foot pedal" ?b) #'foo) would make events coming from the device named "Lars' foot pedal" go to "foo", and (define-key map [[eraser] mouse-1] #'artist-erase-drag) would make events coming from an eraser run "artist-erase-drag". But I'm not sure how much work that would be. I think we will new syntax for that in `kbd', at the very least. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:44 ` Eli Zaretskii 2022-04-10 7:31 ` Po Lu @ 2022-04-10 11:46 ` Lars Ingebrigtsen 1 sibling, 0 replies; 86+ messages in thread From: Lars Ingebrigtsen @ 2022-04-10 11:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Po Lu, monnier, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> But we cannot determine whether a given device is a foot pedal without >> the help of the user. > > Who is "we" in this context? What level of Emacs input processing > does this "we" allude to? The OS doesn't know that the footpad HID device is a footpad, and we certainly don't want to maintain a list in Emacs to map device identifiers to classes -- that'd be a maintenance nightmare. But we can allow users to see the device name (in C-h k, for instance), and then allow the user to bind these events by referring to these names. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 0:37 ` Po Lu 2022-04-10 5:49 ` Eli Zaretskii @ 2022-04-10 11:41 ` Lars Ingebrigtsen 1 sibling, 0 replies; 86+ messages in thread From: Lars Ingebrigtsen @ 2022-04-10 11:41 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, Stefan Monnier, Richard Stallman (There's been a lot of posts in this thread and I haven't read them all yet, so I apologise in advance if I'm going over things that have already been covered.) Po Lu <luangruo@yahoo.com> writes: > I could imagine a different API that didn't put the device name into the > name of the key, though: there could be a system for making keymaps > "device-local", or even better device-specific bindings in a keymap: > > (keymap-set global-mode-map "b" #'do-something "name of footpad") Hm, yes, that could also make sense. I was pondering whether it would make sense to allow having events from different devices in one key sequence. For instance, having the footpad be a prefix key: (keymap-set global-mode-map "{footpad-name}-b f" #'do-something) (keymap-set global-mode-map "{footpad-name}-b g" #'do-something-else) I think that could potentially be useful and powerful, so extending the key syntax with the device name might be the way to go. > And the "name of footpad" can reasonably be system dependent, since the > user will be making such a customization, and he can look in the output > of `xinput list' (or the system's input preferences.) Yup. > We could also have a system like: > > (keymap-set global-mode-map "<wheel-down>" > #'pixel-scroll-precision-interpolate 'mouse) > > Where the last part doesn't have to be window system dependent, as long > as it's one of the values documented in `device-class'. Yes, that does seem like a handy way to deal with this use case. > This is likely to make some things mysterious, so it will probably need > adjustment to the `describe-keymap' output. Yup. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 14:04 ` Eli Zaretskii 2022-04-09 16:33 ` Stefan Monnier @ 2022-04-10 0:48 ` Po Lu 2022-04-10 6:04 ` Eli Zaretskii 1 sibling, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 0:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Richard Stallman, Lars Ingebrigtsen, monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Po Lu <luangruo@yahoo.com> >> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org >> Date: Sat, 09 Apr 2022 19:44:57 +0800 >> >> Eli Zaretskii <eliz@gnu.org> 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. > > If the events are to be interpreted as usual in some situations and > differently in others, we could have a special mode or variable to > change the produced events only when we want that to be. > > Alternatively, we could always produce special kinds of events, and > have them mapped to the same commands as the "normal" events. For > example, touchpad-button-1 could be mapped to the same command as > mouse-1 in most cases, but when we want to treat those touchpad events > specially, we could rebind them to other commands. Similar to how we > usually make shifted keys to invoke the same commands as unshifted > keys, unless there's actually a binding for the shifted key. What if the buttons we want to change are not part of a specific kind of device? We would then still have to expose the name of the device via the events, like such: "Logitec USB Optical Mouse (2)-mouse-1" "Logitec USB Optical Mouse-mouse-1" These are events from two different mice, that are otherwise identical. > That's exactly what I was afraid of: that commands will need to care > about devices. Next we will have N devices for X Windows, M different > devices for NS, Y devices for MS-Windows (some of them similar to X, > others similar to NS), etc. -- and commands will have to dispatch on > all those devices, right? Not exactly. Only commands that operate on devices by name (in which case the user will be setting the name, see my reply to Lars), or on devices that aren't explictly supported in `device-class' will have to care about the window-system specific device name. > What does it matter who personally will write the code -- it will need > to be written, and sooner or later will find its way into the core. > "Please accept this patch that adds the device I have here and would > like to be able to use with Emacs, but it is not yet in the list of > devices Emacs supports." Sounds familiar? > Yes, and then someone develops another compositor and provides names > that are identical to Wayland for different devices, or different > names for the same devices. Each team of toolkit developers might be > consistent with itself, but why should we believe they are consistent > with each other? On GNU/Linux systems the names are nearly always consistent with each other. On other window systems, that's why functions like `device-class' exist: the porting process will deal with the identification of devices. >> (cond ((eq draw-how 'artist-do-continously) >> - (artist-mouse-draw-continously ev)) >> + (artist-mouse-draw-continously ev >> + (when (eq (device-class last-event-frame >> + last-event-device) >> + 'eraser) >> + 'erase-char))) > > Do you really believe this is how Emacs's application code should be > written? We don't distinguish between different devices in file I/O, > although different filesystem definitely support different features. > Instead, where abstractions could be devised that could express > different underlying implementations, we have such abstractions in > Emacs. Example: file-extended-attributes, which allow us to > transparently support several variants of Posix-style and NTFS-style > ACLs. And where no such abstractions can be made or make sense, we > have specific features supported only by some filesystems, while > others just error out or return trivial values. But we never-ever ask > the filesystem what is its type and use that to change application > code. > > Why should input event be any different? File systems are not the best anology. We have many places where we look to see if a frame is capable of various features: displaying grayscale, colors, true color, variable-width fonts, etc. That would IMHO be a closer example. (I think shr checks `display-graphic-p' before trying to insert images, for example.) `device-class' also fits an area rather close to `file-extended-attributes', I think. > I don't need the name, I only need its number. The number is the same, the only part that is different is the name. We could make the C code number them differently, but it will need to identify that device, and that identification must be provided by the user through Lisp. > Yes, and where we produce the lispy keystroke event, we can convert > that to "я", given the low-level information about the keyboard which > emitted the key. This way, no Lisp will need to know anything about > the device. The user will at least have to make the device which produced the lispy event known to Emacs, using the language in which customizations are written, which happens to be Lisp. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 0:48 ` Po Lu @ 2022-04-10 6:04 ` Eli Zaretskii 2022-04-10 6:17 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 6:04 UTC (permalink / raw) To: Po Lu; +Cc: larsi, emacs-devel, rms, monnier > From: Po Lu <luangruo@yahoo.com> > Cc: Richard Stallman <rms@gnu.org>, Lars Ingebrigtsen <larsi@gnus.org>, > monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 08:48:48 +0800 > > > Alternatively, we could always produce special kinds of events, and > > have them mapped to the same commands as the "normal" events. For > > example, touchpad-button-1 could be mapped to the same command as > > mouse-1 in most cases, but when we want to treat those touchpad events > > specially, we could rebind them to other commands. Similar to how we > > usually make shifted keys to invoke the same commands as unshifted > > keys, unless there's actually a binding for the shifted key. > > What if the buttons we want to change are not part of a specific kind of > device? Then the events emitted by those buttons which are not part of the device will not be emitted. Or maybe I misunderstand what you have in mind when you say "the buttons we want to change are not part of the device". > We would then still have to expose the name of the device via > the events, like such: > > "Logitec USB Optical Mouse (2)-mouse-1" > "Logitec USB Optical Mouse-mouse-1" If these events are different, they should have different symbols, yes. How is this different from, say, mouse-6, which only appears when you have a mouse with 6 or more buttons, although commands can be bound to mouse-6 even if such a mouse isn't available? > These are events from two different mice, that are otherwise identical. We've been through this: the second mouse should have its buttons numbered starting from some number N to distinguish it from the first. For example, N could be 11, so the buttons are mouse-11, mouse-12, etc. > File systems are not the best anology. We have many places where we > look to see if a frame is capable of various features: displaying > grayscale, colors, true color, variable-width fonts, etc. That would > IMHO be a closer example. (I think shr checks `display-graphic-p' > before trying to insert images, for example.) Display capabilities are tested as preconditions for producing some fancy effect on display, not for dispatch on input events. If we don't test the display for some capability, trying to produce the related display effect is likely to signal an error, which is not useful. Besides, even if the display-capability analogy is actually an argument against your design: we test generic capabilities, not the names of the display terminal on which Emacs shows its frames. Applied to input events, the test for the capability is done where we produce the Lispy events: if a device doesn't have some capabilities, the corresponding events are not produced. So the test of the capabilities is in this case implicit from the Lisp POV; the Lisp level is always ready to receive all the events Emacs knows about. > > Yes, and where we produce the lispy keystroke event, we can convert > > that to "я", given the low-level information about the keyboard which > > emitted the key. This way, no Lisp will need to know anything about > > the device. > > The user will at least have to make the device which produced the lispy > event known to Emacs, using the language in which customizations are > written, which happens to be Lisp. That is a separate issue, not the one I was talking about. If there needs to be some Lisp executed, once, when the (second) keyboard is attached to Emacs, or when we switch to another type of keyboard, and if that cannot be done automatically (e.g., by Emacs listening to some special system event or polling some port), then so be it. But from that point onwards, the key input on the Lisp level doesn't need to know about the keyboard devices, perhaps not even that there's more than one keyboard. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:04 ` Eli Zaretskii @ 2022-04-10 6:17 ` Po Lu 2022-04-10 6:49 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 6:17 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, emacs-devel, rms, monnier Eli Zaretskii <eliz@gnu.org> writes: > Then the events emitted by those buttons which are not part of the > device will not be emitted. > > Or maybe I misunderstand what you have in mind when you say "the > buttons we want to change are not part of the device". I wanted to say that the buttons belong to different instances of the same kind of device (ordinary computer mice). > If these events are different, they should have different symbols, > yes. How is this different from, say, mouse-6, which only appears > when you have a mouse with 6 or more buttons, although commands can be > bound to mouse-6 even if such a mouse isn't available? These events are the same aside from the device that generated them, the only difference is that we want the same event to be treated differently based on such a fact. > We've been through this: the second mouse should have its buttons > numbered starting from some number N to distinguish it from the first. > For example, N could be 11, so the buttons are mouse-11, mouse-12, > etc. How do you decide which mouse is the "second mouse"? > Display capabilities are tested as preconditions for producing some > fancy effect on display, not for dispatch on input events. If we > don't test the display for some capability, trying to produce the > related display effect is likely to signal an error, which is not > useful. > > Besides, even if the display-capability analogy is actually an > argument against your design: we test generic capabilities, not the > names of the display terminal on which Emacs shows its frames. Hmm, then I suppose a better anology would be `overriding-terminal-local-map'. If I connect the second mouse to a different X display, I can make input from that mouse behave differently by changing the keymap for the terminal associated with that other display. Why shouldn't I be able to do that with the second mouse when it is connected to the same X display as the first mouse? Thanks. > That is a separate issue, not the one I was talking about. If there > needs to be some Lisp executed, once, when the (second) keyboard is > attached to Emacs, or when we switch to another type of keyboard, and > if that cannot be done automatically (e.g., by Emacs listening to some > special system event or polling some port), then so be it. But from > that point onwards, the key input on the Lisp level doesn't need to > know about the keyboard devices, perhaps not even that there's more > than one keyboard. I will give this some more thought. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:17 ` Po Lu @ 2022-04-10 6:49 ` Eli Zaretskii 2022-04-10 7:01 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 6:49 UTC (permalink / raw) To: Po Lu; +Cc: larsi, rms, monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, emacs-devel@gnu.org, rms@gnu.org, > monnier@iro.umontreal.ca > Date: Sun, 10 Apr 2022 14:17:46 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > We've been through this: the second mouse should have its buttons > > numbered starting from some number N to distinguish it from the first. > > For example, N could be 11, so the buttons are mouse-11, mouse-12, > > etc. > > How do you decide which mouse is the "second mouse"? Why is this detail important? Conceptually, some code that runs at Emacs startup will enumerate the mice and decide which one is which and how to name its buttons. Are you saying that this is impossible in principle? > Hmm, then I suppose a better anology would be > `overriding-terminal-local-map'. If I connect the second mouse to a > different X display, I can make input from that mouse behave differently > by changing the keymap for the terminal associated with that other > display. > > Why shouldn't I be able to do that with the second mouse when it is > connected to the same X display as the first mouse? I think the question is rather "why do you think you _have_ to be able to do the same when a second mouse is connected?" IOW, if this second mouse can be handled by existing Lisp-level infrastructure, why do we need to introduce new infrastructure, and one that leaks low-level information to Lisp on top of that? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:49 ` Eli Zaretskii @ 2022-04-10 7:01 ` Po Lu 2022-04-10 8:24 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 7:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, rms, monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Why is this detail important? Conceptually, some code that runs at > Emacs startup will enumerate the mice and decide which one is which > and how to name its buttons. Are you saying that this is impossible > in principle? This is impossible in practice. How will we know which button belongs to which mouse? What if the mice are enumerated in the wrong order? We could sort the mice by some unique identifier (read: their names), but the user will still have to know the names of the mice, and it seems to me that will be very confusing. > I think the question is rather "why do you think you _have_ to be able > to do the same when a second mouse is connected?" IOW, if this second > mouse can be handled by existing Lisp-level infrastructure, why do we > need to introduce new infrastructure, and one that leaks low-level > information to Lisp on top of that? I wasn't very convinced about the ability of the existing Lisp-level infrastructure to handle this. This information isn't also very low level anymore, when many other programs are exposing the device information to their users and plugins. Programs running in a browser, for example, can access the device name information (and also many other details that we could expose in Emacs, but I can't think of a use case for things such as mouse acceleration profiles and haptic actuators in Lisp code.) The KDE paint program Krita apparently has the ability to configure individual tablet devices to behave differently. The user is presented the device name and a set of different behaviors for that device. Being based on Qt, that device information is also available to Krita plugins. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 7:01 ` Po Lu @ 2022-04-10 8:24 ` Eli Zaretskii 2022-04-10 8:42 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 8:24 UTC (permalink / raw) To: Po Lu; +Cc: larsi, emacs-devel, rms, monnier > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, rms@gnu.org, monnier@iro.umontreal.ca, > emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 15:01:56 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Why is this detail important? Conceptually, some code that runs at > > Emacs startup will enumerate the mice and decide which one is which > > and how to name its buttons. Are you saying that this is impossible > > in principle? > > This is impossible in practice. How will we know which button belongs > to which mouse? Again, who is "we"? If this is about code that reads events from X, then it certainly knows which mouse produced the button-press, by the very nature of reading inputs from the devices. By contrast, in Lisp, buttons of different mice will appear with different symbols, like mouse2-1 or mouse-15, and there's no special need to know which button belongs to which mouse in order to process the button-press. > What if the mice are enumerated in the wrong order? Define "wrong order"? IOW, how and in which situations is the order important/significant, and on what level in Emacs should that be known? > We could sort the mice by some unique identifier (read: their names), > but the user will still have to know the names of the mice, and it seems > to me that will be very confusing. Why will the user need to know? And why is the user's need to know related to how we process the events from the mouse in Lisp? > > I think the question is rather "why do you think you _have_ to be able > > to do the same when a second mouse is connected?" IOW, if this second > > mouse can be handled by existing Lisp-level infrastructure, why do we > > need to introduce new infrastructure, and one that leaks low-level > > information to Lisp on top of that? > > I wasn't very convinced about the ability of the existing Lisp-level > infrastructure to handle this. Why not? > This information isn't also very low level anymore, when many other > programs are exposing the device information to their users and plugins. > > Programs running in a browser, for example, can access the device name > information (and also many other details that we could expose in Emacs, > but I can't think of a use case for things such as mouse acceleration > profiles and haptic actuators in Lisp code.) > > The KDE paint program Krita apparently has the ability to configure > individual tablet devices to behave differently. The user is presented > the device name and a set of different behaviors for that device. > > Being based on Qt, that device information is also available to Krita > plugins. This is orthogonal. Being able to show the user the details of connected input devices is unrelated to how the input events are processed. The information comes from the same source, of course, but the code which produces input events can (and IMO should) consult this information at a low enough level, so that interpreting the events in Lisp and binding them to commands should not need any device information to be known by the application code. The application code should only use the Lispy input event, and that event should already include all the information required for processing it. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 8:24 ` Eli Zaretskii @ 2022-04-10 8:42 ` Po Lu 2022-04-10 9:13 ` Eli Zaretskii 2022-04-10 12:44 ` Brian Cully 0 siblings, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-10 8:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, emacs-devel, rms, monnier Eli Zaretskii <eliz@gnu.org> writes: > Again, who is "we"? If this is about code that reads events from X, > then it certainly knows which mouse produced the button-press, by the > very nature of reading inputs from the devices. By contrast, in Lisp, > buttons of different mice will appear with different symbols, like > mouse2-1 or mouse-15, and there's no special need to know which button > belongs to which mouse in order to process the button-press. [...] > Define "wrong order"? IOW, how and in which situations is the order > important/significant, Because the user doesn't know what lispy button a given button on a certain mouse corresponds to. `mouse-15', for example, could be the first button of any mouse connected to the system, assuming each mouse has 14 buttons. The only way to have this system become remotely predictable is for the button assignment to follow some logical order, such as the alphabetical order of the names of the mice. For example, the mouse named "ABC" might get assigned the buttons 1 to 14, the mouse named "ABD" 15 to 29, and the mouse named "BDC" 30 to 44. But that still doesn't work very well. If another mouse named "BAA" is attached to the system, then it will get the buttons 30 to 44, and "BDC" will get buttons 45 to 59, and any bindings that were made to buttons on "BDC" will now be for the wrong mouse. > and on what level in Emacs should that be known? The code which will assign button numbers to each mouse, if it's implemented that way. > Why will the user need to know? And why is the user's need to know > related to how we process the events from the mouse in Lisp? Because the user will want the buttons from different mice to behave differently, and that will be a customization done in Lisp. > This is orthogonal. Being able to show the user the details of > connected input devices is unrelated to how the input events are > processed. The information comes from the same source, of course, but > the code which produces input events can (and IMO should) consult this > information at a low enough level, so that interpreting the events in > Lisp and binding them to commands should not need any device > information to be known by the application code. The application code > should only use the Lispy input event, and that event should already > include all the information required for processing it. Those programs don't just show the details to the user, they expose those details to application code, in the hopes that the application code will allow the code to behave appropriately, and the user to customise the behavior based on those details. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 8:42 ` Po Lu @ 2022-04-10 9:13 ` Eli Zaretskii 2022-04-10 12:51 ` Brian Cully 2022-04-10 12:44 ` Brian Cully 1 sibling, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 9:13 UTC (permalink / raw) To: Po Lu; +Cc: larsi, rms, monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: larsi@gnus.org, emacs-devel@gnu.org, rms@gnu.org, > monnier@iro.umontreal.ca > Date: Sun, 10 Apr 2022 16:42:36 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Define "wrong order"? IOW, how and in which situations is the order > > important/significant, > > Because the user doesn't know what lispy button a given button on a > certain mouse corresponds to. `mouse-15', for example, could be the > first button of any mouse connected to the system, assuming each mouse > has 14 buttons. The user doesn't care about numbering, the user only cares that when he presses a button on a certain mouse, the command that gets invoked is the command bound to that button of that mouse. Are you saying that querying the system about the connected mice will enumerate them in random order every time the system is restarted? If the order is the same, then the first time a mouse is connected, the user will see the symbols of the buttons of that mouse, and can then do the customizations accordingly. (The same initial adjustment will have to happen with your device-name idea, because the user won't know the name until the mouse is connected and Emacs tells him what is the name of the mouse.) If the order of enumerating the devices is unpredictable each time the system starts, we could have some data structure that maps device IDs to symbols of events. Such a data structure should be designed to be as safe as possible, though, so users couldn't shoot themselves in the foot by making spelling mistakes there. > > This is orthogonal. Being able to show the user the details of > > connected input devices is unrelated to how the input events are > > processed. The information comes from the same source, of course, but > > the code which produces input events can (and IMO should) consult this > > information at a low enough level, so that interpreting the events in > > Lisp and binding them to commands should not need any device > > information to be known by the application code. The application code > > should only use the Lispy input event, and that event should already > > include all the information required for processing it. > > Those programs don't just show the details to the user, they expose > those details to application code, in the hopes that the application > code will allow the code to behave appropriately, and the user to > customise the behavior based on those details. The "show the details to the user" part came from your remark: > This information isn't also very low level anymore, when many other > programs are exposing the device information to their users and plugins. > [...] > The KDE paint program Krita apparently has the ability to configure > individual tablet devices to behave differently. The user is presented > the device name and a set of different behaviors for that device. But anyway, It is okay for Emacs code to use this information provided that we do it on a low enough level. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 9:13 ` Eli Zaretskii @ 2022-04-10 12:51 ` Brian Cully 2022-04-10 13:21 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-10 12:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Po Lu, larsi, emacs-devel, rms, monnier Eli Zaretskii <eliz@gnu.org> writes: > Are you saying that querying the system about the connected mice will > enumerate them in random order every time the system is restarted? This is, in the general sense, correct. While enumeration often appears stable, that’s more due to users not often changing their system, and when they do, enumeration order is not normally a factor in how a device functions, so even if things do get re-ordered, no one tends to care. Users do also unplug and replug USB devices pretty frequently, and that changes the device address. At least on Linux, that’s a monotonically increasing counter, and old device addresses aren’t reused until you wrap the counter. And then there’s things like Bluetooth, where devices absolutely do come and go at seemingly random as low power states are entered and left, so enumeration order (such as it is) is a complete wash. I’m not sure how the device naming system in various GUIs reacts to having multiple, identical devices attached, but a conservative guess would be that they’re disambiguated by enumeration order, in which case even the device name isn’t stable in the presence of identical devices coming and going. There are, of course, stable identifiers (serial number, bluetooth device ID), but I don’t know if those are used for naming purposes. I don’t know how common a situation this is, or if anything can even be done about it, but it’s worth mentioning since it’s come up more than once in this discussion. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 12:51 ` Brian Cully @ 2022-04-10 13:21 ` Po Lu 2022-04-10 18:08 ` Brian Cully 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 13:21 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, larsi, emacs-devel, rms, monnier Brian Cully <bjc@spork.org> writes: > At least on Linux, that’s a monotonically increasing counter, and old > device addresses aren’t reused until you wrap the counter. That's not true on X. This is implementation dependent, but the X.Org server will always try to reuse a device ID that is currently available. Device ID order is what's used when you try to enumerate all devices on the X server with a QueryDevice request, so for our purposes it's "enumeration order". That only makes "device enumeration order" even more confusing. > I’m not sure how the device naming system in various GUIs reacts > to having multiple, identical devices attached, but a conservative guess > would be that they’re disambiguated by enumeration order, in which case > even the device name isn’t stable in the presence of identical devices > coming and going. That's only a last resort. On X Windows, the input driver is supposed to take care of that using serial numbers and any other information that might serve to identify a device uniquely. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 13:21 ` Po Lu @ 2022-04-10 18:08 ` Brian Cully 2022-04-11 0:58 ` Po Lu 2022-04-11 10:10 ` Lars Ingebrigtsen 0 siblings, 2 replies; 86+ messages in thread From: Brian Cully @ 2022-04-10 18:08 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Po Lu <luangruo@yahoo.com> writes: > That's not true on X. This is implementation dependent, but the X.Org > server will always try to reuse a device ID that is currently available. From what I could make out from the code, you are correct, but I was speaking of how Linux assigns USB device addresses. In any event, the index into the inputInfo.devices array isn’t useful as a stable identifier. > That's only a last resort. On X Windows, the input driver is supposed > to take care of that using serial numbers and any other information that > might serve to identify a device uniquely. So I’ve tried to verify this, and couldn’t. I trawled the Xorg xserver code, and from what I can tell, the “name” field that gets assigned to a device comes from the driver level, which, in my case at least, is libinput. I couldn’t find any place in the X server code that changes the name as passed in from the driver level (although I may have missed it, but I doubt it, as I’ll show below). Moreover, it appears as though, at least with udev and libinput, device names are *not* unique. This time, rather than trying to go through their code, I created a simple test: I updated the firmware on a USB device to have the same name, model, vid, and pid as my keyboard, but a different serial number. I think this reflects how this would work in the real world. When I plugged it in, here’s the relevant output from lsusb: ---[snip]--- Bus 001 Device 059: ID 1209:2301 Generic Keyboardio Model 01 Device Descriptor: ⋮ idProduct 0x2301 Keyboardio Model 01 bcdDevice 1.00 iManufacturer 1 Keyboardio iProduct 2 Model 01 iSerial 3 kbio01D ⋮ Bus 001 Device 083: ID 1209:2301 Generic Keyboardio Model 01 Device Descriptor: ⋮ idProduct 0x2301 Keyboardio Model 01 bcdDevice 1.00 iManufacturer 1 Keyboardio iProduct 2 Model 01 iSerial 3 8995E84D0119 ⋮ ---[snip]--- You can see the only difference is the serial number. This is reflected in the Linux device names in /dev/input/by-id: ---[snip]--- usb-Keyboardio_Model_01_8995E84D0119-if02-event-kbd -> ../event28 usb-Keyboardio_Model_01_kbio01D-if03-event-kbd -> ../event26 ---[snip]--- The serial number is clearly visible (8995... is my mock device), and you can see that they reference separate event devices in /dev/input. From there, I launched an X session to see how the name would be reported in the logs: ---[snip]--- ⋮ [2308240.861] (II) config/udev: Adding input device Keyboardio Model 01 (/dev/input/event28) [2308240.861] (**) Keyboardio Model 01: Applying InputClass "evdev keyboard catchall" [2308240.861] (**) Keyboardio Model 01: Applying InputClass "libinput keyboard catchall" [2308240.861] (**) Keyboardio Model 01: Applying InputClass "system-keyboard" [2308240.861] (II) Using input driver 'libinput' for 'Keyboardio Model 01' [2308240.861] Option "_source" "server/udev" [2308240.861] Option "name" "Keyboardio Model 01" [2308240.861] Option "path" "/dev/input/event28" [2308240.861] Option "device" "/dev/input/event28" [2308240.861] Option "major" "13" [2308240.861] Option "minor" "92" [2308240.899] (II) XINPUT: Adding extended input device "Keyboardio Model 01" (type: KEYBOARD, id 8) ⋮ [2308241.075] (II) config/udev: Adding input device Keyboardio Model 01 (/dev/input/event26) [2308241.075] (**) Keyboardio Model 01: Applying InputClass "evdev keyboard catchall" [2308241.075] (**) Keyboardio Model 01: Applying InputClass "libinput keyboard catchall" [2308241.075] (**) Keyboardio Model 01: Applying InputClass "system-keyboard" [2308241.075] (II) Using input driver 'libinput' for 'Keyboardio Model 01' [2308241.075] Option "_source" "server/udev" [2308241.075] Option "name" "Keyboardio Model 01" [2308241.075] Option "path" "/dev/input/event26" [2308241.075] Option "device" "/dev/input/event26" [2308241.075] Option "major" "13" [2308241.075] Option "minor" "90" [2308241.125] (II) XINPUT: Adding extended input device "Keyboardio Model 01" (type: KEYBOARD, id 12) ⋮ ---[snip]--- And here you can see that the two input devices have the same name (Keyboardio Model 01). In particular the last set of XINPUT lines which echo the name come from device activation in xf86input.c at line 412 of the xserver code, just before the device is enabled, and I would assume far too late in the process to adjust the name (but again, I admit I may be missing something). AFAICT this is the name that’s presented to toolkit layers. There may be a place where it’s modified by X, but, again, I couldn’t find it. So, the tl;dr here is that I flashed a USB device to look like one of my existing ones, and from everything I can tell, they have the same name, at least coming out of X. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 18:08 ` Brian Cully @ 2022-04-11 0:58 ` Po Lu 2022-04-11 1:08 ` Brian Cully 2022-04-11 10:10 ` Lars Ingebrigtsen 1 sibling, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-11 0:58 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Brian Cully <bjc@spork.org> writes: > So I’ve tried to verify this, and couldn’t. I trawled the Xorg > xserver code, and from what I can tell, the “name” field that gets > assigned to a device comes from the driver level, which, in my case at > least, is libinput. I couldn’t find any place in the X server code that > changes the name as passed in from the driver level (although I may have > missed it, but I doubt it, as I’ll show below). As I said, the input driver is supposed to give it a unique name. That may be the libinput X driver, the Synaptics driver, the evdev driver, or any number of other drivers. > Moreover, it appears as though, at least with udev and libinput, > device names are *not* unique. This time, rather than trying to go > through their code, I created a simple test: I updated the firmware on a > USB device to have the same name, model, vid, and pid as my keyboard, > but a different serial number. I think this reflects how this would work > in the real world. You likely missed something, or the input driver doesn't know enough about that specific kind of device to create a unique enough name. I would consider that an error in the user's configuration. As a last resort, he could always configure it manually in the X server configuration instead of relying on hotplug. It's possible, though I forgot exactly how. > And here you can see that the two input devices have the same > name (Keyboardio Model 01). In particular the last set of XINPUT lines > which echo the name come from device activation in xf86input.c at line > 412 of the xserver code, just before the device is enabled, and I would > assume far too late in the process to adjust the name (but again, I > admit I may be missing something). When I insert two actual mice of the same kind (I did not flash anything), I get two different names. So there's something wrong with the input driver, or your device isn't providing the information necessary to disambiguate the two. > AFAICT this is the name that’s presented to > toolkit layers. There may be a place where it’s modified by X, but, > again, I couldn’t find it. As I've been saying for a long time, it's modified by the input drivers, which should behave correctly. I don't expect users to flash custom firmware onto their mice specifically for them to look exactly like another device. > So, the tl;dr here is that I flashed a USB device to look like > one of my existing ones, and from everything I can tell, they have the > same name, at least coming out of X. I tried a real pair of the same mice and got different names, and there isn't any more disambugating information supplied to applications (they all rely on names being unique and as persistent as possible), so this is not a problem in practice. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 0:58 ` Po Lu @ 2022-04-11 1:08 ` Brian Cully 2022-04-11 2:00 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-11 1:08 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, larsi, rms, monnier Po Lu <luangruo@yahoo.com> writes: > You likely missed something, or the input driver doesn't know enough > about that specific kind of device to create a unique enough name. That would be because the only way that USB has to disambiguate otherwise identical devices is by serial number. You can verify this yourself, if you like, by looking at the output of ‘lsusb -v’. I have demonstrated that libinput does not use that information to name devices and has no apparent problem re-using the same name across multiple devices. > When I insert two actual mice of the same kind (I did not flash > anything), I get two different names. Is libinput being used for your mice? I suspect that the discrepancy may arrive from different driver usage. > As I've been saying for a long time, it's modified by the input drivers, > which should behave correctly. I don't expect users to flash custom > firmware onto their mice specifically for them to look exactly like > another device. That I flashed firmware is irrelevant. I took care to allow them separate serial numbers, as they would have separate serial numbers from the factory, but otherwise identical identifiers. Do you think I missed something in my test? > I tried a real pair of the same mice and got different names, and there > isn't any more disambugating information supplied to applications (they > all rely on names being unique and as persistent as possible), so this > is not a problem in practice. So, I’d originally flashed my microcontroller because I thought it would be the easiest way to test things, and while I do have duplicate devices in my home, they’re Steam Controllers and I didn’t think it worth digging them out of storage for this. However, in the interest of using “real” devices, here’s the output of ‘libinput list-devices’ with them plugged in. ---[snip]--- Device: Valve Software Steam Controller Kernel: /dev/input/event30 Group: 4 Seat: seat0, default Capabilities: keyboard pointer ⋮ Device: Valve Software Steam Controller Kernel: /dev/input/event29 Group: 5 Seat: seat0, default Capabilities: keyboard pointer ---[snip]--- They work in X just fine. Here are the logs about their mouse functionality: ---[snip]--- [2335445.180] (II) XINPUT: Adding extended input device "Valve Software Steam Controller" (type: MOUSE, id 26) ⋮ [2335518.146] (II) XINPUT: Adding extended input device "Valve Software Steam Controller" (type: MOUSE, id 28) ---[snip]--- The names are, unsurprisingly, identical. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 1:08 ` Brian Cully @ 2022-04-11 2:00 ` Po Lu 2022-04-11 2:03 ` Po Lu 2022-04-11 2:21 ` Brian Cully 0 siblings, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-11 2:00 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, larsi, rms, monnier Brian Cully <bjc@spork.org> writes: > That would be because the only way that USB has to disambiguate > otherwise identical devices is by serial number. You can verify this > yourself, if you like, by looking at the output of ‘lsusb -v’. I have > demonstrated that libinput does not use that information to name devices > and has no apparent problem re-using the same name across multiple > devices. libinput is libinput. It is a driver for the X server, but it is otherwise completely unrelated to the X input extension, which can only operate correctly if each name uniquely identifies a device. > Is libinput being used for your mice? I suspect that the > discrepancy may arrive from different driver usage. libinput is the device driver being used, yes. > So, I’d originally flashed my microcontroller because I thought > it would be the easiest way to test things, and while I do have > duplicate devices in my home, they’re Steam Controllers and I didn’t > think it worth digging them out of storage for this. However, in the > interest of using “real” devices, here’s the output of ‘libinput > list-devices’ with them plugged in. > > ---[snip]--- > Device: Valve Software Steam Controller > Kernel: /dev/input/event30 > Group: 4 > Seat: seat0, default > Capabilities: keyboard pointer > ⋮ > Device: Valve Software Steam Controller > Kernel: /dev/input/event29 > Group: 5 > Seat: seat0, default > Capabilities: keyboard pointer > ---[snip]--- > > They work in X just fine. Then either the names are different, or the devices behave identically in every way, and nobody has yet had a reason to treat the devices differently. If the second "Valve Software Steam Controller" was a foot pedal, I'm certain it would not be working correctly in software designed for that foot pedal. Anyway, that "they work fine in X" proves this is not a problem in practice, so we will wait until someone actually complains in real word usage. > Here are the logs about their mouse functionality: Did you try asking for the device name using the xinput tool? What does it say? Also, what happens if you run `xinput list-props "Valve Software Steam Controller"'? Can you show the output? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 2:00 ` Po Lu @ 2022-04-11 2:03 ` Po Lu 2022-04-11 2:21 ` Brian Cully 1 sibling, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-11 2:03 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, larsi, rms, monnier Po Lu <luangruo@yahoo.com> writes: > libinput is libinput. It is a driver for the X server, but it is ^^ This should have read "can be used as", not "is". ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 2:00 ` Po Lu 2022-04-11 2:03 ` Po Lu @ 2022-04-11 2:21 ` Brian Cully 2022-04-11 3:12 ` Po Lu 1 sibling, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-11 2:21 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Po Lu <luangruo@yahoo.com> writes: > libinput is libinput. It is a driver for the X server, but it is > otherwise completely unrelated to the X input extension, which can only > operate correctly if each name uniquely identifies a device. I think I must be misunderstanding something, because I have devices that are identically named within X and also operate correctly. That seems to me to run counter to “can only operate correctly if each name uniquely identifies a device”. I bring up USB because libinput has to get its information from somewhere, and in the cases of the devices I have that libinput publishes, that is USB. I could potentially dig out some bluetooth ones, but that seems uneccesary. > libinput is the device driver being used, yes. I am at a loss, then. I do not know why libinput would choose to give your devices unique names but not mine. Does the “Device” line of ‘libinput list-devices’ also show unique names? > Then either the names are different, or the devices behave identically > in every way, and nobody has yet had a reason to treat the devices > differently. If the second "Valve Software Steam Controller" was a foot > pedal, I'm certain it would not be working correctly in software > designed for that foot pedal. This thread began with a claim that devices were uniquely named, and thus could be disambiguated within Emacs to provide different functionality based on their names. If I wanted to treat the pointer on one Steam Controller as a vertical scroll, and on the other a horizontal scroll, I do not currently see how I could do that. > Anyway, that "they work fine in X" proves this is not a problem in > practice, so we will wait until someone actually complains in real word > usage. What this shows to me is that precious little in the X stack actually cares about device names. For the most part, they are irrelevant, as devices are self-describing in terms of capabilities. That it is useful for a user to modify the way a device behaves in the context of Emacs I take at face value, and I also grant that the name is one possible, though hopefully as is clear by now, not fool-proof way to do that. I do not actually believe this to be a huge problem. Outside of hardware hackers I don’t think I know anyone who attaches two identical devices. Maybe musicians? I’m sure they exist, but it’s not a lot of people. But I also don’t believe this is a problem Emacs can solve using only the device name, for reasons already stated. > Did you try asking for the device name using the xinput tool? What does > it say? I’m not very familiar with that tool, but here is the relevant output of ‘xinput list’: ---[snip]--- ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ Valve Software Steam Controller id=9 [slave pointer (2)] ⎜ ↳ Valve Software Steam Controller id=10 [slave pointer (2)] ⋮ ⎣ Virtual core keyboard id=3 [master keyboard (2)] ⋮ ↳ Valve Software Steam Controller id=24 [slave keyboard (3)] ↳ Valve Software Steam Controller id=25 [slave keyboard (3)] ---[snip]--- > Also, what happens if you run `xinput list-props "Valve Software Steam > Controller"'? Can you show the output? Gladly (sorry about the length, but I’m not sure what information you might be looking for): ---[snip]--- $ xinput list-props 'Valve Software Steam Controller' Warning: There are multiple devices matching 'Valve Software Steam Controller'. To ensure the correct one is selected, please use the device ID, or prefix the device name with 'pointer:' or 'keyboard:' as appropriate. unable to find device Valve Software Steam Controller $ xinput list-props 24 Device 'Valve Software Steam Controller': Device Enabled (154): 1 Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Send Events Modes Available (275): 1, 0 libinput Send Events Mode Enabled (276): 0, 0 libinput Send Events Mode Enabled Default (277): 0, 0 Device Node (278): "/dev/input/event30" Device Product ID (279): 10462, 4418 $ xinput list-props 25 Device 'Valve Software Steam Controller': Device Enabled (154): 1 Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Send Events Modes Available (275): 1, 0 libinput Send Events Mode Enabled (276): 0, 0 libinput Send Events Mode Enabled Default (277): 0, 0 Device Node (278): "/dev/input/event29" Device Product ID (279): 10462, 4418 $ xinput list-props 9 Device 'Valve Software Steam Controller': Device Enabled (154): 1 Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Natural Scrolling Enabled (290): 0 libinput Natural Scrolling Enabled Default (291): 0 libinput Scroll Methods Available (292): 0, 0, 1 libinput Scroll Method Enabled (293): 0, 0, 0 libinput Scroll Method Enabled Default (294): 0, 0, 0 libinput Button Scrolling Button (295): 2 libinput Button Scrolling Button Default (296): 2 libinput Button Scrolling Button Lock Enabled (297): 0 libinput Button Scrolling Button Lock Enabled Default (298): 0 libinput Middle Emulation Enabled (299): 0 libinput Middle Emulation Enabled Default (300): 0 libinput Accel Speed (301): -0.200000 libinput Accel Speed Default (302): 0.000000 libinput Accel Profiles Available (303): 1, 1 libinput Accel Profile Enabled (304): 0, 1 libinput Accel Profile Enabled Default (305): 1, 0 libinput Left Handed Enabled (306): 0 libinput Left Handed Enabled Default (307): 0 libinput Send Events Modes Available (275): 1, 0 libinput Send Events Mode Enabled (276): 0, 0 libinput Send Events Mode Enabled Default (277): 0, 0 Device Node (278): "/dev/input/event30" Device Product ID (279): 10462, 4418 libinput Drag Lock Buttons (308): <no items> libinput Horizontal Scroll Enabled (309): 1 libinput Scrolling Pixel Distance (310): 15 libinput Scrolling Pixel Distance Default (311): 15 libinput High Resolution Wheel Scroll Enabled (312): 1 $ xinput list-props 10 Device 'Valve Software Steam Controller': Device Enabled (154): 1 Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Natural Scrolling Enabled (290): 0 libinput Natural Scrolling Enabled Default (291): 0 libinput Scroll Methods Available (292): 0, 0, 1 libinput Scroll Method Enabled (293): 0, 0, 0 libinput Scroll Method Enabled Default (294): 0, 0, 0 libinput Button Scrolling Button (295): 2 libinput Button Scrolling Button Default (296): 2 libinput Button Scrolling Button Lock Enabled (297): 0 libinput Button Scrolling Button Lock Enabled Default (298): 0 libinput Middle Emulation Enabled (299): 0 libinput Middle Emulation Enabled Default (300): 0 libinput Accel Speed (301): -0.200000 libinput Accel Speed Default (302): 0.000000 libinput Accel Profiles Available (303): 1, 1 libinput Accel Profile Enabled (304): 0, 1 libinput Accel Profile Enabled Default (305): 1, 0 libinput Left Handed Enabled (306): 0 libinput Left Handed Enabled Default (307): 0 libinput Send Events Modes Available (275): 1, 0 libinput Send Events Mode Enabled (276): 0, 0 libinput Send Events Mode Enabled Default (277): 0, 0 Device Node (278): "/dev/input/event29" Device Product ID (279): 10462, 4418 libinput Drag Lock Buttons (308): <no items> libinput Horizontal Scroll Enabled (309): 1 libinput Scrolling Pixel Distance (310): 15 libinput Scrolling Pixel Distance Default (311): 15 libinput High Resolution Wheel Scroll Enabled (312): 1 ---[snip]--- -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 2:21 ` Brian Cully @ 2022-04-11 3:12 ` Po Lu 2022-04-11 4:11 ` Brian Cully 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-11 3:12 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Brian Cully <bjc@spork.org> writes: > I think I must be misunderstanding something, because I have > devices that are identically named within X and also operate > correctly. That seems to me to run counter to “can only operate > correctly if each name uniquely identifies a device”. That means it's not operating correctly because of a problem in the input driver. It might work, but it's not correct behavior. > I bring up USB because libinput has to get its information from > somewhere, and in the cases of the devices I have that libinput > publishes, that is USB. I could potentially dig out some bluetooth ones, > but that seems uneccesary. libinput in most cases gets its information from evdev. What the kernel driver exposing the evdev device does is outside its scope. > I am at a loss, then. I do not know why libinput would choose to > give your devices unique names but not mine. Does the “Device” line of > ‘libinput list-devices’ also show unique names? It does not. > This thread began with a claim that devices were uniquely named, > and thus could be disambiguated within Emacs to provide different > functionality based on their names. If I wanted to treat the pointer on > one Steam Controller as a vertical scroll, and on the other a horizontal > scroll, I do not currently see how I could do that. That's a bug in the input driver. If the input driver works correctly, then that will be possible. If not (like in your case), you lose, sorry, but there is no way to fix that problem. IOW, the devices are uniquely named, but from the point of view of Emacs the input driver is reporting two devices as a single device. > What this shows to me is that precious little in the X stack > actually cares about device names. For the most part, they are > irrelevant, as devices are self-describing in terms of capabilities. They are not. If you want to configure a program to behave differently based on the individual steam controllers, that will not work, because to them the X server is reporting those two controllers as the same device. And as I already explained, devices are nowhere close to self-describing in their capabilities. Joysticks send motion events, foot pedals send keyboard events, and so on and so forth. > That it is useful for a user to modify the way a device behaves > in the context of Emacs I take at face value, and I also grant that the > name is one possible, though hopefully as is clear by now, not > fool-proof way to do that. It's the only reliable way to do that. What else would you suggest? (Reliable doesn't have to mean it has to work when the input driver is buggy. It just happens to be the only way to single out an input device, and because of that, it's what programs use.) > I do not actually believe this to be a huge problem. Outside of > hardware hackers I don’t think I know anyone who attaches two identical > devices. Maybe musicians? I’m sure they exist, but it’s not a lot of > people. But I also don’t believe this is a problem Emacs can solve using > only the device name, for reasons already stated. If the input driver's naming is broken, they can configure the devices statically in their X server configuration files. "Only the device name" is enough with a correctly functioning input driver, and if xf86-input-libinput is not, then too bad, the users lose. (Or have to mess with their xorg.conf.d.) > prefix the device name with 'pointer:' or 'keyboard:' as appropriate. This message sort of demonstrates my point. It is OK for there to be a pointer and a keyboard extension device with the same name, because they are the same device sending both motion and keyboard events. But it is not correct for there to be more than one physical device with the same name. > $ xinput list-props 24 > Device 'Valve Software Steam Controller': > Device Enabled (154): 1 > Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 > libinput Send Events Modes Available (275): 1, 0 > libinput Send Events Mode Enabled (276): 0, 0 > libinput Send Events Mode Enabled Default (277): 0, 0 > Device Node (278): "/dev/input/event30" > Device Product ID (279): 10462, 4418 > $ xinput list-props 9 > Device 'Valve Software Steam Controller': > Device Enabled (154): 1 > Coordinate Transformation Matrix (156): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 > libinput Natural Scrolling Enabled (290): 0 > libinput Natural Scrolling Enabled Default (291): 0 > libinput Scroll Methods Available (292): 0, 0, 1 > libinput Scroll Method Enabled (293): 0, 0, 0 > libinput Scroll Method Enabled Default (294): 0, 0, 0 > libinput Button Scrolling Button (295): 2 > libinput Button Scrolling Button Default (296): 2 > libinput Button Scrolling Button Lock Enabled (297): 0 > libinput Button Scrolling Button Lock Enabled Default (298): 0 > libinput Middle Emulation Enabled (299): 0 > libinput Middle Emulation Enabled Default (300): 0 > libinput Accel Speed (301): -0.200000 > libinput Accel Speed Default (302): 0.000000 > libinput Accel Profiles Available (303): 1, 1 > libinput Accel Profile Enabled (304): 0, 1 > libinput Accel Profile Enabled Default (305): 1, 0 > libinput Left Handed Enabled (306): 0 > libinput Left Handed Enabled Default (307): 0 > libinput Send Events Modes Available (275): 1, 0 > libinput Send Events Mode Enabled (276): 0, 0 > libinput Send Events Mode Enabled Default (277): 0, 0 > Device Node (278): "/dev/input/event30" > Device Product ID (279): 10462, 4418 > libinput Drag Lock Buttons (308): <no items> > libinput Horizontal Scroll Enabled (309): 1 > libinput Scrolling Pixel Distance (310): 15 > libinput Scrolling Pixel Distance Default (311): 15 > libinput High Resolution Wheel Scroll Enabled (312): 1 One of those is a keyboard, the other is a pointer. They are not ambiguous, since they are extension devices corresponding to the same "real" device. The other pair (25, 10) is a bug, and from the POV of programs is the same controller as the the first pair. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 3:12 ` Po Lu @ 2022-04-11 4:11 ` Brian Cully 2022-04-11 5:20 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-11 4:11 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, rms, larsi, monnier, emacs-devel Po Lu <luangruo@yahoo.com> writes: > libinput in most cases gets its information from evdev. What the kernel > driver exposing the evdev device does is outside its scope. From what I can tell it seems like in all cases it gets its information from evdev, which in turn gets its information from an ioctl call. >> I am at a loss, then. I do not know why libinput would choose to >> give your devices unique names but not mine. Does the “Device” line of >> ‘libinput list-devices’ also show unique names? > > It does not. I do not understand why libinput would show one device name, yet X shows another for you. From what I can tell, there is a direct chain of unmodified names that goes all the way from the kernel, through evdev, through libinput, and up to X. > That's a bug in the input driver. If the input driver works correctly, > then that will be possible. If not (like in your case), you lose, > sorry, but there is no way to fix that problem. IOW, the devices are > uniquely named, but from the point of view of Emacs the input driver is > reporting two devices as a single device. My input driver is bog standard. Why do you claim there is a bug? Is it documented somewhere that the kernel, evdev, or libinput will present unique names? I have not found such documentation, and I have found a number of code paths that make no effort at all at making names unique. > And as I already explained, devices are nowhere close to self-describing > in their capabilities. Joysticks send motion events, foot pedals send > keyboard events, and so on and so forth. We may have different definitions of “self describing” happening here. Joysticks and Gamepads have explicit usage IDs in the Generic Desktop Page of the HID Usage Tables. While they present relative motion like other devices, they are tagged by the USB in order to differentiate them. Most of the commonly used devices have usage table definitions which adequately describe how they function. But of course there is a limit to what is even possible to describe automatically without user intervention. Foot pedals are a good example; they tend to have unique uses based on their users, and as a result their users are expected to configure them. It is reasonable for Emacs to do this. However, what happens when you plug in two pedals of the same make and model and they have the same name? You say this is a bug, and that I lose, but I need to see *why* that’s a bug. In the mean time, there are other identifiers I might be able to use other than the name, like the serial number, or Bluetooth device ID, why should those be off limits to my ability to configure them in Emacs? I think names can be useful, but names are not, by themselves, an adequate solution. I can, seemingly without effort, create name collisions on a standard Manjaro install. At this point I’m pretty certain I could do it on any popular Linux distribution. > It's the only reliable way to do that. What else would you suggest? I would suggest, if we go this route, that the device comes with more information than a name, or can at least be probed, so that I can determine which information to use, such as the serial number. >> prefix the device name with 'pointer:' or 'keyboard:' as appropriate. > > This message sort of demonstrates my point. It is OK for there to be a > pointer and a keyboard extension device with the same name, because they > are the same device sending both motion and keyboard events. But it is > not correct for there to be more than one physical device with the same > name. My point is that it is not just okay to have a device named the same thing with multiple functions (indeed, that is how a tremendous number of devices work), but that it is also okay for them to have the same name with the same functions, because the name is meant for human consumption and not computer algorithms. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 4:11 ` Brian Cully @ 2022-04-11 5:20 ` Po Lu 2022-04-11 11:33 ` Brian Cully 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-11 5:20 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, rms, larsi, monnier, emacs-devel Brian Cully <bjc@spork.org> writes: > I do not understand why libinput would show one device name, yet > X shows another for you. From what I can tell, there is a direct chain > of unmodified names that goes all the way from the kernel, through > evdev, through libinput, and up to X. Well, no. > My input driver is bog standard. Why do you claim there is a > bug? Is it documented somewhere that the kernel, evdev, or libinput will > present unique names? I have not found such documentation, and I have > found a number of code paths that make no effort at all at making names > unique. "Input driver" is not at all related to the Linux kernel, evdev, or libinput. It means a driver for the X server. The X server must produce unique names for each device. That task is delegated to the device-dependent layer (in this case, xf86-input-libinput.) The input extension has provided unique names for each device since its adoption by most X vendors in the early 1990s, before Linux, evdev, HID devices, Bluetooth and Steam controllers even existed. It has also never provided any more information such as serial numbers and "bluetooth IDs", since they are not reasonably portable, and did not even exist when the input extension was first designed. There was once a separately specified "input class", but that died alongside the X Consortium, and is no longer present in version 2 of the input extension. Hotplugging is also a new feature on X. Before that, people configured input devices manually, and the X server did not allow you to have multiple devices with the same name. Also, X to this day runs on many kernels other than Linux. Each with their own supported devices, each with their own mechanisms for retrieving information from devices. This is why it does not expose any Linux, or Solaris, or MS Windows, or VMS specific concepts related to "input device" anywhere. > We may have different definitions of “self describing” happening > here. Joysticks and Gamepads have explicit usage IDs in the Generic > Desktop Page of the HID Usage Tables. While they present relative motion > like other devices, they are tagged by the USB in order to differentiate > them. Please tell me how Emacs can obtain the "explicit usage ID" from the "Generic Desktop Page" of the "HID Usage Tables" from the X server, which does not expose any USB or other low-level device information to Emacs and other clients. > Most of the commonly used devices have usage table definitions > which adequately describe how they function. But of course there is a > limit to what is even possible to describe automatically without user > intervention. Foot pedals are a good example; they tend to have unique > uses based on their users, and as a result their users are expected to > configure them. It is reasonable for Emacs to do this. > > However, what happens when you plug in two pedals of the same > make and model and they have the same name? You say this is a bug, and > that I lose, but I need to see *why* that’s a bug. In the mean time, > there are other identifiers I might be able to use other than the name, > like the serial number, or Bluetooth device ID, why should those be off > limits to my ability to configure them in Emacs? Because the X server does not provide the serial number, Bluetooth device ID, it only provides the name, which has always been unique to each device. > I would suggest, if we go this route, that the device comes with > more information than a name, or can at least be probed, so that I can > determine which information to use, such as the serial number. The X server does not provide any of that information. > My point is that it is not just okay to have a device named the > same thing with multiple functions (indeed, that is how a tremendous > number of devices work), but that it is also okay for them to have the > same name with the same functions, because the name is meant for human > consumption and not computer algorithms. The name is meant for the consumption of any program which needs a way to permanently refer to a device. It always has, it always will be, and if there is a buggy input driver, X clients and users lose. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 5:20 ` Po Lu @ 2022-04-11 11:33 ` Brian Cully 2022-04-11 14:09 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-11 11:33 UTC (permalink / raw) To: Po Lu; +Cc: larsi, Eli Zaretskii, emacs-devel, rms, monnier Po Lu <luangruo@yahoo.com> writes: > "Input driver" is not at all related to the Linux kernel, evdev, or > libinput. It means a driver for the X server. In my context, and the context of many other people, “Input driver” is very related to the Linux kernel, evdev, and libinput. Because that is exactly the stack that is in use for delivering input information to X. I do not think it is useful, in this discussion, to discuss input drivers in the abstract, because no one actually uses an abstract input driver. If there are a substantial number of people with actual driver stacks that don’t match your expectations, then that cannot be handwaved with “bug”, particularly when there’s no evidence that the behavior exhibited is contrary to any specifications. > The input extension has provided unique names for each device since its > adoption by most X vendors in the early 1990s, before Linux, evdev, HID > devices, Bluetooth and Steam controllers even existed. It has also > never provided any more information such as serial numbers and > "bluetooth IDs", since they are not reasonably portable, and did not > even exist when the input extension was first designed. There was once > a separately specified "input class", but that died alongside the X > Consortium, and is no longer present in version 2 of the input > extension. I can only speak to the behavior I am witnessing today, because it has only been the last few days since I started looking into the issue. Whether or not X had a particular behavior in the 90s does not, in-and-of itself, mean it will continue to have that behavior today. The computing landscape is immensely different, as you point out. One major difference is that most input devices in the mid 90s, and before, were not self-describing, but expected to be configured by users. In that context, especially because users were also responsible for *naming* devices, using a name makes more sense. But that context is long gone for most of us. Even embedded host devices query USB devices for their capabilities. > Please tell me how Emacs can obtain the "explicit usage ID" from the > "Generic Desktop Page" of the "HID Usage Tables" from the X server, > which does not expose any USB or other low-level device information to > Emacs and other clients. libinput classifies devices based on these tables (by way of evdev, by way of the kernel). X uses them for simple classification. But X also doesn’t apparently expose joysticks, either (my Steam Controller has a joystick interface that failed to show up in ‘xinput list’). Does that mean Emacs shouldn’t use them? If Emacs is required to use only the information delivered by way of X, then there are large swathes of devices it cannot use. I am aware of the joystick driver, but have not used it. From what I can tell it converts joystick movement into mouse movement, which explicitly defeats using it properly as a joystick by applications. That’s why it’s not included by default in most Linux distributions. > Because the X server does not provide the serial number, Bluetooth > device ID, it only provides the name, which has always been unique to > each device. It does have the event device path, however, which can be used to query capabilities. > The name is meant for the consumption of any program which needs a way > to permanently refer to a device. It always has, it always will be, and > if there is a buggy input driver, X clients and users lose. I contend that my input driver stack, from the kernel, through evdev, through libinput, and into X is not buggy, but in fact, normative. Yet this stack will, trivially, produce identical device names for separate physical devices. Furthermore, I contend that this is completely acceptable. That nothing in this stack has any problem with this situation, and that nothing, even X itself, has any problem disambiguating events from any device, no matter how they are named. If there are applications that use device names under the expectation that they be unique, then I contend that is a bug in those applications, because there is nothing I have found, in spite of a great deal of searching, that appears to make this claim, and you have also provided none when directly asked. There is no code that I can find that would accommodate this feature. And, furthermore, there is no reason for this feature to exist in the modern era -- and I define modern pretty loosely here, X has had USB support longer than it hasn’t, at this point in time. Devices are designed to describe their abilities with enough clarity that they can be used, as expected, with no user intervention what-so-ever, with no care at all given to any possible identifiers, including, but not limited to: model, manufacturer, VID, PID, device ID, serial number, and name (barring, of course, vendor-specific extensions). This modern sensibility is reflected in the driver stack. A user is, of course, allowed to customize their device based on any feature of it they want; it’s their computer after all. They can even use the output of /dev/random if they so desire. But it is *not* a feature of X that they may expect the device name to be a unique identifier, and it should not be communicated to them as such. I have done all I can to show that X does not guarantee unique device names, from abstract rational argument to trawling the actual code in use, to creating custom devices, to finding duplicate, mass-manufactured devices. And while absence of evidence is not evidence of absence, I believe there is enough weight behind my research to show my claim to be correct. The onus is on you to prove the opposite, which is far easier, in that it is at least logically possible: that X has a guarantee of unique device names. Please show me where that claim is made in official documentation, and I will cede that the current behavior is a bug. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 11:33 ` Brian Cully @ 2022-04-11 14:09 ` Po Lu 2022-04-11 16:26 ` Brian Cully 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-11 14:09 UTC (permalink / raw) To: Brian Cully; +Cc: larsi, Eli Zaretskii, emacs-devel, rms, monnier Brian Cully <bjc@spork.org> writes: > In my context, and the context of many other people, “Input > driver” is very related to the Linux kernel, evdev, and > libinput. Because that is exactly the stack that is in use for > delivering input information to X. I do not think it is useful, in this > discussion, to discuss input drivers in the abstract, because no one > actually uses an abstract input driver. If there are a substantial > number of people with actual driver stacks that don’t match your > expectations, then that cannot be handwaved with “bug”, particularly > when there’s no evidence that the behavior exhibited is contrary to any > specifications. But I am not interested in what the Linux kernel, evdev and libinput expose. Emacs cannot use their information when running under X. > I can only speak to the behavior I am witnessing today, because > it has only been the last few days since I started looking into the > issue. Whether or not X had a particular behavior in the 90s does not, > in-and-of itself, mean it will continue to have that behavior today. The > computing landscape is immensely different, as you point out. One major > difference is that most input devices in the mid 90s, and before, were > not self-describing, but expected to be configured by users. The protocol does not by design allow for there to be multiple devices of the same use (master pointer, master keyboard, slave pointer, slave keyboard, floating slave) with the same name. The behavior you are witnessing deviates from the established behavior of the X input extension, that you try to justify it with "that's what Linux does" is irrelevant. > libinput classifies devices based on these tables (by way of > evdev, by way of the kernel). X uses them for simple classification. But > X also doesn’t apparently expose joysticks, either (my Steam Controller > has a joystick interface that failed to show up in ‘xinput list’). Does > that mean Emacs shouldn’t use them? If Emacs is required to use only the > information delivered by way of X, then there are large swathes of > devices it cannot use. Your Steam Controller's joystick is exposed as extra valuators inside the pointer device. The motion is sent as normal Motion extension events with those valuators changed by the X server. Emacs knows nothing about the special-ness of those valuators, unless it knows its name. And FTR, Emacs is required to only use information delivered by X, for the simple fact that there is no information delivered by anything else. > It does have the event device path, however, which can be used > to query capabilities. The device path is only exposed by the libinput (or evdev) drivers through driver-specific device properties. Trying to use those properties is IMNSHO suicidial: they change at random and are not guaranteed to be present everywhere. And what if Emacs is connected to a remote X server, or the device information cannot be queried due to a lack of permissions to open that device file, or the device information is simply incorrect? If we are going to use those properties, we might as well drop X Windows support altogether, and make Emacs use libinput directly for input, because what you are proposing defeats the entire point of X's client-server architecture. > I contend that my input driver stack, from the kernel, through > evdev, through libinput, and into X is not buggy, but in fact, > normative. Yet this stack will, trivially, produce identical device > names for separate physical devices. Then this stack is buggy. I don't care what the Linux kernel does, what evdev does, etc. The X input extension is supposed to produce unique names for each device, that it does not do so points to a bug somewhere in the stack. > Furthermore, I contend that this is completely acceptable. That > nothing in this stack has any problem with this situation, and that > nothing, even X itself, has any problem disambiguating events from any > device, no matter how they are named. Nonsense. I will not try to argue this with you further, since you simply don't understand or have never worked with anything other than a GNU/Linux system running the latest release of the X.Org server. > If there are applications that use device names under the > expectation that they be unique, then I contend that is a bug in those > applications, because there is nothing I have found, in spite of a great > deal of searching, that appears to make this claim, and you have also > provided none when directly asked. I already told you: the X server(s) never did let you configure devices manually, in your XF86Config file, with the same names. And my input devices show up with different names. > And, furthermore, there is no reason for this feature to exist > in the modern era -- and I define modern pretty loosely here, X has had > USB support longer than it hasn’t, at this point in time. X does not support USB at all, or PS/2, or ADB, or any other hardware interface directly. It is a network protocol that abstracts above all of these details. > Devices are designed to describe their abilities with enough > clarity that they can be used, as expected, with no user intervention > what-so-ever, with no care at all given to any possible identifiers, > including, but not limited to: model, manufacturer, VID, PID, device ID, > serial number, and name (barring, of course, vendor-specific > extensions). This modern sensibility is reflected in the driver stack. That is simply nonsense. As I have repeated for many times over and over again, the X server does not tell us what the model, manufacturer, VID, PID, serial number are. Those concepts do not even exist on some of the systems on which X servers run. And Emacs supports almost any X server in existence, from ancient versions of Xsun to the latest release of X.org, and to other servers written in Java that run as a browser applet. > A user is, of course, allowed to customize their device based on > any feature of it they want; it’s their computer after all. They can > even use the output of /dev/random if they so desire. But it is *not* a > feature of X that they may expect the device name to be a unique > identifier, and it should not be communicated to them as such. It is long-standing behavior of the X input extension. > I have done all I can to show that X does not guarantee unique > device names, from abstract rational argument to trawling the actual > code in use, to creating custom devices, to finding duplicate, > mass-manufactured devices. And while absence of evidence is not evidence > of absence, I believe there is enough weight behind my research to show > my claim to be correct. The onus is on you to prove the opposite, which > is far easier, in that it is at least logically possible: that X has a > guarantee of unique device names. Please show me where that claim is > made in official documentation, and I will cede that the current > behavior is a bug. The "official" documentation and guarantees died alongside the X Consortium. But the assumption is made by many tools, including (as I previously demonstrated) the xinput tool itself. Anyway, if you want to incorporate the serial number and USB identifiers into the classifications and names of input devices in Emacs, show us the code, and it working with every X server on at least the Unix-like platforms we currently support. Otherwise, the discussion ends here. I will not waste more time debating the implementation of a feature that cannot be implemented. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-11 14:09 ` Po Lu @ 2022-04-11 16:26 ` Brian Cully 0 siblings, 0 replies; 86+ messages in thread From: Brian Cully @ 2022-04-11 16:26 UTC (permalink / raw) To: Po Lu; +Cc: larsi, monnier, Eli Zaretskii, rms, emacs-devel Po Lu <luangruo@yahoo.com> writes: > But I am not interested in what the Linux kernel, evdev and libinput > expose. Emacs cannot use their information when running under X. It seems to me that part of our disagreement stems from having approached this problem from two different directions: you are looking at it from the perspective of an X client, and trying to use the information available to you in that context to design a feature. I have been looking at it from the perspective of someone who makes input devices, and looking at what is possible from that end. Unfortunately, in the middle we seem to have hit a snag in terms of expectations around device naming. > The device path is only exposed by the libinput (or evdev) drivers > through driver-specific device properties. Trying to use those > properties is IMNSHO suicidial: they change at random and are not > guaranteed to be present everywhere. And what if Emacs is connected to > a remote X server, or the device information cannot be queried due to a > lack of permissions to open that device file, or the device information > is simply incorrect? These are fair points. I do not have a way to resolve them within the scope of a pure X client. > Nonsense. I will not try to argue this with you further, since you > simply don't understand or have never worked with anything other than a > GNU/Linux system running the latest release of the X.Org server. Please do not resort to ad hominem. You do not know my history. I, too, remember a time of hand coding XF86Config in the 90s, and I am thankful to be long past that. And, frankly, recollections of how things worked a quarter century ago are not particularly relevant in the face of contradictory evidence of how things work now. > It is long-standing behavior of the X input extension. It may have been long-standing in the past, but it does not stand today. No one uses MIT X11 anymore. Almost no one uses XFree86. Sun Microsystems has been gone for over a decade, and ceased to be a particularly relevant X environment many years before that. XQuartz borrows heavily from X.Org. Like it or not, X.Org is the de facto standard. If you are using Emacs under X, the odds are very much in favor of that being on a Linux kernel, using evdev, libinput, and X.Org. I am, by no means, suggesting abandoning support for other platforms, I am stating that you cannot ignore the behavior of the platform that is most in use because of a perceived bug on your part. > Anyway, if you want to incorporate the serial number and USB identifiers > into the classifications and names of input devices in Emacs, show us > the code, and it working with every X server on at least the Unix-like > platforms we currently support. I have never claimed to have a solution. At previous points I have said that I don’t think this is a thing that Emacs can solve by itself, and that device names are acceptable to me as a “good enough” solution, provided it is end-user configuration that determines their event mappings. My issues in this thread are two-fold: 1) Device names cannot be counted on to be unique, and any design in Emacs that uses device names must take that into account, and, 2) Users should be informed that if they have multiple devices of the same type, then workarounds for various platforms may be necessary, such as udev rules on Linux. -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 18:08 ` Brian Cully 2022-04-11 0:58 ` Po Lu @ 2022-04-11 10:10 ` Lars Ingebrigtsen 1 sibling, 0 replies; 86+ messages in thread From: Lars Ingebrigtsen @ 2022-04-11 10:10 UTC (permalink / raw) To: Brian Cully; +Cc: Po Lu, Eli Zaretskii, emacs-devel, rms, monnier Brian Cully <bjc@spork.org> writes: > Moreover, it appears as though, at least with udev and libinput, > device names are *not* unique. By default, that's true -- it's left as an exercise to the user to name the devices uniquely if the users want to distinguish between them. Most of the time it doesn't matter whether a keyboard shows up as event12 or event13, after all. If it does matter, the user has to set up udev rules to map something or other from the device to a specific name. (I remember I once had three USB DVD readers that would show up in random order, and they didn't have any distinguishing characteristics -- no serial numbers or anything. So I had to flash them each with a different firmware so that I could work off of the firmware number and give the devices a stable name.) -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 8:42 ` Po Lu 2022-04-10 9:13 ` Eli Zaretskii @ 2022-04-10 12:44 ` Brian Cully 2022-04-10 13:14 ` Po Lu 1 sibling, 1 reply; 86+ messages in thread From: Brian Cully @ 2022-04-10 12:44 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Po Lu <luangruo@yahoo.com> writes: > Those programs don't just show the details to the user, they expose > those details to application code, in the hopes that the application > code will allow the code to behave appropriately, and the user to > customise the behavior based on those details. What level of application code is exposed to device naming? Surely the vast majority of code in Krita is completely agnostic as to where the event is coming from and only responding to an event type. The configuration would only specify a map of device+device-event -> internal-event (eg: (“logitech usb mouse” + “button 1 down”) -> “eraser down”), and the rest of the code in the system only cares about the latter event (“eraser down” in this case). -bjc ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 12:44 ` Brian Cully @ 2022-04-10 13:14 ` Po Lu 0 siblings, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-10 13:14 UTC (permalink / raw) To: Brian Cully; +Cc: Eli Zaretskii, emacs-devel, larsi, monnier, rms Brian Cully <bjc@spork.org> writes: > What level of application code is exposed to device naming? > Surely the vast majority of code in Krita is completely agnostic as to > where the event is coming from and only responding to an event type. The > configuration would only specify a map of device+device-event -> > internal-event (eg: (“logitech usb mouse” + “button 1 down”) -> “eraser > down”), and the rest of the code in the system only cares about the > latter event (“eraser down” in this case). That's out-of-scope. Krita plugins are based on attaching Qt signals to objects, and the plugins are supposed to utilize the Qt input device object that is passed around inside input events, which contains the name. Qt determines the type of device via that name, like Emacs does and other X programs do. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-07 23:41 ` Stefan Monnier 2022-04-08 0:07 ` Po Lu 2022-04-08 6:02 ` Eli Zaretskii @ 2022-04-08 14:27 ` Stefan Monnier 2022-04-09 0:24 ` Po Lu 2 siblings, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-08 14:27 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel >> Which event the global variable applies to is also perfectly clear: it >> applies to the last event that was read, either by the command loop or >> read-event. > Yeah, it works, but relying on state is ugly and better avoided if > we can. How 'bout a midway solution: we keep the var but we additionally put that info into those events where we can? Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-08 14:27 ` Stefan Monnier @ 2022-04-09 0:24 ` Po Lu 2022-04-09 2:52 ` Stefan Monnier 2022-04-09 6:22 ` Eli Zaretskii 0 siblings, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-09 0:24 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> Which event the global variable applies to is also perfectly clear: it >>> applies to the last event that was read, either by the command loop or >>> read-event. >> Yeah, it works, but relying on state is ugly and better avoided if >> we can. > > How 'bout a midway solution: we keep the var but we additionally put > that info into those events where we can? I'm fine with that, but we need a consistent way to get it from the event structures. WDYT about putting the device in the mouse position list? (Of course, Eli's concerns about the info itself will have to be addressed.) That way, we can have a single function `posn-device' to access the device. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 0:24 ` Po Lu @ 2022-04-09 2:52 ` Stefan Monnier 2022-04-09 3:17 ` Po Lu 2022-04-09 6:22 ` Eli Zaretskii 1 sibling, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-09 2:52 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel >> How 'bout a midway solution: we keep the var but we additionally put >> that info into those events where we can? > > I'm fine with that, but we need a consistent way to get it from the > event structures. Indeed. > WDYT about putting the device in the mouse position list? (Of course, > Eli's concerns about the info itself will have to be addressed.) > > That way, we can have a single function `posn-device' to access the > device. We could put it in the "posn" thingy, but at the same time it's not really a "posn" and it's kinda weird to duplicate it into the start and the end posn of an event. It would be better to associate it with the event itself and have an `event-device` function to access it. Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 2:52 ` Stefan Monnier @ 2022-04-09 3:17 ` Po Lu 2022-04-09 13:31 ` Stefan Monnier 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-09 3:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > We could put it in the "posn" thingy, but at the same time it's not > really a "posn" and it's kinda weird to duplicate it into the start and > the end posn of an event. It would be better to associate it with the > event itself and have an `event-device` function to access it. But wouldn't that mean the `event-device' function would have to have a specific implementation for each kind of event, with different indexes passed to `nth', since we can only add information to the end of each event? That's the sort of thing I was trying to avoid. Thanks. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 3:17 ` Po Lu @ 2022-04-09 13:31 ` Stefan Monnier 2022-04-09 13:37 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-09 13:31 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel Po Lu [2022-04-09 11:17:01] wrote: > Stefan Monnier <monnier@iro.umontreal.ca> writes: >> We could put it in the "posn" thingy, but at the same time it's not >> really a "posn" and it's kinda weird to duplicate it into the start and >> the end posn of an event. It would be better to associate it with the >> event itself and have an `event-device` function to access it. > But wouldn't that mean the `event-device' function would have to have a > specific implementation for each kind of event, with different indexes > passed to `nth', since we can only add information to the end of each > event? Not necessarily, it could be something like: (defun event-device (e) (when (consp e) (alist-get 'device (nthcdr 3 e)))) But I agree that the current representation of events is problematic. We should make it more regular and self-descriptive, either based on an alist as above or have every event come with some kind of "class" which then describes the name&position of every accompanying data. Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 13:31 ` Stefan Monnier @ 2022-04-09 13:37 ` Po Lu 2022-04-09 14:20 ` Stefan Monnier 2022-04-09 14:31 ` Eli Zaretskii 0 siblings, 2 replies; 86+ messages in thread From: Po Lu @ 2022-04-09 13:37 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > Not necessarily, it could be something like: > > (defun event-device (e) > (when (consp e) > (alist-get 'device (nthcdr 3 e)))) > > But I agree that the current representation of events is problematic. > We should make it more regular and self-descriptive, either based on an > alist as above or have every event come with some kind of "class" which > then describes the name&position of every accompanying data. Unfortunately, our current representation is basically set in stone. There is too much Lisp out there that relies on the current form of Lisp events, and simply finding all that code will be a serious chore. Maybe we could introduce a new representation of event in addition to the current form, with a its own interactive form and read-event, that represents events as some better data structure? We could then recommend that people use the new form of event, as with `keymap-set' and friends. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 13:37 ` Po Lu @ 2022-04-09 14:20 ` Stefan Monnier 2022-04-10 0:58 ` Po Lu 2022-04-09 14:31 ` Eli Zaretskii 1 sibling, 1 reply; 86+ messages in thread From: Stefan Monnier @ 2022-04-09 14:20 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel >> But I agree that the current representation of events is problematic. >> We should make it more regular and self-descriptive, either based on an >> alist as above or have every event come with some kind of "class" which >> then describes the name&position of every accompanying data. > Unfortunately, our current representation is basically set in stone. To some extent, yes, but we can try and design the new representation to be compatible with the old one. E.g. the "class" could be obtained via: (defun event-class (e) (if (consp e) (get (event-basic-type e) 'event-class) character-event-class)) > There is too much Lisp out there that relies on the current form of Lisp > events, and simply finding all that code will be a serious chore. Yup, that's why we have to introduce the new API in a way that's backward compatible. > Maybe we could introduce a new representation of event in addition to > the current form, with a its own interactive form and read-event, that > represents events as some better data structure? Here, I'd side with Eli and say that the resulting code churn wojuld be more trouble than it's worth. [ Most of that work has already been done in the context of XEmacs, but I doubt we'd be able to make use of it, sadly. ] Stefan ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 14:20 ` Stefan Monnier @ 2022-04-10 0:58 ` Po Lu 0 siblings, 0 replies; 86+ messages in thread From: Po Lu @ 2022-04-10 0:58 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > To some extent, yes, but we can try and design the new representation to > be compatible with the old one. E.g. the "class" could be obtained via: > > (defun event-class (e) > (if (consp e) > (get (event-basic-type e) 'event-class) > character-event-class)) Unfortunately the device class information is separate from the basic type of the event. i.e. trackpoints send mouse movement, and Lars' foot pedal simply pretends to be a keyboard and sends "b". > Here, I'd side with Eli and say that the resulting code churn wojuld be > more trouble than it's worth. Hmm... I will try to think of something. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 13:37 ` Po Lu 2022-04-09 14:20 ` Stefan Monnier @ 2022-04-09 14:31 ` Eli Zaretskii 2022-04-10 0:56 ` Po Lu 1 sibling, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 14:31 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 21:37:56 +0800 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > > Not necessarily, it could be something like: > > > > (defun event-device (e) > > (when (consp e) > > (alist-get 'device (nthcdr 3 e)))) > > > > But I agree that the current representation of events is problematic. > > We should make it more regular and self-descriptive, either based on an > > alist as above or have every event come with some kind of "class" which > > then describes the name&position of every accompanying data. > > Unfortunately, our current representation is basically set in stone. > There is too much Lisp out there that relies on the current form of Lisp > events, and simply finding all that code will be a serious chore. We could keep the form, but add additional members to the list, no? ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 14:31 ` Eli Zaretskii @ 2022-04-10 0:56 ` Po Lu 2022-04-10 6:11 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 0:56 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Po Lu <luangruo@yahoo.com> >> Cc: emacs-devel@gnu.org >> Date: Sat, 09 Apr 2022 21:37:56 +0800 >> >> Stefan Monnier <monnier@iro.umontreal.ca> writes: >> >> > Not necessarily, it could be something like: >> > >> > (defun event-device (e) >> > (when (consp e) >> > (alist-get 'device (nthcdr 3 e)))) >> > >> > But I agree that the current representation of events is problematic. >> > We should make it more regular and self-descriptive, either based on an >> > alist as above or have every event come with some kind of "class" which >> > then describes the name&position of every accompanying data. >> >> Unfortunately, our current representation is basically set in stone. >> There is too much Lisp out there that relies on the current form of Lisp >> events, and simply finding all that code will be a serious chore. > > We could keep the form, but add additional members to the list, no? That's simply too confusing, where different events have very different indexes into the list to get the same property. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 0:56 ` Po Lu @ 2022-04-10 6:11 ` Eli Zaretskii 2022-04-10 6:23 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 6:11 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 08:56:38 +0800 > > >> Unfortunately, our current representation is basically set in stone. > >> There is too much Lisp out there that relies on the current form of Lisp > >> events, and simply finding all that code will be a serious chore. > > > > We could keep the form, but add additional members to the list, no? > > That's simply too confusing, where different events have very different > indexes into the list to get the same property. Why "different indexes to get the same property"? The additional members should provide additional information, unavailable in the original elements. We already have such data structures in Emacs; see, for example, data structures returned by pos-visible-in-window-p and find-composition. The list returned by posn-at-point is another example: the 2nd member can be either display area or buffer position, and the 6th member always reports the position. So this is quite "normal" in Emacs, assuming that the data structure is designed to be convenient for the code that will use it. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:11 ` Eli Zaretskii @ 2022-04-10 6:23 ` Po Lu 2022-04-10 6:52 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 6:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Why "different indexes to get the same property"? The additional > members should provide additional information, unavailable in the > original elements. We already have such data structures in Emacs; > see, for example, data structures returned by pos-visible-in-window-p > and find-composition. The list returned by posn-at-point is another > example: the 2nd member can be either display area or buffer position, > and the 6th member always reports the position. So this is quite > "normal" in Emacs, assuming that the data structure is designed to be > convenient for the code that will use it. Because it doesn't make sense for this additional information to obscure information that is already available. For example, we might extend `wheel-up' and `wheel-down' with an extra DEVICE parameter, so that it might look something like this: (wheel-down POSITION CLICKS LINES PIXEL-DELTA DEVICE) But for touch end events, it would look like this: (touch-end POSITION DEVICE) And for pinch events, (pinch POSITION DX DY SCALE ANGLE DEVICE) To access the device would require the 6th, 3rd and 7th elements of each type of event, which is very confusing. Stefan's solution of making DEVICE an association might work, but I suspect it would be liable to break if any of the preceding elements were also conses. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:23 ` Po Lu @ 2022-04-10 6:52 ` Eli Zaretskii 2022-04-10 7:37 ` Po Lu 0 siblings, 1 reply; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 6:52 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 14:23:58 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Why "different indexes to get the same property"? The additional > > members should provide additional information, unavailable in the > > original elements. We already have such data structures in Emacs; > > see, for example, data structures returned by pos-visible-in-window-p > > and find-composition. The list returned by posn-at-point is another > > example: the 2nd member can be either display area or buffer position, > > and the 6th member always reports the position. So this is quite > > "normal" in Emacs, assuming that the data structure is designed to be > > convenient for the code that will use it. > > Because it doesn't make sense for this additional information to obscure > information that is already available. > > For example, we might extend `wheel-up' and `wheel-down' with an extra > DEVICE parameter, so that it might look something like this: > > (wheel-down POSITION CLICKS LINES PIXEL-DELTA DEVICE) > > But for touch end events, it would look like this: > > (touch-end POSITION DEVICE) > > And for pinch events, > > (pinch POSITION DX DY SCALE ANGLE DEVICE) > > To access the device would require the 6th, 3rd and 7th elements of each > type of event, which is very confusing. We have this in many places in Emacs already, so adding one more will not hurt too much. Dispatch on the first element of the list is easy and produces code that is quite readable and maintainable, IMO. Of course, if more elegant ways exist, I don't object to using them, quite the contrary. But if not, I see nothing especially wrong with doing what you call "very confusing", because we do it elsewhere. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 6:52 ` Eli Zaretskii @ 2022-04-10 7:37 ` Po Lu 2022-04-10 8:12 ` Eli Zaretskii 0 siblings, 1 reply; 86+ messages in thread From: Po Lu @ 2022-04-10 7:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > We have this in many places in Emacs already, so adding one more will > not hurt too much. Dispatch on the first element of the list is easy > and produces code that is quite readable and maintainable, IMO. > > Of course, if more elegant ways exist, I don't object to using them, > quite the contrary. But if not, I see nothing especially wrong with > doing what you call "very confusing", because we do it elsewhere. Hmm, do we use keywords anywhere inside Lisp events? If not, then here's a simple way to add a property list to the end of event lists: (defun event-plist (event) "Return the property list of EVENT." (while (and event (not (keywordp (car event)))) (setq event (cdr event))) event) Then, additional information could just be added to the end of each event by appending any property list that associates keywords. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-10 7:37 ` Po Lu @ 2022-04-10 8:12 ` Eli Zaretskii 0 siblings, 0 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-10 8:12 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sun, 10 Apr 2022 15:37:30 +0800 > > Eli Zaretskii <eliz@gnu.org> writes: > > > We have this in many places in Emacs already, so adding one more will > > not hurt too much. Dispatch on the first element of the list is easy > > and produces code that is quite readable and maintainable, IMO. > > > > Of course, if more elegant ways exist, I don't object to using them, > > quite the contrary. But if not, I see nothing especially wrong with > > doing what you call "very confusing", because we do it elsewhere. > > Hmm, do we use keywords anywhere inside Lisp events? If not, then > here's a simple way to add a property list to the end of event lists: > > (defun event-plist (event) > "Return the property list of EVENT." > (while (and event (not (keywordp (car event)))) > (setq event (cdr event))) > event) > > Then, additional information could just be added to the end of each > event by appending any property list that associates keywords. It's possible. But using ordered lists is also OK. Having keyword/value pairs would probably call for a new kind of event list, so that applications could know whether to use indexed access or keyword-based access. ^ permalink raw reply [flat|nested] 86+ messages in thread
* Re: master 3b41141708: Expose the name of an event's input device to Lisp 2022-04-09 0:24 ` Po Lu 2022-04-09 2:52 ` Stefan Monnier @ 2022-04-09 6:22 ` Eli Zaretskii 1 sibling, 0 replies; 86+ messages in thread From: Eli Zaretskii @ 2022-04-09 6:22 UTC (permalink / raw) To: Po Lu; +Cc: monnier, emacs-devel > From: Po Lu <luangruo@yahoo.com> > Cc: emacs-devel@gnu.org > Date: Sat, 09 Apr 2022 08:24:49 +0800 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > >>> Which event the global variable applies to is also perfectly clear: it > >>> applies to the last event that was read, either by the command loop or > >>> read-event. > >> Yeah, it works, but relying on state is ugly and better avoided if > >> we can. > > > > How 'bout a midway solution: we keep the var but we additionally put > > that info into those events where we can? > > I'm fine with that, but we need a consistent way to get it from the > event structures. > > WDYT about putting the device in the mouse position list? (Of course, > Eli's concerns about the info itself will have to be addressed.) > > That way, we can have a single function `posn-device' to access the > device. From where I stand, I didn't yet understand why we would need to have the information about the "device" on the level where events are interpreted by Lisp programs. Introducing "devices" on that level is a slippery slope: it will inevitably and naturally lead us to platform dependencies where IMO we prefer not to have such dependencies. So I think we must try very hard to avoid using a notion of "device" on that level, and try to come up with alternative ways of letting Emacs do whatever it should without knowing about "devices". ^ permalink raw reply [flat|nested] 86+ messages in thread
end of thread, other threads:[~2022-04-11 16:26 UTC | newest] Thread overview: 86+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <164933858147.29834.15050766441005536059@vcs2.savannah.gnu.org> [not found] ` <20220407133623.9C209C009A8@vcs2.savannah.gnu.org> 2022-04-07 14:05 ` master 3b41141708: Expose the name of an event's input device to Lisp Stefan Monnier 2022-04-07 23:31 ` Po Lu 2022-04-07 23:41 ` Stefan Monnier 2022-04-08 0:07 ` Po Lu 2022-04-08 6:02 ` Eli Zaretskii 2022-04-08 6:08 ` Po Lu 2022-04-08 6:26 ` Eli Zaretskii 2022-04-08 7:36 ` Po Lu 2022-04-08 11:12 ` Eli Zaretskii 2022-04-08 11:31 ` Po Lu 2022-04-08 12:12 ` Eli Zaretskii 2022-04-08 12:35 ` Po Lu 2022-04-09 6:48 ` Eli Zaretskii 2022-04-09 9:06 ` Po Lu 2022-04-09 9:09 ` Lars Ingebrigtsen 2022-04-09 9:30 ` Eli Zaretskii 2022-04-09 10:03 ` Po Lu 2022-04-09 11:03 ` Eli Zaretskii 2022-04-09 11:44 ` Po Lu 2022-04-09 14:04 ` Eli Zaretskii 2022-04-09 16:33 ` Stefan Monnier 2022-04-09 16:41 ` Lars Ingebrigtsen 2022-04-09 17:06 ` Eli Zaretskii 2022-04-09 17:16 ` Eli Zaretskii 2022-04-09 17:52 ` Brian Cully 2022-04-09 19:18 ` Eli Zaretskii 2022-04-10 0:54 ` Po Lu 2022-04-10 1:46 ` Brian Cully 2022-04-10 2:11 ` Po Lu 2022-04-10 2:45 ` Brian Cully 2022-04-10 3:30 ` Po Lu 2022-04-10 0:37 ` Po Lu 2022-04-10 5:49 ` Eli Zaretskii 2022-04-10 6:09 ` Po Lu 2022-04-10 6:44 ` Eli Zaretskii 2022-04-10 7:31 ` Po Lu 2022-04-10 8:28 ` Eli Zaretskii 2022-04-10 8:50 ` Po Lu 2022-04-10 9:17 ` Eli Zaretskii 2022-04-10 9:25 ` Po Lu 2022-04-10 11:15 ` Po Lu 2022-04-10 15:16 ` Stefan Monnier 2022-04-11 1:02 ` Po Lu 2022-04-10 11:46 ` Lars Ingebrigtsen 2022-04-10 11:41 ` Lars Ingebrigtsen 2022-04-10 0:48 ` Po Lu 2022-04-10 6:04 ` Eli Zaretskii 2022-04-10 6:17 ` Po Lu 2022-04-10 6:49 ` Eli Zaretskii 2022-04-10 7:01 ` Po Lu 2022-04-10 8:24 ` Eli Zaretskii 2022-04-10 8:42 ` Po Lu 2022-04-10 9:13 ` Eli Zaretskii 2022-04-10 12:51 ` Brian Cully 2022-04-10 13:21 ` Po Lu 2022-04-10 18:08 ` Brian Cully 2022-04-11 0:58 ` Po Lu 2022-04-11 1:08 ` Brian Cully 2022-04-11 2:00 ` Po Lu 2022-04-11 2:03 ` Po Lu 2022-04-11 2:21 ` Brian Cully 2022-04-11 3:12 ` Po Lu 2022-04-11 4:11 ` Brian Cully 2022-04-11 5:20 ` Po Lu 2022-04-11 11:33 ` Brian Cully 2022-04-11 14:09 ` Po Lu 2022-04-11 16:26 ` Brian Cully 2022-04-11 10:10 ` Lars Ingebrigtsen 2022-04-10 12:44 ` Brian Cully 2022-04-10 13:14 ` Po Lu 2022-04-08 14:27 ` Stefan Monnier 2022-04-09 0:24 ` Po Lu 2022-04-09 2:52 ` Stefan Monnier 2022-04-09 3:17 ` Po Lu 2022-04-09 13:31 ` Stefan Monnier 2022-04-09 13:37 ` Po Lu 2022-04-09 14:20 ` Stefan Monnier 2022-04-10 0:58 ` Po Lu 2022-04-09 14:31 ` Eli Zaretskii 2022-04-10 0:56 ` Po Lu 2022-04-10 6:11 ` Eli Zaretskii 2022-04-10 6:23 ` Po Lu 2022-04-10 6:52 ` Eli Zaretskii 2022-04-10 7:37 ` Po Lu 2022-04-10 8:12 ` Eli Zaretskii 2022-04-09 6:22 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).