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

From: Po Lu <[email-masked]>
Date: Tue, 04 Jul 2023 21:19:51 +0800

[email-masked] writes:

> Ah, I see.  Then, like pipes and sockets, it should really at least
> support interrupting the transfer...

It's 30 years too late for changes to the ICCCM.  So we will have to
make the best out of what we have.

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

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

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

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

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