unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* 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-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  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

* 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  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 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 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 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: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 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-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-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-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-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-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-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  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  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  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: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: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: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: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: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: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  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  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-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  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: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: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: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  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  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-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  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  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: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-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 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 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-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-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-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-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

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).