Subject: Re: bug#64423: 29.0.92; save-interprogram-paste-before-kill doesn't prevent streaming large selections

From: [email-masked]
Date: Tue, 04 Jul 2023 14:46:36 +0000 (UTC)

Po Lu <[email-masked]> writes:
>> Such costs only need to be paid if there are indeed multiple conversions
>> happening at the same time.  In the common case there's just one, so
>> there's no extra cost of adding the ability to have multiple ongoing
>> conversions.
>
> Adding extra round trip cost to a part of Emacs that is already one of
> the slowest and most synchronous components of the X Windows support is
> unacceptable in my book.  Especially for such an uncommon situation: I
> can't remember the last time I quit a selection request to a working
> selection owner, and I use Emacs over wide area networks every day.

I think you might be misunderstanding me?  Just to say again, in the
normal case, this would not add extra cost.  This would only add extra
round trip cost in cases which, as you say below, currently just confuse
and break Emacs.

(Also, the entire point would be that this component would move from
being synchronous to being able to run in the background, concurrent
with other things.)

>> Actually, how does this work today?  If an Emacs user quits a conversion
>> and then immediately starts a new one, that seems to work fine.  We
>> don't do different properties in each request.  I realize the protocol
>> doesn't support it, but doesn't that suggest that it's fine in practice
>> to interrupt a conversion...?
>
> If Emacs quits while waiting for a property change to take place, and
> the property change event from the recipient of the request that was
> quit still arrives, Emacs will become confused and return outdated
> selection data.  Or even worse, a mixture of the selection data from
> both the new and old owners.
>
> Selection owners that are not implemented robustly may also freeze if
> Emacs quits before removing the selection transfer property from its
> window to acknowledge the selection data's arrival.

OK, interesting.  So it's basically broken already today to interrupt a
gui-get-selection... great.

>> (Quitting a conversion then running another would be one way to have
>> multiple conversions at the same time.  Another way would be (related to
>> my other thread about call-process) to allow running Lisp while an
>> incremental selection transfer is ongoing.  I know that seems useless
>> but I really am of the opinion that every blocking operation in Emacs
>> which can take more than a few milliseconds should support running Lisp
>> while it blocks...)
>
> No, it's only necessary for us to ensure that C-g works, so the user can
> always quit from the long-running operation.  Otherwise, your position
> cannot be consistent without insisting that constructs such as `while'
> also check for and run timers and selection converters.

This is becoming tangential, but, yes, I will bite that bullet.  "while"
should also check for and run timers and selection converters, when Lisp
code opts-in to that behavior.  I can think of several ways to implement
this without hurting performance.

IMO the major issue with the Emacs UI at the moment is that it blocks
too much, relative to "modern" applications.  Some of this blocking can
only be fixed by speeding up Lisp execution, but substantial parts of
this blocking can only be fixed by making Emacs more concurrent - that
is, making it possible for Lisp code to run concurrently with other Lisp
code, on an opt-in basis, instead of blocking all Lisp execution while
operations like gui-get-selection and call-process are running.

I am aware this is a major undertaking, but I think it's important for
Emacs to compare favorably with "modern" applications which don't
exhibit as much random UI blocking.  I regard this as basically
equivalent to the lexical-binding transition.

>> Yes.  Personally I'd like to have a lower value for that when a
>> save-interprogram-paste-before-kill is triggered.  So adding a separate
>> save-interprogram-paste-before-kill-timeout which can be lower, and
>> which let-binds x-selection-timeout, seems good.
>
> How is that different from setting `x-selection-timeout'?  IOW, what's
> your real-world use case for such an additional option?  Have you tried
> adjusting `x-selection-timeout' for all selection transfers?

Here is the real-world use case: When I yank I'm willing to wait for 2
or 10 seconds for the paste to complete, since the paste is what I
actually want.  But when I kill-new I want to wait less time, because
the save-interprogram-paste-before-kill behavior is just a nice-to-have,
which I want to happen if it's convenient and fast, not the actual thing
I want to do.

> Let's not overengineer the system independent interprogram code with
> X-specific options.  Thanks.

A gui-selection-timeout would be fine with me, too.  Maybe other systems
would benefit?  pgtk?