It seems kwin expects a wl_surface_commit() for each
xdg_surface_ack_configure().
We don't want to commit before we've rendered a resized surface. So,
if we *did* change the window size, let the normal rendering path do
the surface commit.
Only when we did *not* change the window size do we need to explicitly
commit the surface in xdg_surface_configure().
Call render_resize_force() when the decoration type changes
run-time. This ensures the CSDs are drawn when changing from server ->
client side decorations, and removed when going the other way.
xdg_output_handle_logical_size() reports _logical_ output size. That
is, it is scaled by the output's scale factor.
We want the _actual_ DPI. The _real_ output size is reported by
output_mode(), so use that instead.
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..