commit 79c735bb934dae1241a6ee5876c377f8acd19913
parent e0453c2110ce5556e74b86e2611151f6a6ee9921
Author: Janne Veteläinen <janne.vetelainen@elisanet.fi>
Date: Sun, 23 Jun 2024 21:58:14 +0300
Avoid circular reference
Diffstat:
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/systray/sndbusmenu.c b/systray/sndbusmenu.c
@@ -274,13 +274,17 @@ reschedule_update(SnItem *snitem, GParamSpec *pspec, void *data)
{
SnDbusmenu *self = SN_DBUSMENU(data);
+ g_return_if_fail(SN_IS_ITEM(self->snitem));
+
gboolean popover_visible = sn_item_get_popover_visible(snitem);
if (popover_visible || !self->reschedule)
return;
self->reschedule = FALSE;
+ g_object_ref(self->snitem);
layout_update(self);
+ g_object_unref(self->snitem);
}
static gboolean
@@ -373,7 +377,11 @@ proxy_signal_handler(GDBusProxy *proxy,
void *data)
{
SnDbusmenu *self = SN_DBUSMENU(data);
+
+ g_return_if_fail(SN_IS_ITEM(self->snitem));
+
g_mutex_lock(&self->mutex);
+ g_object_ref(self->snitem);
if (strcmp(signal, "LayoutUpdated") == 0) {
gboolean popover_visible = sn_item_get_popover_visible(self->snitem);
@@ -403,6 +411,7 @@ proxy_signal_handler(GDBusProxy *proxy,
g_variant_unref(updated_props);
}
}
+ g_object_unref(self->snitem);
g_mutex_unlock(&self->mutex);
}
@@ -653,7 +662,6 @@ sn_dbusmenu_dispose(GObject *obj)
self->busobj);
g_object_unref(self->proxy);
- g_object_unref(self->snitem);
G_OBJECT_CLASS(sn_dbusmenu_parent_class)->dispose(obj);
}
diff --git a/systray/snhost.c b/systray/snhost.c
@@ -151,10 +151,7 @@ sn_host_unregister_item(SnHost *self, SnItem *snitem)
self->trayitems = g_slist_remove(self->trayitems, snitem);
- g_object_ref(snitem);
gtk_box_remove(GTK_BOX(self), GTK_WIDGET(snitem));
- g_object_run_dispose(G_OBJECT(snitem));
- g_object_unref(snitem);
self->nitems = self->nitems - 1;
diff --git a/systray/snitem.c b/systray/snitem.c
@@ -35,6 +35,8 @@ struct _SnItem
gboolean ready;
gboolean exiting;
gboolean menu_visible;
+
+ ulong popup_sig_id;
};
G_DEFINE_FINAL_TYPE(SnItem, sn_item, GTK_TYPE_WIDGET)
@@ -386,8 +388,7 @@ sn_item_proxy_signal_handler(GDBusProxy *proxy,
static void
sn_item_popup(SnDbusmenu *dbusmenu, SnItem *self)
{
- if (!GTK_IS_POPOVER_MENU(self->popovermenu))
- return;
+ g_return_if_fail(!SN_IS_ITEM(self) || !GTK_IS_POPOVER_MENU(self->popovermenu));
g_object_set(self, "menuvisible", TRUE, NULL);
gtk_popover_popup(GTK_POPOVER(self->popovermenu));
@@ -471,10 +472,14 @@ sn_item_proxy_ready_handler(GObject *obj, GAsyncResult *res, void *data)
if (menu_buspath_v && !self->exiting) {
g_variant_get(menu_buspath_v, "&o", &menu_buspath);
- SnDbusmenu *dbusmenu = sn_dbusmenu_new(self->busname, menu_buspath, g_object_ref(self));
+ SnDbusmenu *dbusmenu = sn_dbusmenu_new(self->busname, menu_buspath, self);
g_object_set(self, "dbusmenu", dbusmenu, NULL);
- g_signal_connect(self->dbusmenu, "abouttoshowhandled", G_CALLBACK(sn_item_popup), self);
+ self->popup_sig_id = g_signal_connect(self->dbusmenu,
+ "abouttoshowhandled",
+ G_CALLBACK(sn_item_popup),
+ self);
+
g_variant_unref(menu_buspath_v);
}
self->ready = TRUE;
@@ -772,6 +777,8 @@ sn_item_dispose(GObject *obj)
self->exiting = TRUE;
if (self->dbusmenu) {
+ g_signal_handler_disconnect(self->dbusmenu, self->popup_sig_id);
+ self->popup_sig_id = 0;
g_object_unref(self->dbusmenu);
self->dbusmenu = NULL;
}