summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2023-02-15 17:02:28 +0200
committerMarius Vlad <marius.vlad@collabora.com>2023-02-15 18:11:20 +0200
commit28ec0cff16d62260fb1a5900f57353f48446e199 (patch)
tree5030a82e8267bbffc3c74298e7d0b444907fb750
parentee50083d93869aaa581a092c522efe08252fae55 (diff)
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 <marius.vlad@collabora.com> Change-Id: Ice3a127edfc9d356830ba8f0d0a20bb86284d7de
-rw-r--r--src/compositor.c94
-rw-r--r--src/desktop.c1
-rw-r--r--src/ivi-compositor.h4
3 files changed, 99 insertions, 0 deletions
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