mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04: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
2 changed files with 35 additions and 4 deletions
|
|
@ -539,6 +539,17 @@ static bool commit_layers(struct wlr_wl_output *output,
|
||||||
return true;
|
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,
|
static bool output_commit(struct wlr_output *wlr_output,
|
||||||
const struct wlr_output_state *state) {
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_wl_output *output =
|
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);
|
bool pending_enabled = output_pending_enabled(wlr_output, state);
|
||||||
|
|
||||||
if (wlr_output->enabled && !pending_enabled) {
|
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_attach(output->surface, NULL, 0, 0);
|
||||||
wl_surface_commit(output->surface);
|
wl_surface_commit(output->surface);
|
||||||
|
|
||||||
|
|
@ -710,6 +729,10 @@ static void output_destroy(struct wlr_output *wlr_output) {
|
||||||
presentation_feedback_destroy(feedback);
|
presentation_feedback_destroy(feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output->unmap_callback) {
|
||||||
|
wl_callback_destroy(output->unmap_callback);
|
||||||
|
}
|
||||||
|
|
||||||
if (output->zxdg_toplevel_decoration_v1) {
|
if (output->zxdg_toplevel_decoration_v1) {
|
||||||
zxdg_toplevel_decoration_v1_destroy(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;
|
struct wlr_wl_output *output = data;
|
||||||
assert(output && output->xdg_surface == xdg_surface);
|
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_width = output->wlr_output.width;
|
||||||
int32_t req_height = output->wlr_output.height;
|
int32_t req_height = output->wlr_output.height;
|
||||||
if (output->requested_width > 0) {
|
if (output->requested_width > 0) {
|
||||||
|
|
@ -781,6 +800,14 @@ static void xdg_surface_handle_configure(void *data,
|
||||||
output->requested_height = 0;
|
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;
|
struct wlr_output_state state;
|
||||||
wlr_output_state_init(&state);
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_custom_mode(&state, req_width, req_height, 0);
|
wlr_output_state_set_custom_mode(&state, req_width, req_height, 0);
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,10 @@ struct wlr_wl_output {
|
||||||
|
|
||||||
bool initialized;
|
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;
|
uint32_t enter_serial;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue