summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2020-04-29 17:14:58 +0300
committerMarius Vlad <marius.vlad@collabora.com>2020-06-08 17:26:36 +0300
commitedbfbad7344c4de62cbf5a4a5c8935afa50d8b4a (patch)
tree41290558d79630da21dc1d7644f6f70dbebfe7ca
parentf73edbcf826fcc46dcc692f8f8b7802e4f053a0f (diff)
shell: Introduce fullscreen and split role type of a surface
With it, this also adds two pending lists, for each role type and aggregates the checks used to compare against the roles type when the surface is being created. There's no functional at this stage. Bug-AGL: SPEC-3334 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I1900399fe35d9dbc26a93c374ac2f86efa860ba6
-rw-r--r--protocol/agl-shell-desktop.xml2
-rw-r--r--src/desktop.c5
-rw-r--r--src/ivi-compositor.h34
-rw-r--r--src/main.c2
-rw-r--r--src/shell.c176
5 files changed, 206 insertions, 13 deletions
diff --git a/protocol/agl-shell-desktop.xml b/protocol/agl-shell-desktop.xml
index 05a3725..9ef4cca 100644
--- a/protocol/agl-shell-desktop.xml
+++ b/protocol/agl-shell-desktop.xml
@@ -35,6 +35,8 @@
<enum name="app_role">
<entry name="popup" value="0"/>
<entry name="fullscreen" value="1"/>
+ <entry name="split_vertical" value="2"/>
+ <entry name="split_horizontal" value="3"/>
</enum>
<enum name="app_state">
diff --git a/src/desktop.c b/src/desktop.c
index 07680b9..2ef6fee 100644
--- a/src/desktop.c
+++ b/src/desktop.c
@@ -93,10 +93,7 @@ desktop_surface_added(struct weston_desktop_surface *dsurface, void *userdata)
weston_desktop_surface_set_user_data(dsurface, surface);
if (ivi->shell_client.ready) {
- if (ivi_check_pending_desktop_surface_popup(surface))
- ivi_set_desktop_surface_popup(surface);
- else
- ivi_set_desktop_surface(surface);
+ ivi_check_pending_desktop_surface(surface);
} else {
/*
* We delay creating "normal" desktop surfaces until later, to
diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h
index 91b5340..3c547aa 100644
--- a/src/ivi-compositor.h
+++ b/src/ivi-compositor.h
@@ -89,6 +89,8 @@ struct ivi_compositor {
struct wl_list pending_surfaces;
struct wl_list popup_pending_apps;
+ struct wl_list fullscreen_pending_apps;
+ struct wl_list split_pending_apps;
struct weston_layer hidden;
struct weston_layer background;
@@ -143,6 +145,9 @@ enum ivi_surface_role {
IVI_SURFACE_ROLE_BACKGROUND,
IVI_SURFACE_ROLE_PANEL,
IVI_SURFACE_ROLE_POPUP,
+ IVI_SURFACE_ROLE_FULLSCREEN,
+ IVI_SURFACE_ROLE_SPLIT_V,
+ IVI_SURFACE_ROLE_SPLIT_H,
};
struct pending_popup {
@@ -153,6 +158,19 @@ struct pending_popup {
struct wl_list link; /** ivi_compositor::popup_pending_surfaces */
};
+struct pending_fullscreen {
+ struct ivi_output *ioutput;
+ char *app_id;
+ struct wl_list link; /** ivi_compositor::fullscreen_pending_apps */
+};
+
+struct pending_split {
+ struct ivi_output *ioutput;
+ char *app_id;
+ uint32_t orientation;
+ struct wl_list link; /** ivi_compositor::split_pending_apps */
+};
+
struct ivi_desktop_surface {
struct ivi_output *pending_output;
struct ivi_output *last_output;
@@ -168,6 +186,15 @@ struct ivi_popup_surface {
int y;
};
+struct ivi_fullscreen_surface {
+ struct ivi_output *output;
+};
+
+struct ivi_split_surface {
+ struct ivi_output *output;
+ uint32_t orientation;
+};
+
struct ivi_panel_surface {
struct ivi_output *output;
enum agl_shell_edge edge;
@@ -199,6 +226,8 @@ struct ivi_surface {
struct ivi_background_surface bg;
struct ivi_panel_surface panel;
struct ivi_popup_surface popup;
+ struct ivi_fullscreen_surface fullscreen;
+ struct ivi_split_surface split;
};
};
@@ -253,11 +282,8 @@ ivi_set_desktop_surface(struct ivi_surface *surface);
/*
* removes the pending popup one
*/
-bool
-ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface);
-
void
-ivi_set_desktop_surface_popup(struct ivi_surface *surface);
+ivi_check_pending_desktop_surface(struct ivi_surface *surface);
void
ivi_reflow_outputs(struct ivi_compositor *ivi);
diff --git a/src/main.c b/src/main.c
index 2764d4b..3fa4132 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1173,6 +1173,8 @@ int main(int argc, char *argv[])
wl_list_init(&ivi.surfaces);
wl_list_init(&ivi.pending_surfaces);
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.desktop_clients);
/* Prevent any clients we spawn getting our stdin */
diff --git a/src/shell.c b/src/shell.c
index 527cdba..c132ae5 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -66,7 +66,7 @@ ivi_set_desktop_surface(struct ivi_surface *surface)
}
}
-void
+static void
ivi_set_desktop_surface_popup(struct ivi_surface *surface)
{
struct ivi_compositor *ivi = surface->ivi;
@@ -77,6 +77,30 @@ ivi_set_desktop_surface_popup(struct ivi_surface *surface)
}
static void
+ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface)
+{
+ struct ivi_compositor *ivi = surface->ivi;
+ assert(surface->role == IVI_SURFACE_ROLE_NONE);
+
+ surface->role = IVI_SURFACE_ROLE_FULLSCREEN;
+ wl_list_insert(&ivi->surfaces, &surface->link);
+}
+
+static void
+ivi_set_desktop_surface_split(struct ivi_surface *surface)
+{
+ struct ivi_compositor *ivi = surface->ivi;
+ assert(surface->role == IVI_SURFACE_ROLE_NONE);
+
+ if (surface->split.orientation == AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL)
+ surface->role = IVI_SURFACE_ROLE_SPLIT_V;
+ else
+ surface->role = IVI_SURFACE_ROLE_SPLIT_H;
+
+ wl_list_insert(&ivi->surfaces, &surface->link);
+}
+
+static void
ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput,
int x, int y, const char *app_id)
{
@@ -95,6 +119,61 @@ ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput,
}
static void
+ivi_set_pending_desktop_surface_fullscreen(struct ivi_output *ioutput,
+ const char *app_id)
+{
+ struct ivi_compositor *ivi = ioutput->ivi;
+ size_t len_app_id = strlen(app_id);
+
+ struct pending_fullscreen *fs = zalloc(sizeof(*fs));
+
+ fs->app_id = zalloc(sizeof(char) * (len_app_id + 1));
+ memcpy(fs->app_id, app_id, len_app_id);
+
+ fs->ioutput = ioutput;
+
+ wl_list_insert(&ivi->fullscreen_pending_apps, &fs->link);
+}
+
+static void
+ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput,
+ const char *app_id, uint32_t orientation)
+{
+ struct ivi_compositor *ivi = ioutput->ivi;
+ size_t len_app_id = strlen(app_id);
+
+ if (orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL &&
+ orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL)
+ return;
+
+ struct pending_split *split = zalloc(sizeof(*split));
+
+ split->app_id = zalloc(sizeof(char) * (len_app_id + 1));
+ memcpy(split->app_id, app_id, len_app_id);
+
+ split->ioutput = ioutput;
+ split->orientation = orientation;
+
+ wl_list_insert(&ivi->split_pending_apps, &split->link);
+}
+
+static void
+ivi_remove_pending_desktop_surface_split(struct pending_split *split)
+{
+ free(split->app_id);
+ wl_list_remove(&split->link);
+ free(split);
+}
+
+static void
+ivi_remove_pending_desktop_surface_fullscreen(struct pending_fullscreen *fs)
+{
+ free(fs->app_id);
+ wl_list_remove(&fs->link);
+ free(fs);
+}
+
+static void
ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup)
{
free(p_popup->app_id);
@@ -102,7 +181,7 @@ ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup)
free(p_popup);
}
-bool
+static bool
ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface)
{
struct ivi_compositor *ivi = surface->ivi;
@@ -110,13 +189,15 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface)
const char *_app_id =
weston_desktop_surface_get_app_id(surface->dsurface);
+ if (wl_list_empty(&ivi->popup_pending_apps))
+ return false;
+
wl_list_for_each_safe(p_popup, next_p_popup,
&ivi->popup_pending_apps, link) {
if (!strcmp(_app_id, p_popup->app_id)) {
surface->popup.output = p_popup->ioutput;
surface->popup.x = p_popup->x;
surface->popup.y = p_popup->y;
-
ivi_remove_pending_desktop_surface_popup(p_popup);
return true;
}
@@ -125,6 +206,80 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface)
return false;
}
+static bool
+ivi_check_pending_desktop_surface_split(struct ivi_surface *surface)
+{
+ struct pending_split *split_surf, *next_split_surf;
+ struct ivi_compositor *ivi = surface->ivi;
+ const char *_app_id =
+ weston_desktop_surface_get_app_id(surface->dsurface);
+
+ if (wl_list_empty(&ivi->split_pending_apps))
+ return false;
+
+ wl_list_for_each_safe(split_surf, next_split_surf,
+ &ivi->split_pending_apps, link) {
+ if (!strcmp(_app_id, split_surf->app_id)) {
+ surface->split.output = split_surf->ioutput;
+ surface->split.orientation = split_surf->orientation;
+ ivi_remove_pending_desktop_surface_split(split_surf);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool
+ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface)
+{
+ struct pending_fullscreen *fs_surf, *next_fs_surf;
+ struct ivi_compositor *ivi = surface->ivi;
+ const char *_app_id =
+ weston_desktop_surface_get_app_id(surface->dsurface);
+
+ if (wl_list_empty(&ivi->fullscreen_pending_apps))
+ return false;
+
+ wl_list_for_each_safe(fs_surf, next_fs_surf,
+ &ivi->fullscreen_pending_apps, link) {
+ if (!strcmp(_app_id, fs_surf->app_id)) {
+ surface->fullscreen.output = fs_surf->ioutput;
+ ivi_remove_pending_desktop_surface_fullscreen(fs_surf);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+ivi_check_pending_desktop_surface(struct ivi_surface *surface)
+{
+ bool ret = false;
+
+ ret = ivi_check_pending_desktop_surface_popup(surface);
+ if (ret) {
+ ivi_set_desktop_surface_popup(surface);
+ return;
+ }
+
+ ret = ivi_check_pending_desktop_surface_split(surface);
+ if (ret) {
+ ivi_set_desktop_surface_split(surface);
+ return;
+ }
+
+ ret = ivi_check_pending_desktop_surface_fullscreen(surface);
+ if (ret) {
+ ivi_set_desktop_surface_fullscreen(surface);
+ return;
+ }
+
+ /* if we end up here means we have a regular desktop app */
+ ivi_set_desktop_surface(surface);
+}
+
void
ivi_shell_init_black_fs(struct ivi_compositor *ivi)
{
@@ -597,9 +752,20 @@ shell_desktop_set_app_property(struct wl_client *client,
struct weston_output *woutput = weston_head_get_output(head);
struct ivi_output *output = to_ivi_output(woutput);
- /* temporary store the app_id such that, when created to be check against */
- if (role == AGL_SHELL_DESKTOP_APP_ROLE_POPUP)
+ switch (role) {
+ case AGL_SHELL_DESKTOP_APP_ROLE_POPUP:
ivi_set_pending_desktop_surface_popup(output, x, y, app_id);
+ break;
+ case AGL_SHELL_DESKTOP_APP_ROLE_FULLSCREEN:
+ ivi_set_pending_desktop_surface_fullscreen(output, app_id);
+ break;
+ case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL:
+ case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL:
+ ivi_set_pending_desktop_surface_split(output, app_id, role);
+ break;
+ default:
+ break;
+ }
}
static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = {