From 28ec0cff16d62260fb1a5900f57353f48446e199 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Wed, 15 Feb 2023 17:02:28 +0200 Subject: [PATCH] compositor: Added layout_save/layout_restore In order to send correct dimensions after a hot-plug event, we need to be able to save the area we had before. Note that implies that the connectors do not change names in between hot-plugs, which normally doesn't happen, but it might if udev rules are executed/invoked. We restore based on output name it had previously. Bug-AGL: SPEC-4705 Signed-off-by: Marius Vlad Change-Id: Ice3a127edfc9d356830ba8f0d0a20bb86284d7de --- src/compositor.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/desktop.c | 1 + src/ivi-compositor.h | 4 +++ 3 files changed, 99 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index b97ad79..60d5dd2 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -79,6 +79,95 @@ sigint_helper(int sig) raise(SIGUSR2); } +void +ivi_layout_save(struct ivi_compositor *ivi, struct ivi_output *output) +{ + struct ivi_output *new_output; + ivi->need_ivi_output_relayout = true; + + new_output = zalloc(sizeof(*new_output)); + + new_output->ivi = ivi; + new_output->background = output->background; + + new_output->top = output->top; + new_output->bottom = output->bottom; + new_output->left = output->left; + new_output->right = output->right; + + new_output->active = output->active; + new_output->previous_active = output->previous_active; + new_output->name = strdup(output->name); + if (output->app_ids) + new_output->app_ids = strdup(output->app_ids); + + new_output->area = output->area; + new_output->area_saved = output->area_saved; + new_output->area_activation = output->area_activation; + + weston_log("saving output layout for output %s\n", new_output->name); + + wl_list_insert(&ivi->saved_outputs, &new_output->link); +} + +void +ivi_layout_restore(struct ivi_compositor *ivi, struct ivi_output *n_output) +{ + struct ivi_output *output = NULL; + struct ivi_output *iter_output; + + if (!ivi->need_ivi_output_relayout) + return; + + ivi->need_ivi_output_relayout = false; + + wl_list_for_each(iter_output, &ivi->saved_outputs, link) { + if (strcmp(n_output->name, iter_output->name) == 0) { + output = iter_output; + break; + } + } + + if (!output) + return; + + weston_log("restoring output layout for output %s\n", output->name); + n_output->background = output->background; + + n_output->top = output->top; + n_output->bottom = output->bottom; + n_output->left = output->left; + n_output->right = output->right; + + n_output->active = output->active; + n_output->previous_active = output->previous_active; + if (output->app_ids) + n_output->app_ids = strdup(output->app_ids); + + n_output->area = output->area; + n_output->area_saved = output->area_saved; + n_output->area_activation = output->area_activation; + + free(output->app_ids); + free(output->name); + wl_list_remove(&output->link); + free(output); +} + +void +ivi_layout_destroy_saved_outputs(struct ivi_compositor *ivi) +{ + struct ivi_output *output, *output_next; + + wl_list_for_each_safe(output, output_next, &ivi->saved_outputs, link) { + free(output->app_ids); + free(output->name); + + wl_list_remove(&output->link); + free(output); + } +} + static void handle_output_destroy(struct wl_listener *listener, void *data) { @@ -93,6 +182,8 @@ handle_output_destroy(struct wl_listener *listener, void *data) output->fullscreen_view.fs->view = NULL; } + ivi_layout_save(output->ivi, output); + output->output = NULL; wl_list_remove(&output->output_destroy.link); } @@ -454,6 +545,8 @@ try_attach_enable_heads(struct ivi_output *output) for (size_t i = fail_len; i < output->add_len; ++i) add_head_destroyed_listener(output->add[i]); + ivi_layout_restore(output->ivi, output); + output->add_len = fail_len; return 0; } @@ -1688,6 +1781,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da }; wl_list_init(&ivi.outputs); + wl_list_init(&ivi.saved_outputs); wl_list_init(&ivi.surfaces); wl_list_init(&ivi.pending_surfaces); wl_list_init(&ivi.popup_pending_apps); diff --git a/src/desktop.c b/src/desktop.c index 0f1da18..eb0dc8a 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -531,6 +531,7 @@ ivi_shell_destroy(struct wl_listener *listener, void *data) ivi_shell_finalize(ivi); ivi_compositor_destroy_pending_surfaces(ivi); + ivi_layout_destroy_saved_outputs(ivi); weston_desktop_destroy(ivi->desktop); wl_list_remove(&listener->link); diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index 0ccbb52..ed56c7f 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -104,6 +104,7 @@ struct ivi_compositor { struct wl_list desktop_clients; /* desktop_client::link */ struct wl_list outputs; /* ivi_output.link */ + struct wl_list saved_outputs; /* ivi_output.link */ struct wl_list surfaces; /* ivi_surface.link */ struct weston_desktop *desktop; @@ -125,6 +126,7 @@ struct ivi_compositor { struct weston_layer popup; struct weston_layer fullscreen; + bool need_ivi_output_relayout; struct wl_list child_process_list; }; @@ -502,5 +504,7 @@ sigchld_handler(int signal_number, void *data); void shell_send_app_state(struct ivi_compositor *ivi, const char *app_id, enum agl_shell_app_state state); +void +ivi_layout_destroy_saved_outputs(struct ivi_compositor *ivi); #endif -- 2.16.6