layout: Do not delay mapping of desktop surface until commit time 34/23734/2
authorMarius Vlad <marius.vlad@collabora.com>
Mon, 3 Feb 2020 19:48:39 +0000 (21:48 +0200)
committerMarius Vlad <marius.vlad@collabora.com>
Tue, 4 Feb 2020 17:03:46 +0000 (19:03 +0200)
On some older qtwayland versions (5.11) the weston_desktop_surface
window geometry has all its members set to 0. The panel initialization
takes place with the 'ready' request and this will result in an invalid
x and y position for panels  different than the top one.

This patch alleviates that by not mapping the desktop surface in case we
determine that the desktop_surface geometry is invalid and proceed on
doing so when the surface is committed, which will allow to retrieve the
correct desktop surface and set the proper location of the panel. That
should be sufficient to display top/bottom panels until we switch a
newer qtwayland version. This keeps the panel initialization in place,
as to avoid any other changes in the future.

Bug-AGL: SPEC-3136

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: I7388444ffe213f0524898cd3a5b175d90985ff1c

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

index ed6208f..a637ddd 100644 (file)
@@ -120,8 +120,20 @@ desktop_committed(struct weston_desktop_surface *dsurface,
 {
        struct ivi_surface *surface =
                weston_desktop_surface_get_user_data(dsurface);
-       if (surface->role == IVI_SURFACE_ROLE_DESKTOP)
+       weston_compositor_schedule_repaint(surface->ivi->compositor);
+
+       switch (surface->role) {
+       case IVI_SURFACE_ROLE_DESKTOP:
                ivi_layout_desktop_committed(surface);
+               break;
+       case IVI_SURFACE_ROLE_PANEL:
+               ivi_layout_panel_committed(surface);
+               break;
+       case IVI_SURFACE_ROLE_NONE:
+       case IVI_SURFACE_ROLE_BACKGROUND:
+       default: /* fall through */
+               break;
+       }
 }
 
 static void
index f3a51d6..47e20a3 100644 (file)
@@ -236,4 +236,7 @@ ivi_layout_activate(struct ivi_output *output, const char *app_id);
 void
 ivi_layout_desktop_committed(struct ivi_surface *surf);
 
+void
+ivi_layout_panel_committed(struct ivi_surface *surface);
+
 #endif
index 106f6fb..3166e92 100644 (file)
@@ -114,9 +114,28 @@ ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output,
                        panel->panel.edge, view, x, y);
 #endif
 
+       /* this is necessary for cases we already mapped it desktop_committed()
+        * but we not running the older qtwayland, so we still have a chance
+        * for this to run at the next test */
+       if (view->surface->is_mapped) {
+               weston_layer_entry_remove(&view->layer_link);
+
+               view->is_mapped = false;
+               view->surface->is_mapped = false;
+       }
+
+       /* give ivi_layout_panel_committed() a chance to map the view/surface
+        * instead */
+       if ((geom.width == geom.height && geom.width == 0) &&
+           (geom.x == geom.y && geom.x == 0) &&
+           panel->panel.edge != AGL_SHELL_EDGE_TOP)
+               return;
+
        view->is_mapped = true;
        view->surface->is_mapped = true;
-
+#ifdef AGL_COMP_DEBUG
+       weston_log("panel type %d inited\n", panel->panel.edge);
+#endif
        weston_layer_entry_insert(&ivi->panel.view_list, &view->layer_link);
 }
 
@@ -250,6 +269,73 @@ ivi_layout_desktop_committed(struct ivi_surface *surf)
        ivi_layout_activate_complete(output, surf);
 }
 
+void
+ivi_layout_panel_committed(struct ivi_surface *surface)
+{
+       struct ivi_compositor *ivi = surface->ivi;
+       struct ivi_output *output = surface->bg.output;
+       struct weston_output *woutput = output->output;
+       struct weston_desktop_surface *dsurface = surface->dsurface;
+       struct weston_surface *wsurface =
+               weston_desktop_surface_get_surface(dsurface);
+       struct weston_geometry geom;
+       int x = woutput->x;
+       int y = woutput->y;
+
+       assert(surface->role == IVI_SURFACE_ROLE_PANEL);
+
+       /*
+        * If the desktop_surface geometry is not set and the panel is not a
+        * top one, we'll give this a chance to run, as some qtwayland version
+        * seem to have a 'problem', where the panel initilization part will
+        * have a desktop surface with 0 as geometry for *all* its members
+        * (width/height). Doing that will result in the panel not being
+        * displayed at all.
+        *
+        * Later versions of qtwayland do have the correct window geometry for
+        * the desktop surface so the weston_surface is already mapped in
+        * ivi_panel_init().
+        */
+       if (wsurface->is_mapped)
+               return;
+
+       geom = weston_desktop_surface_get_geometry(dsurface);
+
+#ifdef AGL_COMP_DEBUG
+       weston_log("geom.width %d, geom.height %d, geom.x %d, geom.y %d\n",
+                       geom.width, geom.height, geom.x, geom.y);
+#endif
+
+       switch (surface->panel.edge) {
+       case AGL_SHELL_EDGE_TOP:
+               /* Do nothing */
+               break;
+       case AGL_SHELL_EDGE_BOTTOM:
+               y += woutput->height - geom.height;
+               break;
+       case AGL_SHELL_EDGE_LEFT:
+               /* Do nothing */
+               break;
+       case AGL_SHELL_EDGE_RIGHT:
+               x += woutput->width - geom.width;
+               break;
+       }
+#ifndef AGL_COMP_DEBUG
+       weston_log("panel type %d commited\n", surface->panel.edge);
+#endif
+
+       weston_view_set_output(surface->view, woutput);
+       weston_view_set_position(surface->view, x, y);
+       weston_layer_entry_insert(&ivi->panel.view_list,
+                                 &surface->view->layer_link);
+
+       weston_view_update_transform(surface->view);
+       weston_view_schedule_repaint(surface->view);
+
+       wsurface->is_mapped = true;
+       surface->view->is_mapped = true;
+}
+
 void
 ivi_layout_activate(struct ivi_output *output, const char *app_id)
 {