src/: Add the remote surface role 53/24653/2
authorMarius Vlad <marius.vlad@collabora.com>
Fri, 29 May 2020 17:41:58 +0000 (20:41 +0300)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Sun, 14 Jun 2020 12:53:38 +0000 (12:53 +0000)
This patch adds the 'remote' surface role, which clients can make use of
to hint the compositor that it should place the surface on other
output.

While both private extension protocols (agl-shell and agl-shell-desktop)
explicitly  require a wl_output when activating or when setting surface
roles, we still need the inform the compositor that the surface should be
placed on another output.

This is due to the activate_by_default functionality that requires
having an output being present, with the default regular XDG desktop
role deriving its output by using the output of the backgound surface
(which is being normally set by the client shell).

Just like pop-up dialog role and split surface role this patch adds
another temporary hold up place before the surface is actually created.

Bug-AGL: SPEC-3280

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

protocol/agl-shell-desktop.xml
src/ivi-compositor.h
src/main.c
src/shell.c

index 9ef4cca..4f942f5 100644 (file)
@@ -37,6 +37,7 @@
       <entry name="fullscreen" value="1"/>
       <entry name="split_vertical" value="2"/>
       <entry name="split_horizontal" value="3"/>
+      <entry name="remote" value="4"/>
     </enum>
 
     <enum name="app_state">
index 5244afe..671ceac 100644 (file)
@@ -91,6 +91,7 @@ struct ivi_compositor {
        struct wl_list popup_pending_apps;
        struct wl_list fullscreen_pending_apps;
        struct wl_list split_pending_apps;
+       struct wl_list remote_pending_apps;
 
        struct weston_layer hidden;
        struct weston_layer background;
@@ -149,6 +150,7 @@ enum ivi_surface_role {
        IVI_SURFACE_ROLE_FULLSCREEN,
        IVI_SURFACE_ROLE_SPLIT_V,
        IVI_SURFACE_ROLE_SPLIT_H,
+       IVI_SURFACE_ROLE_REMOTE,
 };
 
 struct pending_popup {
@@ -172,6 +174,12 @@ struct pending_split {
        struct wl_list link;    /** ivi_compositor::split_pending_apps */
 };
 
+struct pending_remote {
+       struct ivi_output *ioutput;
+       char *app_id;
+       struct wl_list link;    /** ivi_compositor::remote_pending_apps */
+};
+
 struct ivi_desktop_surface {
        struct ivi_output *pending_output;
        struct ivi_output *last_output;
@@ -196,6 +204,10 @@ struct ivi_split_surface {
        uint32_t orientation;
 };
 
+struct ivi_remote_surface {
+       struct ivi_output *output;
+};
+
 struct ivi_panel_surface {
        struct ivi_output *output;
        enum agl_shell_edge edge;
@@ -229,6 +241,7 @@ struct ivi_surface {
                struct ivi_popup_surface popup;
                struct ivi_fullscreen_surface fullscreen;
                struct ivi_split_surface split;
+               struct ivi_remote_surface remote;
        };
 };
 
index 3fa4132..306ad6e 100644 (file)
@@ -1175,6 +1175,7 @@ int main(int argc, char *argv[])
        wl_list_init(&ivi.popup_pending_apps);
        wl_list_init(&ivi.fullscreen_pending_apps);
        wl_list_init(&ivi.split_pending_apps);
+       wl_list_init(&ivi.remote_pending_apps);
        wl_list_init(&ivi.desktop_clients);
 
        /* Prevent any clients we spawn getting our stdin */
index 687094a..37ceb25 100644 (file)
@@ -86,6 +86,19 @@ ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface)
        wl_list_insert(&ivi->surfaces, &surface->link);
 }
 
+static void
+ivi_set_desktop_surface_remote(struct ivi_surface *surface)
+{
+       struct ivi_compositor *ivi = surface->ivi;
+       assert(surface->role == IVI_SURFACE_ROLE_NONE);
+
+       /* remote type are the same as desktop just that client can tell
+        * the compositor to start on another output */
+       surface->role = IVI_SURFACE_ROLE_REMOTE;
+       wl_list_insert(&ivi->surfaces, &surface->link);
+}
+
+
 static void
 ivi_set_desktop_surface_split(struct ivi_surface *surface)
 {
@@ -165,6 +178,24 @@ ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput,
        wl_list_insert(&ivi->split_pending_apps, &split->link);
 }
 
+static void
+ivi_set_pending_desktop_surface_remote(struct ivi_output *ioutput,
+               const char *app_id)
+{
+       struct ivi_compositor *ivi = ioutput->ivi;
+       size_t len_app_id = strlen(app_id);
+
+       struct pending_remote *remote = zalloc(sizeof(*remote));
+
+       remote->app_id = zalloc(sizeof(char) * (len_app_id + 1));
+       memcpy(remote->app_id, app_id, len_app_id);
+
+       remote->ioutput = ioutput;
+
+       wl_list_insert(&ivi->remote_pending_apps, &remote->link);
+}
+
+
 static void
 ivi_remove_pending_desktop_surface_split(struct pending_split *split)
 {
@@ -189,6 +220,14 @@ ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup)
        free(p_popup);
 }
 
+static void
+ivi_remove_pending_desktop_surface_remote(struct pending_remote *remote)
+{
+       free(remote->app_id);
+       wl_list_remove(&remote->link);
+       free(remote);
+}
+
 static bool
 ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface)
 {
@@ -261,6 +300,30 @@ ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface)
        return false;
 }
 
+static bool
+ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface)
+{
+       struct pending_remote *remote_surf, *next_remote_surf;
+       struct ivi_compositor *ivi = surface->ivi;
+       const char *_app_id =
+               weston_desktop_surface_get_app_id(surface->dsurface);
+
+       if (wl_list_empty(&ivi->remote_pending_apps))
+               return false;
+
+       wl_list_for_each_safe(remote_surf, next_remote_surf,
+                             &ivi->remote_pending_apps, link) {
+               if (!strcmp(_app_id, remote_surf->app_id)) {
+                       surface->remote.output = remote_surf->ioutput;
+                       ivi_remove_pending_desktop_surface_remote(remote_surf);
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+
 void
 ivi_check_pending_desktop_surface(struct ivi_surface *surface)
 {
@@ -284,6 +347,12 @@ ivi_check_pending_desktop_surface(struct ivi_surface *surface)
                return;
        }
 
+       ret = ivi_check_pending_desktop_surface_remote(surface);
+       if (ret) {
+               ivi_set_desktop_surface_remote(surface);
+               return;
+       }
+
        /* if we end up here means we have a regular desktop app and
         * try to activate it */
        ivi_set_desktop_surface(surface);
@@ -767,6 +836,9 @@ shell_desktop_set_app_property(struct wl_client *client,
        case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL:
                ivi_set_pending_desktop_surface_split(output, app_id, role);
                break;
+       case AGL_SHELL_DESKTOP_APP_ROLE_REMOTE:
+               ivi_set_pending_desktop_surface_remote(output, app_id);
+               break;
        default:
                break;
        }