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

Reply via email to