That is, only call it if we have POLLIN. If not, then we never read
any events and we still hold the read lock and thus we shouldn't try
to acquire it again.
This way, we don't have to manually insert flushes in code paths that
may execute outside of a wl_display_dispatch_pending().
(Those that execute inside a wl_display_dispatch_pending() are subject
to the flush performed at the end of the normal wayland FDM handler).
With a bad behaving client (e.g. 'less' with mouse support enabled),
we can end up with a *lot* of xcursor updates (so much, that we
flooded the wayland socket before we implemented a blocking
wayl_flush()).
Since there's little point in updating the cursor more than once per
frame interval, use frame callbacks to throttle the updates.
This works more or lesslike normal terminal refreshes:
render_xcursor_set() stores the last terminal (window) that had (and
updated) the cursor.
The renderer's FDM hook checks if we have such a pending terminal set,
and if so, tries to refresh the cursor.
This is done by first checking if we're already waiting for a callback
from a previous cursor update, and if so we do nothing; the callback
will update the cursor for the next frame. If we're *not* already
waiting for a callback, we update the cursor immediately.
Since it doesn't block, we need to detect EAGAIN failures and ensure
we actually flush everything.
If we don't, we sooner or later end up in a wayland client library
call that aborts due to the socket buffer being full.
Ideally, we'd simply enable POLLOUT in the FDM. However, we cannot
write *anything* to the wayland socket until we've actually managed to
send everything. This means enabling POLLOUT in the FDM wont work
since we may (*will*) end up trying to write more data to it before
we've flushed it.
So, add a wrapper function, wayl_flush(), that acts as a blocking
variant of wl_display_flush(), by detecting EAGAIN failiures and
calling poll() itself, on the wayland socket only, until all data has
been sent.
When background alpha is 1.0 (0xffff), i.e. completely opaque, tell
the compositor this, via wl_surface_set_opaque_region().
This allows it to optimize drawing of surfaces _behind_ our window.
wl_display_dispatch() calls poll(), which is unnecessary since we
already know the FD is readable.
Use the more lower level wl_display_read_events() +
wl_display_dispatch_pending().
These require wl_display_prepare_read() to have been called.
The idea is to call wl_display_prepare_read() **before** calling
poll().
Thus, we do this more or less last in wayl_init(), and at the **end**
of the FDM handler.
However, having taking this lock also means we no longer can call
wl_display_roundtrip() directly (it will hang).
So, add a wrapper, wayl_roundtrip(), that cancels the read intent,
does the roundtrip, and then re-acquires the read intent.
This hopefully fixes and issue where the visual focus in/out caused a
render refresh with the *old* size.
This caused the occasional flicker at startup, or when resizing the
window.
By placing the resize call before the visual focus in/out, we ensure
the refresh uses the new size.
This is a temporary workaround. The correct solution is to ensure we
only call refresh() once.
Any changes done in any of the configure events are ignored before
we've ack:ed the configure event.
In particular, this means the resize done in xdg-toplevel-configure
isn't displayed until the next time we call render_refresh().
Unless we do something ourselves, this can take quite some time, since
we're basically need the slave to write something.
So, in xdg-surface-configure, *after* having ack:ed the configure
event, call render_refresh() to make the changes done in
xdg-toplevel-configure visible as soon as possible.
We can now lookup terminal instances at all times, making it
unnecessary to detect "early" configure events.
Note that we still need to prevent a resize from happening when
width/height is 0.
Instead of having `wayl_win_init()` call
`wl_display_roundtrip()` (which it itself doesn't need), call it from
`term_init()`.
This allows us to add ourselves (the new terminal instance) to the
terminal list in the wayland backend, before triggering the wayland
events caused by `wayl_win_init()`.
This is turn allows the wayland backend to find/lookup the new
terminal when those events occur..
This adds a flag, -p,--presentation-timings, that enables input lag
measuring using the presentation time Wayland protocol.
When enabled, we store a timestamp when we *send* a key to the
slave. Then, when we commit a frame for rendering to the compositor,
we request presentation feedback. We also store a timestamp for when
the frame was committed.
The 'presented' callback then looks at the input and commit
timestamps, and compares it with the presented timestamp.
The delay is logged at INFO when the delay was less than one frame
interval, at WARN when it was one frame interval, and at ERR when it
was two or more frame intervals.
We also update statistic counters that we log when foot is shut down.
We may have many windows open, which tries to update/change the
xcursor at various points.
Track which cursor is currently loaded, regardless of which window it
was set by. If someone tries to load that very same xcursor again,
simply skip it.
One example is when we've moused over a window that does *not* have
keyboard focus, and then the user clicks, or by some other mean gives
that window keyboard focus. In many cases it will then try to set the
same cursor again (most of the times, the cursor is the same
regardless of keyboard focus, but not always).