layout: Inform client to resize for fullscreen roles 32/27532/1
authorMarius Vlad <marius.vlad@collabora.com>
Mon, 2 May 2022 12:05:23 +0000 (15:05 +0300)
committerMarius Vlad <marius.vlad@collabora.com>
Thu, 26 May 2022 12:24:34 +0000 (15:24 +0300)
In a previous patch we optimized sending the dimensions from the start,
but in some situations the client might set up the surface roles
*after* that happens, which might lead to issue as we are explicitly
terminating the connection if the client wasn't correctly resized by
that time.

This corrects that such that even if we perform a late set-up for the
fullscreen role, we can still tell the client to resize, and later on to
display the surface.

Bug-AGL: SPEC-4339
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: I491c60c9881e99bc3201216a842782417286f0d9
(cherry picked from commit 7a7b46bd7040b2814ad5f314818742bad990e93c)

src/ivi-compositor.h
src/layout.c

index 0b26d04..e12be18 100644 (file)
@@ -267,6 +267,11 @@ struct ivi_surface {
        bool activated_by_default;
        bool advertised_on_launch;
        bool checked_pending;
+       enum {
+               NORMAL,
+               RESIZING,
+               FULLSCREEN,
+       } state;
 
        enum ivi_surface_role role;
        union {
index 62e422c..700a318 100644 (file)
@@ -405,46 +405,80 @@ ivi_layout_fullscreen_committed(struct ivi_surface *surface)
        struct ivi_output *bg_output = ivi_layout_find_bg_output(ivi);
 
        struct weston_view *view = surface->view;
-       struct weston_geometry geom;
+       struct weston_geometry geom =
+               weston_desktop_surface_get_geometry(dsurface);
+
+       bool is_fullscreen = weston_desktop_surface_get_fullscreen(dsurface);
+       bool is_dim_same =
+               geom.width == bg_output->output->width &&
+               geom.height == bg_output->output->height;
 
        if (policy && policy->api.surface_activate_by_default &&
            !policy->api.surface_activate_by_default(surface, surface->ivi) &&
            !surface->activated_by_default)
                return;
 
-       if (surface->view->is_mapped)
+       assert(surface->role == IVI_SURFACE_ROLE_FULLSCREEN);
+
+       if (weston_view_is_mapped(view))
                return;
 
-       geom = weston_desktop_surface_get_geometry(dsurface);
-       assert(surface->role == IVI_SURFACE_ROLE_FULLSCREEN);
+       /* if we still get here but we haven't resized so far, send configure
+        * events to do so */
+       if (surface->state != RESIZING && (!is_fullscreen || !is_dim_same)) {
+               struct ivi_output *bg_output =
+                       ivi_layout_find_bg_output(surface->ivi);
+
+               weston_log("Placing fullscreen app_id %s, type %s in hidden layer\n",
+                               app_id, ivi_layout_get_surface_role_name(surface));
+               weston_desktop_surface_set_fullscreen(dsurface, true);
+               weston_desktop_surface_set_size(dsurface,
+                                               bg_output->output->width,
+                                               bg_output->output->height);
 
-       if (!weston_desktop_surface_get_fullscreen(dsurface) ||
-           geom.width != bg_output->output->width ||
-           geom.height != bg_output->output->height) {
+               surface->state = RESIZING;
+               weston_view_set_output(view, output->output);
+               weston_layer_entry_insert(&ivi->hidden.view_list, &view->layer_link);
+               return;
+       }
+
+       /* eventually, we would set the surface fullscreen, but the client
+        * hasn't resized correctly by this point, so terminate connection */
+       if (surface->state == RESIZING && is_fullscreen && !is_dim_same) {
                struct weston_desktop_client *desktop_client =
                        weston_desktop_surface_get_client(dsurface);
                struct wl_client *client =
                        weston_desktop_client_get_client(desktop_client);
                wl_client_post_implementation_error(client,
-                               "Can not display surface due to invalid geometry");
+                               "can not display surface due to invalid geometry."
+                               " Client should perform a geometry resize!");
                return;
        }
 
-       weston_view_set_output(view, woutput);
-       weston_view_set_position(view, woutput->x, woutput->y);
-       weston_layer_entry_insert(&ivi->fullscreen.view_list, &view->layer_link);
+       /* this implies we resized correctly */
+       if (!weston_view_is_mapped(view)) {
+               weston_layer_entry_remove(&view->layer_link);
 
-       weston_view_geometry_dirty(view);
-       weston_surface_damage(view->surface);
+               weston_view_set_output(view, woutput);
+               weston_view_set_position(view, woutput->x, woutput->y);
+               weston_layer_entry_insert(&ivi->fullscreen.view_list, &view->layer_link);
 
-       wsurface->is_mapped = true;
-       surface->view->is_mapped = true;
+               wsurface->is_mapped = true;
+               surface->view->is_mapped = true;
+               surface->state = FULLSCREEN;
 
-       shell_advertise_app_state(ivi, app_id,
-                                 NULL, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED);
+               weston_view_geometry_dirty(view);
+               weston_surface_damage(view->surface);
 
-       weston_log("Activation completed for app_id %s, role %s, output %s\n",
-                       app_id, ivi_layout_get_surface_role_name(surface), output->name);
+               shell_advertise_app_state(ivi, app_id,
+                               NULL, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED);
+
+               weston_log("Activation completed for app_id %s, role %s, "
+                          "output %s\n", app_id,
+                          ivi_layout_get_surface_role_name(surface),
+                          output->name);
+
+       }
 }
 
 void