aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--protocol/agl-shell-desktop.xml1
-rw-r--r--src/desktop.c1
-rw-r--r--src/ivi-compositor.h13
-rw-r--r--src/layout.c86
-rw-r--r--src/main.c1
-rw-r--r--src/shell.c69
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)
{
diff --git a/src/main.c b/src/main.c
index 3fa4132..306ad6e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}