From: Quentin Glidic <sardemff7+...@sardemff7.net> Some shells (wl_shell) does not let the compositor control the surface state and instead force one. Therefore, they cannot call {maximized,fullscreen}_requested as these imply the compositor can still opt-out. This new callback is called whenever a state change requests a new size, be it triggered by the client or the compositor.
Signed-off-by: Quentin Glidic <sardemff7+...@sardemff7.net> --- This patch works correctly as-is, but is RFC because I have yet to add some API to support output choice in wl_shell. libweston-desktop/internal.h | 12 +++++++ libweston-desktop/libweston-desktop.c | 8 +++++ libweston-desktop/libweston-desktop.h | 11 ++++++ libweston-desktop/surface.c | 36 ++++++++++++++++++++ libweston-desktop/wl-shell.c | 14 +++++--- libweston-desktop/xdg-shell-v5.c | 64 +++++++++++++++++++++++++++++------ libweston-desktop/xdg-shell-v6.c | 64 +++++++++++++++++++++++++++++------ libweston-desktop/xwayland.c | 11 ++++-- 8 files changed, 194 insertions(+), 26 deletions(-) diff --git a/libweston-desktop/internal.h b/libweston-desktop/internal.h index 763355bf..38386916 100644 --- a/libweston-desktop/internal.h +++ b/libweston-desktop/internal.h @@ -80,6 +80,9 @@ weston_desktop_api_maximized_requested(struct weston_desktop *desktop, void weston_desktop_api_minimized_requested(struct weston_desktop *desktop, struct weston_desktop_surface *surface); +void +weston_desktop_api_size_requested(struct weston_desktop *desktop, + struct weston_desktop_surface *surface); void weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop, @@ -123,6 +126,15 @@ struct weston_desktop_surface_implementation { (*get_min_size)(struct weston_desktop_surface *surface, void *user_data); + bool (*get_pending_activated)(struct weston_desktop_surface *surface, + void *user_data); + bool (*get_pending_fullscreen)(struct weston_desktop_surface *surface, + void *user_data); + bool (*get_pending_maximized)(struct weston_desktop_surface *surface, + void *user_data); + bool (*get_pending_resizing)(struct weston_desktop_surface *surface, + void *user_data); + void (*destroy)(struct weston_desktop_surface *surface, void *user_data); }; diff --git a/libweston-desktop/libweston-desktop.c b/libweston-desktop/libweston-desktop.c index 48e90009..a5ae5bd9 100644 --- a/libweston-desktop/libweston-desktop.c +++ b/libweston-desktop/libweston-desktop.c @@ -243,6 +243,14 @@ weston_desktop_api_minimized_requested(struct weston_desktop *desktop, desktop->api.minimized_requested(surface, desktop->user_data); } +void +weston_desktop_api_size_requested(struct weston_desktop *desktop, + struct weston_desktop_surface *surface) +{ + if (desktop->api.size_requested != NULL) + desktop->api.size_requested(surface, desktop->user_data); +} + void weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop, struct weston_desktop_surface *surface, diff --git a/libweston-desktop/libweston-desktop.h b/libweston-desktop/libweston-desktop.h index 03b04c7b..8da10a49 100644 --- a/libweston-desktop/libweston-desktop.h +++ b/libweston-desktop/libweston-desktop.h @@ -80,6 +80,8 @@ struct weston_desktop_api { bool maximized, void *user_data); void (*minimized_requested)(struct weston_desktop_surface *surface, void *user_data); + void (*size_requested)(struct weston_desktop_surface *surface, + void *user_data); /** Position suggestion for an Xwayland window * @@ -192,6 +194,15 @@ weston_desktop_surface_get_max_size(struct weston_desktop_surface *surface); struct weston_size weston_desktop_surface_get_min_size(struct weston_desktop_surface *surface); +bool +weston_desktop_surface_get_pending_activated(struct weston_desktop_surface *surface); +bool +weston_desktop_surface_get_pending_maximized(struct weston_desktop_surface *surface); +bool +weston_desktop_surface_get_pending_fullscreen(struct weston_desktop_surface *surface); +bool +weston_desktop_surface_get_pending_resizing(struct weston_desktop_surface *surface); + #ifdef __cplusplus } #endif diff --git a/libweston-desktop/surface.c b/libweston-desktop/surface.c index d3be9364..50aa4f46 100644 --- a/libweston-desktop/surface.c +++ b/libweston-desktop/surface.c @@ -675,6 +675,42 @@ weston_desktop_surface_get_min_size(struct weston_desktop_surface *surface) surface->implementation_data); } +WL_EXPORT bool +weston_desktop_surface_get_pending_activated(struct weston_desktop_surface *surface) +{ + if (surface->implementation->get_pending_activated == NULL) + return false; + return surface->implementation->get_pending_activated(surface, + surface->implementation_data); +} + +WL_EXPORT bool +weston_desktop_surface_get_pending_resizing(struct weston_desktop_surface *surface) +{ + if (surface->implementation->get_pending_resizing == NULL) + return false; + return surface->implementation->get_pending_resizing(surface, + surface->implementation_data); +} + +WL_EXPORT bool +weston_desktop_surface_get_pending_maximized(struct weston_desktop_surface *surface) +{ + if (surface->implementation->get_pending_maximized == NULL) + return false; + return surface->implementation->get_pending_maximized(surface, + surface->implementation_data); +} + +WL_EXPORT bool +weston_desktop_surface_get_pending_fullscreen(struct weston_desktop_surface *surface) +{ + if (surface->implementation->get_pending_fullscreen == NULL) + return false; + return surface->implementation->get_pending_fullscreen(surface, + surface->implementation_data); +} + void weston_desktop_surface_set_title(struct weston_desktop_surface *surface, const char *title) diff --git a/libweston-desktop/wl-shell.c b/libweston-desktop/wl-shell.c index 399139cf..a48c8ab7 100644 --- a/libweston-desktop/wl-shell.c +++ b/libweston-desktop/wl-shell.c @@ -155,6 +155,8 @@ weston_desktop_wl_shell_change_state(struct weston_desktop_wl_shell_surface *sur if (to_add && surface->added) { surface->state = state; + weston_desktop_api_size_requested(surface->desktop, + surface->surface); return; } @@ -162,16 +164,19 @@ weston_desktop_wl_shell_change_state(struct weston_desktop_wl_shell_surface *sur if (surface->state == POPUP) weston_desktop_wl_shell_surface_maybe_ungrab(surface); + surface->state = state; + if (to_add) { weston_desktop_surface_unset_relative_to(surface->surface); weston_desktop_api_surface_added(surface->desktop, surface->surface); + weston_desktop_api_size_requested(surface->desktop, + surface->surface); } else if (surface->added) { weston_desktop_api_surface_removed(surface->desktop, surface->surface); } - surface->state = state; surface->added = to_add; } @@ -304,9 +309,8 @@ weston_desktop_wl_shell_surface_protocol_set_fullscreen(struct wl_client *wl_cli if (output_resource != NULL) output = wl_resource_get_user_data(output_resource); + /* FIXME: add back output usage */ weston_desktop_wl_shell_change_state(surface, FULLSCREEN, NULL, 0, 0); - weston_desktop_api_fullscreen_requested(surface->desktop, dsurface, - true, output); } static void @@ -355,7 +359,6 @@ weston_desktop_wl_shell_surface_protocol_set_maximized(struct wl_client *wl_clie weston_desktop_surface_get_implementation_data(dsurface); weston_desktop_wl_shell_change_state(surface, MAXIMIZED, NULL, 0, 0); - weston_desktop_api_maximized_requested(surface->desktop, dsurface, true); } static void @@ -403,6 +406,9 @@ static const struct weston_desktop_surface_implementation weston_desktop_wl_shel .get_maximized = weston_desktop_wl_shell_surface_get_maximized, .get_fullscreen = weston_desktop_wl_shell_surface_get_fullscreen, + .get_pending_maximized = weston_desktop_wl_shell_surface_get_maximized, + .get_pending_fullscreen = weston_desktop_wl_shell_surface_get_fullscreen, + .destroy = weston_desktop_wl_shell_surface_destroy, }; diff --git a/libweston-desktop/xdg-shell-v5.c b/libweston-desktop/xdg-shell-v5.c index 08cf71ee..b2cb6588 100644 --- a/libweston-desktop/xdg-shell-v5.c +++ b/libweston-desktop/xdg-shell-v5.c @@ -53,7 +53,7 @@ struct weston_desktop_xdg_surface { bool fullscreen; bool resizing; bool activated; - } requested_state, next_state, state; + } pending_state, next_state, state; bool has_next_geometry; struct weston_geometry next_geometry; }; @@ -86,25 +86,28 @@ weston_desktop_xdg_surface_send_configure(void *data) uint32_t *s; struct wl_array states; + /* User is expected to call _set_size(), so we trigger it now so it + * doesn’t schedule another configure event */ + weston_desktop_api_size_requested(surface->desktop, surface->surface); surface->configure_idle = NULL; surface->configure_serial = wl_display_next_serial(weston_desktop_get_display(surface->desktop)); wl_array_init(&states); - if (surface->requested_state.maximized) { + if (surface->pending_state.maximized) { s = wl_array_add(&states, sizeof(uint32_t)); *s = XDG_SURFACE_STATE_MAXIMIZED; } - if (surface->requested_state.fullscreen) { + if (surface->pending_state.fullscreen) { s = wl_array_add(&states, sizeof(uint32_t)); *s = XDG_SURFACE_STATE_FULLSCREEN; } - if (surface->requested_state.resizing) { + if (surface->pending_state.resizing) { s = wl_array_add(&states, sizeof(uint32_t)); *s = XDG_SURFACE_STATE_RESIZING; } - if (surface->requested_state.activated) { + if (surface->pending_state.activated) { s = wl_array_add(&states, sizeof(uint32_t)); *s = XDG_SURFACE_STATE_ACTIVATED; } @@ -141,7 +144,7 @@ weston_desktop_xdg_surface_set_maximized(struct weston_desktop_surface *dsurface if (surface->state.maximized == maximized) return; - surface->requested_state.maximized = maximized; + surface->pending_state.maximized = maximized; weston_desktop_xdg_surface_schedule_configure(surface); } @@ -154,7 +157,7 @@ weston_desktop_xdg_surface_set_fullscreen(struct weston_desktop_surface *dsurfac if (surface->state.fullscreen == fullscreen) return; - surface->requested_state.fullscreen = fullscreen; + surface->pending_state.fullscreen = fullscreen; weston_desktop_xdg_surface_schedule_configure(surface); } @@ -167,7 +170,7 @@ weston_desktop_xdg_surface_set_resizing(struct weston_desktop_surface *dsurface, if (surface->state.resizing == resizing) return; - surface->requested_state.resizing = resizing; + surface->pending_state.resizing = resizing; weston_desktop_xdg_surface_schedule_configure(surface); } @@ -180,7 +183,7 @@ weston_desktop_xdg_surface_set_activated(struct weston_desktop_surface *dsurface if (surface->state.activated == activated) return; - surface->requested_state.activated = activated; + surface->pending_state.activated = activated; weston_desktop_xdg_surface_schedule_configure(surface); } @@ -288,6 +291,42 @@ weston_desktop_xdg_surface_get_activated(struct weston_desktop_surface *dsurface return surface->state.activated; } +static bool +weston_desktop_xdg_surface_get_pending_maximized(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_surface *surface = user_data; + + return surface->pending_state.maximized; +} + +static bool +weston_desktop_xdg_surface_get_pending_fullscreen(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_surface *surface = user_data; + + return surface->pending_state.fullscreen; +} + +static bool +weston_desktop_xdg_surface_get_pending_resizing(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_surface *surface = user_data; + + return surface->pending_state.resizing; +} + +static bool +weston_desktop_xdg_surface_get_pending_activated(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_surface *surface = user_data; + + return surface->pending_state.activated; +} + static void weston_desktop_xdg_surface_destroy(struct weston_desktop_surface *dsurface, void *user_data) @@ -415,7 +454,7 @@ weston_desktop_xdg_surface_protocol_ack_configure(struct wl_client *wl_client, if (surface->configure_serial != serial) return; - surface->next_state = surface->requested_state; + surface->next_state = surface->pending_state; } static void @@ -540,6 +579,11 @@ static const struct weston_desktop_surface_implementation weston_desktop_xdg_sur .get_resizing = weston_desktop_xdg_surface_get_resizing, .get_activated = weston_desktop_xdg_surface_get_activated, + .get_pending_maximized = weston_desktop_xdg_surface_get_pending_maximized, + .get_pending_fullscreen = weston_desktop_xdg_surface_get_pending_fullscreen, + .get_pending_resizing = weston_desktop_xdg_surface_get_pending_resizing, + .get_pending_activated = weston_desktop_xdg_surface_get_pending_activated, + .destroy = weston_desktop_xdg_surface_destroy, }; diff --git a/libweston-desktop/xdg-shell-v6.c b/libweston-desktop/xdg-shell-v6.c index 7d0bd8e4..df838170 100644 --- a/libweston-desktop/xdg-shell-v6.c +++ b/libweston-desktop/xdg-shell-v6.c @@ -88,7 +88,7 @@ struct weston_desktop_xdg_toplevel { bool fullscreen; bool resizing; bool activated; - } requested_state, next_state, state; + } pending_state, next_state, state; struct weston_size next_max_size, max_size, next_min_size, min_size; @@ -413,7 +413,7 @@ weston_desktop_xdg_toplevel_protocol_resize(struct wl_client *wl_client, static void weston_desktop_xdg_toplevel_ack_configure(struct weston_desktop_xdg_toplevel *toplevel) { - toplevel->next_state = toplevel->requested_state; + toplevel->next_state = toplevel->pending_state; } static void @@ -523,19 +523,19 @@ weston_desktop_xdg_toplevel_send_configure(struct weston_desktop_xdg_toplevel *t struct wl_array states; wl_array_init(&states); - if (toplevel->requested_state.maximized) { + if (toplevel->pending_state.maximized) { s = wl_array_add(&states, sizeof(uint32_t)); *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED; } - if (toplevel->requested_state.fullscreen) { + if (toplevel->pending_state.fullscreen) { s = wl_array_add(&states, sizeof(uint32_t)); *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN; } - if (toplevel->requested_state.resizing) { + if (toplevel->pending_state.resizing) { s = wl_array_add(&states, sizeof(uint32_t)); *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING; } - if (toplevel->requested_state.activated) { + if (toplevel->pending_state.activated) { s = wl_array_add(&states, sizeof(uint32_t)); *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED; } @@ -557,7 +557,7 @@ weston_desktop_xdg_toplevel_set_maximized(struct weston_desktop_surface *dsurfac if (toplevel->state.maximized == maximized) return; - toplevel->requested_state.maximized = maximized; + toplevel->pending_state.maximized = maximized; weston_desktop_xdg_surface_schedule_configure(&toplevel->base); } @@ -570,7 +570,7 @@ weston_desktop_xdg_toplevel_set_fullscreen(struct weston_desktop_surface *dsurfa if (toplevel->state.fullscreen == fullscreen) return; - toplevel->requested_state.fullscreen = fullscreen; + toplevel->pending_state.fullscreen = fullscreen; weston_desktop_xdg_surface_schedule_configure(&toplevel->base); } @@ -583,7 +583,7 @@ weston_desktop_xdg_toplevel_set_resizing(struct weston_desktop_surface *dsurface if (toplevel->state.resizing == resizing) return; - toplevel->requested_state.resizing = resizing; + toplevel->pending_state.resizing = resizing; weston_desktop_xdg_surface_schedule_configure(&toplevel->base); } @@ -596,7 +596,7 @@ weston_desktop_xdg_toplevel_set_activated(struct weston_desktop_surface *dsurfac if (toplevel->state.activated == activated) return; - toplevel->requested_state.activated = activated; + toplevel->pending_state.activated = activated; weston_desktop_xdg_surface_schedule_configure(&toplevel->base); } @@ -694,6 +694,42 @@ weston_desktop_xdg_toplevel_get_activated(struct weston_desktop_surface *dsurfac return toplevel->state.activated; } +static bool +weston_desktop_xdg_toplevel_get_pending_maximized(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_toplevel *toplevel = user_data; + + return toplevel->pending_state.maximized; +} + +static bool +weston_desktop_xdg_toplevel_get_pending_fullscreen(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_toplevel *toplevel = user_data; + + return toplevel->pending_state.fullscreen; +} + +static bool +weston_desktop_xdg_toplevel_get_pending_resizing(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_toplevel *toplevel = user_data; + + return toplevel->pending_state.resizing; +} + +static bool +weston_desktop_xdg_toplevel_get_pending_activated(struct weston_desktop_surface *dsurface, + void *user_data) +{ + struct weston_desktop_xdg_toplevel *toplevel = user_data; + + return toplevel->pending_state.activated; +} + static void weston_desktop_xdg_toplevel_destroy(struct weston_desktop_xdg_toplevel *toplevel) { @@ -851,6 +887,9 @@ weston_desktop_xdg_surface_send_configure(void *user_data) { struct weston_desktop_xdg_surface *surface = user_data; + /* User is expected to call _set_size(), so we trigger it now so it + * doesn’t schedule another configure event */ + weston_desktop_api_size_requested(surface->desktop, surface->desktop_surface); surface->configure_idle = NULL; surface->configure_serial = wl_display_next_serial(weston_desktop_get_display(surface->desktop)); @@ -1148,6 +1187,11 @@ static const struct weston_desktop_surface_implementation weston_desktop_xdg_sur .get_resizing = weston_desktop_xdg_toplevel_get_resizing, .get_activated = weston_desktop_xdg_toplevel_get_activated, + .get_pending_maximized = weston_desktop_xdg_toplevel_get_pending_maximized, + .get_pending_fullscreen = weston_desktop_xdg_toplevel_get_pending_fullscreen, + .get_pending_resizing = weston_desktop_xdg_toplevel_get_pending_resizing, + .get_pending_activated = weston_desktop_xdg_toplevel_get_pending_activated, + /* These are used for popup only */ .update_position = weston_desktop_xdg_popup_update_position, diff --git a/libweston-desktop/xwayland.c b/libweston-desktop/xwayland.c index b9843853..d2670e37 100644 --- a/libweston-desktop/xwayland.c +++ b/libweston-desktop/xwayland.c @@ -79,6 +79,8 @@ weston_desktop_xwayland_surface_change_state(struct weston_desktop_xwayland_surf if (to_add && surface->added) { surface->state = state; + weston_desktop_api_size_requested(surface->desktop, + surface->surface); return; } @@ -94,10 +96,14 @@ weston_desktop_xwayland_surface_change_state(struct weston_desktop_xwayland_surf weston_surface_unmap(wsurface); } + surface->state = state; + if (to_add) { weston_desktop_surface_unset_relative_to(surface->surface); weston_desktop_api_surface_added(surface->desktop, surface->surface); + weston_desktop_api_size_requested(surface->desktop, + surface->surface); surface->added = true; } else if (surface->added) { weston_desktop_api_surface_removed(surface->desktop, @@ -116,8 +122,6 @@ weston_desktop_xwayland_surface_change_state(struct weston_desktop_xwayland_surf surface->view->is_mapped = true; wsurface->is_mapped = true; } - - surface->state = state; } if (parent != NULL) @@ -202,6 +206,9 @@ static const struct weston_desktop_surface_implementation weston_desktop_xwaylan .get_maximized = weston_desktop_xwayland_surface_get_maximized, .get_fullscreen = weston_desktop_xwayland_surface_get_fullscreen, + .get_pending_maximized = weston_desktop_xwayland_surface_get_maximized, + .get_pending_fullscreen = weston_desktop_xwayland_surface_get_fullscreen, + .destroy = weston_desktop_xwayland_surface_destroy, }; -- 2.11.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel