Not sure how this can happen, but sometimes it does. Not including in
the changelog because it may be caused by changes in this pre-release
version, and it would be difficult to describe to users, anyway.
Squashed commit of the following:
commit ccc54b7910228495983d9ffc8e7b491baafead62
Author: Adam Porter <adam@alphapapa.net>
Date: Thu Sep 15 16:21:31 2022 -0500
Change/Fix: Read receipts
Read receipts are now updated via a global idle timer that iterates
over visible room buffers. This avoids the nasty, inexplicable race
condition that sometimes happened when using window-scroll-functions,
which could cause the functions to be called infinitely, sometimes
making Emacs unresponsive or even causing it to crash.
Also, a room's read receipt is now set to the last completely visible
event (i.e. if an event is only partially displayed, it's not
considered read).
commit 3569c1d2b5251061eb1415a7849039ff0f6f3c2a
Author: Adam Porter <adam@alphapapa.net>
Date: Thu Sep 15 15:23:54 2022 -0500
WIP: See comment
Well, this reproduces the problem fairly reliably in my config in
that, after connecting, it begins calling the
ement-room-start-read-receipt-timer function infinitely. Sometimes I
can interrupt it by selecting one or another room window and scrolling
it or moving point in it. I have no explanation for why the function
is called infinitely; the only entry point into it is in the room
buffers' local values of window-scroll-functions.
I'm going to try another approach, that of changing the global value
of the variable and having the function iterate over visible windows.
Disabling this because of some weird behavior. It seems like a race
condition exists in which the window-scroll-functions are called,
causing the read receipt to get sent, followed by the read-receipt
being updated, causing the window-scroll-functions to be called again
before the updated receipt is displayed in the buffer, which can cause
an infinite loop, which can even exhaust the Lisp stack and cause
Emacs to freeze (without 100% CPU usage). At least, that's the best
explanation I have so far--it's very weird. Until it's solved, we'll
have to do without sending read receipts. Maybe
window-scroll-functions isn't suitable for this, even though it seems
ideal in theory. Maybe instead we should use a simple idle timer that
iterates over windows, or something like that.
A bug was introduced in the previous fixes that can cause excessive
read receipts to be sent in rapid succession. A more thoughtful fix
will be necessary to properly send only one receipt per room event and
per scroll event. In the meantime, this must be disabled to prevent
the excessive network requests.
This may fix a weird bug introduced in the last commit or
two (involving variable-binding-depth errors, timers running
repeatedly and making Emacs unresponsive, etc--I have no idea how the
changes could have caused such a thing, but they apparently did).
- Move function called by timer to a named function.
- Send read receipt even if its position is outside the range of
retrieved events. Otherwise, it could be so far back that it never
gets updated, which doesn't seem useful. The fully-read marker
remains unmoved until the user gets to the end of the room's events
and marks them all as read, which seems right and useful.