emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: master 3b41141708: Expose the name of an event's input device to Lis


From: Eli Zaretskii
Subject: Re: master 3b41141708: Expose the name of an event's input device to Lisp
Date: Sat, 09 Apr 2022 17:04:23 +0300

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]