diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h index c2a47cd2..a591873a 100644 --- a/ivi-shell/ivi-layout-export.h +++ b/ivi-shell/ivi-layout-export.h @@ -587,6 +587,20 @@ struct ivi_layout_interface { */ int32_t (*screen_remove_layer)(struct weston_output *output, struct ivi_layout_layer *removelayer); + + /** + * \brief Add a shell destroy listener only once. + * + * The begining of shell destroying, this signal is emitted + * to the listening controller plugins. + * The null pointer sent as the void *data argument + * to the wl_listener::notify callback function of the listener. + * + * \return IVI_SUCCEEDED if the method call was successful + * \return IVI_FAILED if the method call was failed + */ + int32_t (*shell_add_destroy_listener_once)(struct wl_listener *listener, + wl_notify_func_t destroy_handler); }; static inline const struct ivi_layout_interface * diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h index 7aef4158..0e0e0146 100644 --- a/ivi-shell/ivi-layout-private.h +++ b/ivi-shell/ivi-layout-private.h @@ -99,6 +99,10 @@ struct ivi_layout { struct wl_list screen_list; /* ivi_layout_screen::link */ struct wl_list view_list; /* ivi_layout_view::link */ + struct { + struct wl_signal destroy_signal; + } shell_notification; + struct { struct wl_signal created; struct wl_signal removed; diff --git a/ivi-shell/ivi-layout-shell.h b/ivi-shell/ivi-layout-shell.h index 1c10a8ba..ee275162 100644 --- a/ivi-shell/ivi-layout-shell.h +++ b/ivi-shell/ivi-layout-shell.h @@ -68,4 +68,7 @@ int load_controller_modules(struct weston_compositor *compositor, const char *modules, int *argc, char *argv[]); +void +ivi_layout_ivi_shell_destroy(void); + #endif /* IVI_LAYOUT_SHELL_H */ diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c index 0364ac12..fbbaa3bb 100644 --- a/ivi-shell/ivi-layout.c +++ b/ivi-shell/ivi-layout.c @@ -70,6 +70,7 @@ #include "shared/helpers.h" #include "shared/os-compatibility.h" +#include "shared/signal.h" #define max(a, b) ((a) > (b) ? (a) : (b)) @@ -1034,6 +1035,23 @@ ivi_layout_add_listener_configure_desktop_surface(struct wl_listener *listener) return IVI_SUCCEEDED; } +static int32_t +ivi_layout_shell_add_destroy_listener_once(struct wl_listener *listener, wl_notify_func_t destroy_handler) +{ + struct ivi_layout *layout = get_instance(); + if (!listener || !destroy_handler) { + weston_log("ivi_layout_shell_add_destroy_listener_once: invalid argument\n"); + return IVI_FAILED; + } + + if (wl_signal_get(&layout->shell_notification.destroy_signal, destroy_handler)) + return IVI_FAILED; + + listener->notify = destroy_handler; + wl_signal_add(&layout->shell_notification.destroy_signal, listener); + return IVI_SUCCEEDED; +} + uint32_t ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf) { @@ -2064,6 +2082,15 @@ ivi_layout_surface_create(struct weston_surface *wl_surface, return ivisurf; } +void +ivi_layout_ivi_shell_destroy(void) +{ + struct ivi_layout *layout = get_instance(); + + /* emit callback which is set by ivi-layout api user */ + weston_signal_emit_mutable(&layout->shell_notification.destroy_signal, NULL); +} + static struct ivi_layout_interface ivi_layout_interface; void @@ -2086,6 +2113,8 @@ ivi_layout_init_with_compositor(struct weston_compositor *ec) wl_signal_init(&layout->surface_notification.configure_changed); wl_signal_init(&layout->surface_notification.configure_desktop_changed); + wl_signal_init(&layout->shell_notification.destroy_signal); + /* Add layout_layer at the last of weston_compositor.layer_list */ weston_layer_init(&layout->layout_layer, ec); weston_layer_set_position(&layout->layout_layer, @@ -2190,4 +2219,9 @@ static struct ivi_layout_interface ivi_layout_interface = { */ .surface_get_size = ivi_layout_surface_get_size, .surface_dump = ivi_layout_surface_dump, + + /** + * shell interfaces + */ + .shell_add_destroy_listener_once = ivi_layout_shell_add_destroy_listener_once, }; diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c index 4044db01..4a1b6c78 100644 --- a/ivi-shell/ivi-shell.c +++ b/ivi-shell/ivi-shell.c @@ -349,6 +349,8 @@ shell_destroy(struct wl_listener *listener, void *data) container_of(listener, struct ivi_shell, destroy_listener); struct ivi_shell_surface *ivisurf, *next; + ivi_layout_ivi_shell_destroy(); + wl_list_remove(&shell->destroy_listener.link); wl_list_remove(&shell->wake_listener.link); diff --git a/ivi-shell/meson.build b/ivi-shell/meson.build index 8e064fb7..13f990da 100644 --- a/ivi-shell/meson.build +++ b/ivi-shell/meson.build @@ -15,7 +15,8 @@ if get_option('shell-ivi') dependencies: [ dep_libm, dep_libexec_weston, - dep_libweston_public + dep_libweston_public, + dep_libshared ], name_prefix: '', install: true,