From 5eb28d6f34b19c6a6b4f8ac70ce4673f55ac21d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 7 Nov 2025 22:25:37 +0100 Subject: [PATCH 1/2] seat: Destroy seat views before cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Destroy a seat view invokes `phoc_cursor_set_mode` so we need to do that first. We can't use `g_clear_pointer` as that seats the given pointer to `NULL` before invoking the free func. This breaks fails as `seat_view_destroy` still accesses `priv->views`. As `phoc_seat_handle_destroy` does the same we need to guard against double cleanup. We'll disentangle that further when looking at multiple seats. Signed-off-by: Guido Günther Part-of: --- src/seat.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/seat.c b/src/seat.c index 2ec77c7c7..b1a2f8249 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); -- GitLab From 9952dc6b795a8329cac43af852682b2e0375f164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 7 Nov 2025 22:02:25 +0100 Subject: [PATCH 2/2] server: Kill spawned child gracefully MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far we just went away. Instead pass the `SIGTERM` on to the child so it can clean up. On 2nd `SIGTERM` we exit gracefully. Signed-off-by: Guido Günther Part-of: --- src/server.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/server.c b/src/server.c index 1b80a4442..08326c760 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); -- GitLab