wayland: configure: work around GNOME/mutter weirdness

When resizing the window under mutter, mutter seems to expect a
configure ack *and* a surface commit *right* away, or things get out
of sync.

Unlike kwin, which is requires a commit for each configure ack, but is
fine with having the commit arrive later (after we've rendered it),
mutter is not.

I even tried delaying the configure ack until just before the commit,
but still no go.

So for now, detect when we're running under mutter and always do a
surface commit right away.

This can *not* be done on any other compositor as it breaks the CSD
and main surface synchronization; we've resized the CSDs, but not the
main surface.

I.e. this *should* not work, but for some reason is the *only* way to
make things work on mutter.

Interestingly, doing it any other way on mutter causes visual
glitches; window jumping around when resizing, or de-synchronized
CSDs/main surface.
This commit is contained in:
Daniel Eklöf 2020-02-28 18:43:33 +01:00
parent b69c9b5f58
commit 6ba476b3bd
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -595,11 +595,41 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
else
term_visual_focus_out(term);
if (!resized) {
static bool desktop_is_gnome = false;
static bool desktop_is_initialized = false;
if (!desktop_is_initialized) {
const char *current_desktop = getenv("XDG_CURRENT_DESKTOP");
desktop_is_gnome = current_desktop != NULL &&
strcasestr(current_desktop, "gnome") != NULL;
if (desktop_is_gnome)
LOG_WARN("applying wl_surface_commit() workaround for mutter");
desktop_is_initialized = true;
}
if (desktop_is_gnome) {
/*
* kwin seems to need a commit for each configure ack, or it
* will get stuck. Since we'll get a "real" commit soon if we
* resized, only commit here if size did *not* change
* Resizing the window under mutter causes the "other" side to
* jump back and forth, *even* if we re-render and commit a
* properly resized frame immediately.
*
* For that reason, the code path below also does not work,
* since in case we *did* resize, it appears the commit
* happens "too late" after the ack.
*
* Finally, doing this on any other compositor breaks the CSD
* synchronization with the main surface. Hence we only do
* this when running under mutter.
*/
wl_surface_commit(win->surface);
} else if (!resized) {
/*
* If we didn't resize, we won't be commit a new surface
* anytime soon. Some compositors require a commit in
* combination with an ack - make them happy.
*/
wl_surface_commit(win->surface);
}