Add gtk_display_cleanup() to properly tear down GTK display state: remove console and mouse notifiers, unregister clipboard peer, destroy the main window and virtual consoles.
Signed-off-by: Marc-André Lureau <[email protected]> --- include/ui/gtk.h | 1 + ui/gtk-clipboard.c | 15 +++++++++++++++ ui/gtk.c | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/include/ui/gtk.h b/include/ui/gtk.h index 3e6ce3cb48c..5156a049509 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -225,6 +225,7 @@ int gd_gl_area_make_current(DisplayGLCtx *dgc, /* gtk-clipboard.c */ void gd_clipboard_init(GtkDisplayState *gd); +void gd_clipboard_cleanup(GtkDisplayState *gd); void gd_update_scale(VirtualConsole *vc, int ww, int wh, int fbw, int fbh); diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c index ea9444be70f..476e6b8303c 100644 --- a/ui/gtk-clipboard.c +++ b/ui/gtk-clipboard.c @@ -235,3 +235,18 @@ void gd_clipboard_init(GtkDisplayState *gd) g_signal_connect(gd->gtkcb[QEMU_CLIPBOARD_SELECTION_SECONDARY], "owner-change", G_CALLBACK(gd_owner_change), gd); } + +void gd_clipboard_cleanup(GtkDisplayState *gd) +{ + if (!gd->cbpeer.name) { + return; + } + qemu_clipboard_peer_unregister(&gd->cbpeer); + g_signal_handlers_disconnect_by_data( + gd->gtkcb[QEMU_CLIPBOARD_SELECTION_CLIPBOARD], gd); + g_signal_handlers_disconnect_by_data( + gd->gtkcb[QEMU_CLIPBOARD_SELECTION_PRIMARY], gd); + g_signal_handlers_disconnect_by_data( + gd->gtkcb[QEMU_CLIPBOARD_SELECTION_SECONDARY], gd); + gd->cbpeer.name = NULL; +} diff --git a/ui/gtk.c b/ui/gtk.c index 2ee826b56fb..c26dc83ac3e 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -2505,6 +2505,7 @@ static void gd_create_menus(GtkDisplayState *s, DisplayOptions *opts) } +static GtkDisplayState *gtk_display_state; static gboolean gtkinit; static void gtk_display_init(DisplayState *ds, DisplayOptions *opts) @@ -2523,6 +2524,7 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts) } assert(opts->type == DISPLAY_TYPE_GTK); s = g_malloc0(sizeof(*s)); + gtk_display_state = s; s->opts = opts; theme = gtk_icon_theme_get_default(); @@ -2681,10 +2683,26 @@ static void early_gtk_display_init(DisplayOptions *opts) #endif } +static void gtk_display_cleanup(void) +{ + GtkDisplayState *s = gtk_display_state; + + if (!s) { + return; + } + + qemu_remove_mouse_mode_change_notifier(&s->mouse_mode_notifier); + gd_clipboard_cleanup(s); + g_clear_pointer(&s->window, gtk_widget_destroy); + g_clear_object(&s->null_cursor); + g_clear_pointer(>k_display_state, g_free); +} + static QemuDisplay qemu_display_gtk = { .type = DISPLAY_TYPE_GTK, .early_init = early_gtk_display_init, .init = gtk_display_init, + .cleanup = gtk_display_cleanup, .vc = "vc", }; -- 2.54.0
