Fix switch-host migration with Spice. spice-gtk doesn't like channels staying around when they should be destroyed/finalized, ie removed from session. spice-gtk should probably learned to handle better the case of non cooperating clients, and be able to dissociate a channel from a session without waiting for it to be disposed, but for now, the relation is quite tight. --- src/virt-viewer-display-spice.c | 17 +++++++++-------- src/virt-viewer-display-spice.h | 4 +--- src/virt-viewer-session-spice.c | 11 ++++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c index f7bb26d..0b6949b 100644 --- a/src/virt-viewer-display-spice.c +++ b/src/virt-viewer-display-spice.c @@ -35,7 +35,7 @@ G_DEFINE_TYPE (VirtViewerDisplaySpice, virt_viewer_display_spice, VIRT_VIEWER_TYPE_DISPLAY) struct _VirtViewerDisplaySpicePrivate { - SpiceChannel *channel; + SpiceChannel *channel; /* weak reference */ SpiceDisplay *display; }; @@ -54,7 +54,6 @@ virt_viewer_display_spice_finalize(GObject *obj) VirtViewerDisplaySpice *spice = VIRT_VIEWER_DISPLAY_SPICE(obj); g_object_unref(spice->priv->display); - g_object_unref(spice->priv->channel); G_OBJECT_CLASS(virt_viewer_display_spice_parent_class)->finalize(obj); } @@ -199,15 +198,14 @@ enable_accel_changed(VirtViewerApp *app, GtkWidget * virt_viewer_display_spice_new(VirtViewerSessionSpice *session, - SpiceChannel *channel, - SpiceDisplay *display) + SpiceChannel *channel) { VirtViewerDisplaySpice *self; VirtViewerApp *app; gint channelid; + SpiceSession *s; g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL); - g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL); g_object_get(channel, "channel-id", &channelid, NULL); @@ -215,15 +213,18 @@ virt_viewer_display_spice_new(VirtViewerSessionSpice *session, "session", session, "nth-display", channelid, NULL); - self->priv->channel = g_object_ref(channel); - self->priv->display = g_object_ref(display); + self->priv->channel = channel; + + g_object_get(session, "spice-session", &s, NULL); + self->priv->display = spice_display_new(s, channelid); + g_object_unref(s); g_signal_connect(channel, "display-primary-create", G_CALLBACK(primary_create), self); g_signal_connect(channel, "display-mark", G_CALLBACK(display_mark), self); - gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->priv->display)); + gtk_container_add(GTK_CONTAINER(self), g_object_ref(self->priv->display)); gtk_widget_show(GTK_WIDGET(self->priv->display)); g_object_set(self->priv->display, "grab-keyboard", TRUE, diff --git a/src/virt-viewer-display-spice.h b/src/virt-viewer-display-spice.h index eecc03e..701ed85 100644 --- a/src/virt-viewer-display-spice.h +++ b/src/virt-viewer-display-spice.h @@ -66,9 +66,7 @@ struct _VirtViewerDisplaySpiceClass { GType virt_viewer_display_spice_get_type(void); -GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session, - SpiceChannel *channel, - SpiceDisplay *display); +GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session, SpiceChannel *channel); G_END_DECLS diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c index d11d7a1..c9ba9e2 100644 --- a/src/virt-viewer-session-spice.c +++ b/src/virt-viewer-session-spice.c @@ -448,10 +448,8 @@ virt_viewer_session_spice_channel_new(SpiceSession *s, g_signal_emit_by_name(session, "session-connected"); DEBUG_LOG("new display channel (#%d)", id); - display = virt_viewer_display_spice_new(self, - channel, - spice_display_new(s, id)); - + display = virt_viewer_display_spice_new(self, channel); + g_object_set_data(G_OBJECT(channel), "virt-viewer-display", display); virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session), VIRT_VIEWER_DISPLAY(display)); @@ -533,7 +531,10 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s, } if (SPICE_IS_DISPLAY_CHANNEL(channel)) { - DEBUG_LOG("zap session channel (#%d)", id); + VirtViewerDisplay *display = g_object_get_data(G_OBJECT(channel), "virt-viewer-display"); + DEBUG_LOG("zap display channel (#%d, %p)", id, display); + virt_viewer_session_remove_display(session, display); + G_BREAKPOINT(); } if (SPICE_IS_PLAYBACK_CHANNEL(channel) && self->priv->audio) { -- 1.7.10.1