summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2020-02-06 15:25:54 +0200
committerMarius Vlad <marius.vlad@collabora.com>2020-02-07 13:13:09 +0200
commitb43a012824af0165f3716c7986888213420885aa (patch)
tree4b5b9f8e921f7bc3c5384002b0b539cf1bb652af
parent433edac095bb142e6024314e39409afacbfaa5c2 (diff)
shell: Add a black surface in the fullscreen layer
Now that we're capable of restarting the client shell without the need to restart the compositor, create a black surface and insert in the fullscreen layer as to denote that the client shell is no longer running. This black surface is removed when the 'ready' request is received and inserted back when the client shell unbinds from the agl-shell protocol. Also, we were missing implementation protocol specification as the presentation delay required a black surface being displayed instead, so this brings the implementation closer to that of the protocol specification. Bug-SPEC: SPEC-3161 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I40f01135583eea8af78d3077cdad97ad5ad450f5
-rw-r--r--src/ivi-compositor.h9
-rw-r--r--src/main.c2
-rw-r--r--src/shell.c102
3 files changed, 112 insertions, 1 deletions
diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h
index 3d7bd25..5d210fb 100644
--- a/src/ivi-compositor.h
+++ b/src/ivi-compositor.h
@@ -103,6 +103,12 @@ struct ivi_output {
struct ivi_surface *left;
struct ivi_surface *right;
+ /* for the black surface */
+ struct fullscreen_view {
+ struct ivi_surface *fs;
+ struct wl_listener fs_destroy;
+ } fullscreen_view;
+
struct wl_listener output_destroy;
/*
@@ -193,6 +199,9 @@ ivi_agl_systemd_notify(struct ivi_compositor *ivi)
int
ivi_shell_init(struct ivi_compositor *ivi);
+void
+ivi_shell_init_black_fs(struct ivi_compositor *ivi);
+
int
ivi_shell_create_global(struct ivi_compositor *ivi);
diff --git a/src/main.c b/src/main.c
index 240fb77..54de038 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1209,6 +1209,8 @@ int main(int argc, char *argv[])
weston_compositor_flush_heads_changed(ivi.compositor);
+ ivi_shell_init_black_fs(&ivi);
+
if (create_listening_socket(display, socket_name) < 0)
goto error_compositor;
diff --git a/src/shell.c b/src/shell.c
index 6a1596e..16b4146 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -40,6 +40,12 @@
#include "agl-shell-server-protocol.h"
+static void
+create_black_surface_view(struct ivi_output *output);
+
+static void
+insert_black_surface(struct ivi_output *output);
+
void
ivi_set_desktop_surface(struct ivi_surface *surface)
{
@@ -49,6 +55,17 @@ ivi_set_desktop_surface(struct ivi_surface *surface)
wl_list_insert(&surface->ivi->surfaces, &surface->link);
}
+void
+ivi_shell_init_black_fs(struct ivi_compositor *ivi)
+{
+ struct ivi_output *out;
+
+ wl_list_for_each(out, &ivi->outputs, link) {
+ create_black_surface_view(out);
+ insert_black_surface(out);
+ }
+}
+
int
ivi_shell_init(struct ivi_compositor *ivi)
{
@@ -168,6 +185,87 @@ ivi_launch_shell_client(struct ivi_compositor *ivi)
}
static void
+destroy_black_view(struct wl_listener *listener, void *data)
+{
+ struct fullscreen_view *fs =
+ wl_container_of(listener, fs, fs_destroy);
+
+
+ if (fs && fs->fs) {
+ if (fs->fs->view && fs->fs->view->surface) {
+ weston_surface_destroy(fs->fs->view->surface);
+ fs->fs->view = NULL;
+ }
+
+ free(fs->fs);
+ wl_list_remove(&fs->fs_destroy.link);
+ }
+}
+
+
+static void
+create_black_surface_view(struct ivi_output *output)
+{
+ struct weston_surface *surface = NULL;
+ struct weston_view *view;
+ struct ivi_compositor *ivi = output->ivi;
+ struct weston_compositor *wc= ivi->compositor;
+ struct weston_output *woutput = output->output;
+
+ surface = weston_surface_create(wc);
+ view = weston_view_create(surface);
+
+ assert(view || surface);
+
+ weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
+ weston_surface_set_size(surface, woutput->width, woutput->height);
+ weston_view_set_position(view, woutput->x, woutput->y);
+
+ output->fullscreen_view.fs = zalloc(sizeof(struct ivi_surface));
+ output->fullscreen_view.fs->view = view;
+
+ output->fullscreen_view.fs_destroy.notify = destroy_black_view;
+ wl_signal_add(&woutput->destroy_signal,
+ &output->fullscreen_view.fs_destroy);
+}
+
+static void
+remove_black_surface(struct ivi_output *output)
+{
+ struct weston_view *view = output->fullscreen_view.fs->view;
+
+ assert(view->is_mapped == true ||
+ view->surface->is_mapped == true);
+
+ view->is_mapped = false;
+ view->surface->is_mapped = false;
+
+ weston_layer_entry_remove(&view->layer_link);
+ weston_view_update_transform(view);
+
+ weston_output_damage(output->output);
+}
+
+static void
+insert_black_surface(struct ivi_output *output)
+{
+ struct weston_view *view = output->fullscreen_view.fs->view;
+
+ if (view->is_mapped || view->surface->is_mapped)
+ return;
+
+ weston_layer_entry_remove(&view->layer_link);
+ weston_layer_entry_insert(&output->ivi->fullscreen.view_list,
+ &view->layer_link);
+
+ view->is_mapped = true;
+ view->surface->is_mapped = true;
+
+ weston_view_update_transform(view);
+ weston_output_damage(output->output);
+}
+
+static void
shell_ready(struct wl_client *client, struct wl_resource *shell_res)
{
struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res);
@@ -179,9 +277,9 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res)
return;
ivi->shell_client.ready = true;
- /* TODO: Create a black screen and remove it here */
wl_list_for_each(output, &ivi->outputs, link) {
+ remove_black_surface(output);
ivi_layout_init(ivi, output);
}
@@ -373,6 +471,8 @@ unbind_agl_shell(struct wl_resource *resource)
weston_layer_entry_remove(&output->active->view->layer_link);
output->active = NULL;
}
+
+ insert_black_surface(output);
}
wl_list_for_each_safe(surf, surf_tmp, &ivi->surfaces, link) {