This will trigger e.d. keyboard_leave() and wl_pointer_leave() events,
which ensures there aren't any references to the destroyed window from
the global wayland struct.
Call wl_display_roundtrip() to trigger those events *before* we
destroy the window.
It is perfectly possible, and legal, for a FDM handler to delete
another handler. The problem however is when the epoll returned array
of FD events contain the removed FD handler *after* the handler that
removed it.
That is, if the epoll returned array is:
[FD=13, FD=37]
and the handler for FD=13 removes FD=37, then given the current
implementation, the FD user data (our handler callback etc) will point
to a free:d address.
Add support for this situation by deferring FD handler removal *when
called from another handler*.
This is done by "locking" the FDM struct before looping the handlers
for FDs with events (and unlocking afterwards).
In fdm_del(), we check if the FDM has been locked, in which case the
FD is marked as deleted, and put on a deferred list. But
not *actually* deleted.
Meanwhile, in the FDM poll function, we skip calling handlers for
marked-for-deletion FDs.
Then, when all FDs have been processed, we loop the deferred list and
finally deletes the FDs for real.
This function unmaps the terminal window, removes itself from the
wayland list of terminals and then finally destroys itself.
We ensure we don't get any callbacks/events referring to a free:d
terminal struct, we close all terminal related FDs and unmap the
wayland window.
Then, to be really really sure there aren't any (by the FDM) queued up
events, we delay the self-destruction to the next FDM poll iteration,
by opening an event FD and adding it to the FDM.
The callback for the event FD removes the FD from the FDM again, and
closes it. And then proceeds to destroy the terminal.
When doing "small" scrolls (typically done via mouse wheel or
similar), we render the scrolling by emitting a "scroll damage".
A recent commit changed how scroll damage is rendered; only when the
view is at the bottom ("following" the screen output) do we render the
damage.
To fix this, add a new type of scroll damage,
SCROLL_DAMAGE_IN_VIEW and SCROLL_DAMAGE_REVERSE_IN_VIEW.
These signal to the renderer that it should always render the damage.
Since we now initialize the worker threads from term_init(), which
returns before the threads terminate, we can no longer use
stack-allocated worker contexts.
We _could_ put them in the terminal struct. But a simpler solution is
to allocate them in term_init(), and let the threads free them when
they don't need them anymore.
When user has scrolled back in the output history, new output should
not trigger scrolling.
This was true for normal cell rendering, which renders the cells *in
view*, not caring where the "front" of the output is.
However, we still applied scroll damage. I.e. we memmoved part of the
screen.
The fix is simple; only apply scroll damage when the view is at the
front of the output.
We do however need access to it, so provide a pointer. The difference
is that now we can have a *single* wayland instance, but multiple
terminal instances.