[RFC weston] libweston-desktop: Add size_requested API
Quentin Glidic
sardemff7+wayland at sardemff7.net
Tue Mar 21 11:53:10 UTC 2017
From: Quentin Glidic <sardemff7+git at 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+git at 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
More information about the wayland-devel
mailing list