wayland: unset hidden state in frame callback

More wayland weirdness. So previously, flipping a hidden state from true
to false was done in vo_wayland_wait_frame. In theory, this would be
after you get the frame callback and all those events so there's no
problem. However since the function also does a bunch of
flushing/dispatching/etc. to the default display queue so a lot of
unknown things can happen before we actually set the hidden variable
back to false. For example if a single image was paused and left on
another virtual desktop long enough (~5 minutes) while also not having
focus, switching back to that desktop could render it a black frame.

This edge case was supposed to be handled by the surface being activated
again in the toplevel event but apparently that doesn't always work. The
fix is to just delete all of that junk and set wl->hidden = false in the
frame callback. What's actually happening is kind of a mystery honestly.
Probably the compositor drops the buffers after a while as an
optimization (sensible) and forces a repaint if you switch back to the
virtual desktop. Somehow wl->hidden not being set to false would not
properly trigger a repaint (likely because it also sends a toplevel
event which does stuff) thus you just get a black window. If you just
make sure to set hidden in the frame callback, it appears like all of
these problems and edge cases are solved. Since this event must happen
first, that makes sense. That simplifies a lot of stuff and fixes some
subtle bugs at the same time so just go with this approach.
This commit is contained in:
Dudemanguy 2021-07-26 14:26:51 -05:00
parent f8e62d3d82
commit e2c24adebe
1 changed files with 1 additions and 8 deletions

View File

@ -838,12 +838,6 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
{
wl->focused = !wl->focused;
wl->pending_vo_events |= VO_EVENT_FOCUS;
if (wl->activated) {
/* If the surface comes back into view, force a redraw. */
vo_wayland_wait_frame(wl);
wl->pending_vo_events |= VO_EVENT_EXPOSE;
}
}
}
@ -994,6 +988,7 @@ static void frame_callback(void *data, struct wl_callback *callback, uint32_t ti
}
wl->frame_wait = false;
wl->hidden = false;
}
static const struct wl_callback_listener frame_listener = {
@ -1992,13 +1987,11 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl)
return;
} else {
wl->timeout_count += 1;
wl->hidden = false;
return;
}
}
wl->timeout_count = 0;
wl->hidden = false;
}
void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us)