diff --git a/src/seat.c b/src/seat.c index 2ec77c7c7db22e0c18ed5e551b7052c40ea99870..b1a2f8249cf08cb5bc146eacb0091b13e19f1f71 100644 --- a/src/seat.c +++ b/src/seat.c @@ -726,19 +726,29 @@ phoc_seat_handle_request_set_primary_selection (struct wl_listener *listener, vo static void seat_view_destroy (PhocSeatView *seat_view); + +static void +phoc_seat_seat_views_destroy (PhocSeat *self) +{ + PhocSeatPrivate *priv = phoc_seat_get_instance_private (self); + + if (priv->views) { + g_queue_free_full (priv->views, (GDestroyNotify)seat_view_destroy); + priv->views = NULL; + } +} + + static void phoc_seat_handle_destroy (struct wl_listener *listener, void *data) { PhocSeat *self = wl_container_of (listener, self, destroy); - PhocSeatPrivate *priv = phoc_seat_get_instance_private (self); // TODO: probably more to be freed here wl_list_remove (&self->destroy.link); phoc_input_method_relay_destroy (&self->im_relay); - - g_queue_free_full (priv->views, (GDestroyNotify)seat_view_destroy); - priv->views = NULL; + phoc_seat_seat_views_destroy (self); } @@ -1855,6 +1865,7 @@ phoc_seat_dispose (GObject *object) PhocSeat *self = PHOC_SEAT (object); PhocSeatPrivate *priv = phoc_seat_get_instance_private (self); + phoc_seat_seat_views_destroy (self); g_clear_object (&priv->device_state); g_clear_object (&self->cursor); diff --git a/src/server.c b/src/server.c index 1b80a4442f3cac6b60268fea62d0940f4e5cc833..08326c7600b8ecc8aee7e79905ebf426e32c1495 100644 --- a/src/server.c +++ b/src/server.c @@ -20,6 +20,8 @@ #include +#include + #include #include #include @@ -66,6 +68,7 @@ typedef struct _PhocServer { PhocDesktop *desktop; gchar *session_exec; + GPid session_pid; gint exit_status; GMainLoop *mainloop; @@ -85,6 +88,7 @@ typedef struct _PhocServer { struct wlr_data_device_manager *data_device_manager; struct wl_listener new_surface; + } PhocServer; static void phoc_server_initable_iface_init (GInitableIface *iface); @@ -98,6 +102,27 @@ typedef struct { } WaylandEventSource; +static gboolean +on_shutdown_signal (gpointer user_data) +{ + static gboolean signal_sent; + PhocServer *self = PHOC_SERVER (user_data); + + g_return_val_if_fail (self->session_pid > 0, FALSE); + + if (!signal_sent) { + g_debug ("Ending session via SIGTERM"); + kill (self->session_pid, SIGTERM); + signal_sent = TRUE; + return TRUE; + } + + g_warning ("Received 2nd SIGTERM, quitting."); + g_main_loop_quit (self->mainloop); + return FALSE; +} + + static gboolean wayland_event_source_prepare (GSource *base, int *timeout) @@ -221,6 +246,8 @@ phoc_startup_session_in_idle (gpointer data) G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, on_child_setup, self, &pid, &err)) { g_child_watch_add (pid, (GChildWatchFunc)on_session_exit, self); + self->session_pid = pid; + g_unix_signal_add (SIGTERM, on_shutdown_signal, self); } else { g_critical ("Failed to launch session: %s", err->message); g_main_loop_quit (self->mainloop);