diff options
-rw-r--r-- | protocol/agl-shell-desktop.xml | 1 | ||||
-rw-r--r-- | src/desktop.c | 1 | ||||
-rw-r--r-- | src/ivi-compositor.h | 13 | ||||
-rw-r--r-- | src/layout.c | 86 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/shell.c | 69 |
6 files changed, 143 insertions, 28 deletions
diff --git a/protocol/agl-shell-desktop.xml b/protocol/agl-shell-desktop.xml index 9ef4cca..4f942f5 100644 --- a/protocol/agl-shell-desktop.xml +++ b/protocol/agl-shell-desktop.xml @@ -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"> diff --git a/src/desktop.c b/src/desktop.c index 211c7e2..cf97a52 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -168,6 +168,7 @@ desktop_committed(struct weston_desktop_surface *dsurface, switch (surface->role) { case IVI_SURFACE_ROLE_DESKTOP: + case IVI_SURFACE_ROLE_REMOTE: ivi_layout_desktop_committed(surface); break; case IVI_SURFACE_ROLE_PANEL: diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index f8f2780..e12b454 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -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_FS, 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; @@ -191,6 +199,10 @@ struct ivi_fs_surface { struct ivi_output *output; }; +struct ivi_remote_surface { + struct ivi_output *output; +}; + struct ivi_split_surface { struct ivi_output *output; uint32_t orientation; @@ -229,6 +241,7 @@ struct ivi_surface { struct ivi_popup_surface popup; struct ivi_fs_surface fs; struct ivi_split_surface split; + struct ivi_remote_surface remote; }; }; diff --git a/src/layout.c b/src/layout.c index fd01c5b..872a548 100644 --- a/src/layout.c +++ b/src/layout.c @@ -216,6 +216,7 @@ ivi_layout_activate_complete(struct ivi_output *output, /* force repaint of the entire output */ weston_output_damage(output->output); + surf->desktop.last_output = surf->desktop.pending_output; surf->desktop.pending_output = NULL; } @@ -234,19 +235,48 @@ ivi_layout_find_bg_output(struct ivi_compositor *ivi) return NULL; } +static struct ivi_output * +ivi_layout_get_output_from_surface(struct ivi_surface *surf) +{ + struct ivi_output *ivi_output = NULL; + + switch (surf->role) { + case IVI_SURFACE_ROLE_DESKTOP: + if (surf->desktop.pending_output) + ivi_output = surf->desktop.pending_output; + else + ivi_output = surf->desktop.last_output; + break; + case IVI_SURFACE_ROLE_POPUP: + ivi_output = surf->popup.output; + break; + case IVI_SURFACE_ROLE_REMOTE: + ivi_output = surf->remote.output; + break; + default: + case IVI_SURFACE_ROLE_BACKGROUND: + case IVI_SURFACE_ROLE_PANEL: + case IVI_SURFACE_ROLE_NONE: + break; + } + + return ivi_output; +} + void ivi_layout_desktop_committed(struct ivi_surface *surf) { struct weston_desktop_surface *dsurf = surf->dsurface; struct weston_geometry geom = weston_desktop_surface_get_geometry(dsurf); struct ivi_output *output; + struct ivi_policy *policy = surf->ivi->policy; - assert(surf->role == IVI_SURFACE_ROLE_DESKTOP); + assert(surf->role == IVI_SURFACE_ROLE_DESKTOP || + surf->role == IVI_SURFACE_ROLE_REMOTE); - output = surf->desktop.pending_output; + output = ivi_layout_get_output_from_surface(surf); if (!output) { struct ivi_output *ivi_bg_output; - struct ivi_policy *policy = surf->ivi->policy; if (policy && policy->api.surface_activate_by_default) if (policy->api.surface_activate_by_default(surf, surf->ivi)) @@ -276,6 +306,30 @@ skip_config_check: return; } + if (surf->role == IVI_SURFACE_ROLE_REMOTE && output) { + const char *app_id; + + if (policy && policy->api.surface_activate_by_default && + !policy->api.surface_activate_by_default(surf, surf->ivi)) + return; + + app_id = weston_desktop_surface_get_app_id(dsurf); + if (app_id) { + ivi_layout_activate(output, app_id); + + /* we transition to the desktop role from remote one, + * as they're basically one and the same, but in order + * to keep the same functionality (that is to display + * it by default when starting), we need to know the + * output before hand, fact that that is not true for, + * regular desktop ones. + */ + surf->role = IVI_SURFACE_ROLE_DESKTOP; + surf->activated_by_default = true; + } + return; + } + if (!weston_desktop_surface_get_maximized(dsurf) || geom.width != output->area.width || geom.height != output->area.height) @@ -321,6 +375,7 @@ ivi_layout_fs_committed(struct ivi_surface *surface) surface->view->is_mapped = true; } + void ivi_layout_desktop_resize(struct ivi_surface *surface, struct weston_geometry area) @@ -636,31 +691,6 @@ ivi_layout_activate(struct ivi_output *output, const char *app_id) } } -static struct ivi_output * -ivi_layout_get_output_from_surface(struct ivi_surface *surf) -{ - struct ivi_output *ivi_output = NULL; - - switch (surf->role) { - case IVI_SURFACE_ROLE_DESKTOP: - if (surf->desktop.pending_output) - ivi_output = surf->desktop.pending_output; - else - ivi_output = surf->desktop.last_output; - break; - case IVI_SURFACE_ROLE_POPUP: - ivi_output = surf->popup.output; - break; - default: - case IVI_SURFACE_ROLE_BACKGROUND: - case IVI_SURFACE_ROLE_PANEL: - case IVI_SURFACE_ROLE_NONE: - break; - } - - return ivi_output; -} - void ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id) { @@ -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 */ diff --git a/src/shell.c b/src/shell.c index cb70691..3205804 100644 --- a/src/shell.c +++ b/src/shell.c @@ -87,6 +87,18 @@ ivi_set_desktop_surface_fs(struct ivi_surface *surface) } 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) { struct ivi_compositor *ivi = surface->ivi; @@ -166,6 +178,23 @@ ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput, } 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) { free(split->app_id); @@ -189,6 +218,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 +298,29 @@ ivi_check_pending_desktop_surface_fs(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 +344,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 +833,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; } |