mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-25 00:22:25 +00:00
backend/wayland: don't ack outdated configures
This commit fixes the following interaction: 1) The host compositor sends a configure sequence for an output. 2) Before handling it, the guest compositor disables and immediately re-enables the output. 3) The guest compositor tries to ack the configure event from step 1 which isn't relevant anymore after unmapping and re-initialization. Instead, ignore all configure events after unmapping until we're sure the host compositor has processed the unmapping. Also see https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/108.
This commit is contained in:
parent
d80c46250d
commit
629a5171f2
@ -539,6 +539,17 @@ static bool commit_layers(struct wlr_wl_output *output,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void unmap_callback_handle_done(void *data, struct wl_callback *callback,
|
||||
uint32_t cb_data) {
|
||||
struct wlr_wl_output *output = data;
|
||||
output->unmap_callback = NULL;
|
||||
wl_callback_destroy(callback);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener unmap_callback_listener = {
|
||||
.done = unmap_callback_handle_done,
|
||||
};
|
||||
|
||||
static bool output_commit(struct wlr_output *wlr_output,
|
||||
const struct wlr_output_state *state) {
|
||||
struct wlr_wl_output *output =
|
||||
@ -551,6 +562,14 @@ static bool output_commit(struct wlr_output *wlr_output,
|
||||
bool pending_enabled = output_pending_enabled(wlr_output, state);
|
||||
|
||||
if (wlr_output->enabled && !pending_enabled) {
|
||||
if (output->own_surface) {
|
||||
output->unmap_callback = wl_display_sync(output->backend->remote_display);
|
||||
if (output->unmap_callback == NULL) {
|
||||
return false;
|
||||
}
|
||||
wl_callback_add_listener(output->unmap_callback, &unmap_callback_listener, output);
|
||||
}
|
||||
|
||||
wl_surface_attach(output->surface, NULL, 0, 0);
|
||||
wl_surface_commit(output->surface);
|
||||
|
||||
@ -710,6 +729,10 @@ static void output_destroy(struct wlr_output *wlr_output) {
|
||||
presentation_feedback_destroy(feedback);
|
||||
}
|
||||
|
||||
if (output->unmap_callback) {
|
||||
wl_callback_destroy(output->unmap_callback);
|
||||
}
|
||||
|
||||
if (output->zxdg_toplevel_decoration_v1) {
|
||||
zxdg_toplevel_decoration_v1_destroy(output->zxdg_toplevel_decoration_v1);
|
||||
}
|
||||
@ -766,10 +789,6 @@ static void xdg_surface_handle_configure(void *data,
|
||||
struct wlr_wl_output *output = data;
|
||||
assert(output && output->xdg_surface == xdg_surface);
|
||||
|
||||
output->configured = true;
|
||||
output->has_configure_serial = true;
|
||||
output->configure_serial = serial;
|
||||
|
||||
int32_t req_width = output->wlr_output.width;
|
||||
int32_t req_height = output->wlr_output.height;
|
||||
if (output->requested_width > 0) {
|
||||
@ -781,6 +800,14 @@ static void xdg_surface_handle_configure(void *data,
|
||||
output->requested_height = 0;
|
||||
}
|
||||
|
||||
if (output->unmap_callback != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
output->configured = true;
|
||||
output->has_configure_serial = true;
|
||||
output->configure_serial = serial;
|
||||
|
||||
struct wlr_output_state state;
|
||||
wlr_output_state_init(&state);
|
||||
wlr_output_state_set_custom_mode(&state, req_width, req_height, 0);
|
||||
|
@ -101,6 +101,10 @@ struct wlr_wl_output {
|
||||
|
||||
bool initialized;
|
||||
|
||||
// If not NULL, the host compositor hasn't acknowledged the unmapping yet;
|
||||
// ignore all configure events
|
||||
struct wl_callback *unmap_callback;
|
||||
|
||||
uint32_t enter_serial;
|
||||
|
||||
struct {
|
||||
|
Loading…
Reference in New Issue
Block a user