~ted/indicator-appmenu/destruction-will-happen-in-time

« back to all changes in this revision

Viewing changes to src/window-menus.c

  • Committer: Ted Gould
  • Date: 2011-02-03 19:24:52 UTC
  • mfrom: (97.1.4 lp706941)
  • Revision ID: ted@gould.cx-20110203192452-8mm10mporstyjh37
Make sure to ref through the signal handlers, clean up the items right and clear the signal handlers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
82
82
static void menu_entry_added        (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
83
83
static void menu_entry_removed      (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
84
84
static void menu_entry_realized     (DbusmenuMenuitem * newentry, gpointer user_data);
 
85
static void menu_prop_changed       (DbusmenuMenuitem * item, const gchar * property, GVariant * value, gpointer user_data);
85
86
static void menu_child_realized     (DbusmenuMenuitem * child, gpointer user_data);
86
87
static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data);
87
88
 
201
202
entry_free(IndicatorObjectEntry * entry)
202
203
{
203
204
        g_return_if_fail(entry != NULL);
 
205
        WMEntry * wmentry = (WMEntry *)entry;
 
206
 
 
207
        if (wmentry->mi != NULL) {
 
208
                g_signal_handlers_disconnect_by_func(wmentry->mi, G_CALLBACK(menu_prop_changed), &wmentry->ioentry);
 
209
                g_object_unref(G_OBJECT(wmentry->mi));
 
210
                wmentry->mi = NULL;
 
211
        }
204
212
 
205
213
        if (entry->label != NULL) {
206
214
                g_object_unref(entry->label);
219
227
        g_free(entry);
220
228
}
221
229
 
222
 
/* Free memory */
223
230
static void
224
 
window_menus_finalize (GObject *object)
 
231
free_entries(GObject *object, gboolean should_signal)
225
232
{
 
233
        g_return_if_fail(IS_WINDOW_MENUS(object));
 
234
 
226
235
        WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
227
236
 
228
 
        g_debug("Window Menus Object finalizing for: %d", priv->windowid);
229
 
 
230
237
        if (priv->entries != NULL) {
231
238
                int i;
232
239
                for (i = 0; i < priv->entries->len; i++) {
233
240
                        IndicatorObjectEntry * entry;
234
241
                        entry = g_array_index(priv->entries, IndicatorObjectEntry *, i);
 
242
                        g_array_remove_index(priv->entries, i);
 
243
                        if (should_signal) {                    
 
244
                                g_signal_emit(object, signals[ENTRY_REMOVED], 0, entry, TRUE);
 
245
                        }
235
246
                        entry_free(entry);
236
247
                }
 
248
        }
 
249
}
 
250
 
 
251
/* Free memory */
 
252
static void
 
253
window_menus_finalize (GObject *object)
 
254
{
 
255
        WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
 
256
 
 
257
        g_debug("Window Menus Object finalizing for: %d", priv->windowid);
 
258
 
 
259
        free_entries(object, FALSE);
 
260
 
 
261
        if (priv->entries != NULL) {
237
262
                g_array_free(priv->entries, TRUE);
238
263
                priv->entries = NULL;
239
264
        }
507
532
        WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
508
533
 
509
534
        /* Remove the old entries */
510
 
        while (priv->entries->len != 0) {
511
 
                menu_entry_removed(NULL, NULL, user_data);
512
 
        }
 
535
        free_entries(G_OBJECT(user_data), TRUE);
513
536
 
514
537
        if (priv->root != NULL) {
515
538
                g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), G_CALLBACK(menu_entry_added), user_data);
569
592
                if (children != NULL) {
570
593
                        gpointer * data = g_new(gpointer, 2);
571
594
                        data[0] = user_data;
572
 
                        data[1] = newentry;
 
595
                        data[1] = g_object_ref(newentry);
573
596
 
574
597
                        g_signal_connect(G_OBJECT(children->data), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(menu_child_realized), data);
575
598
                } else {
578
601
        } else {
579
602
                gpointer * data = g_new(gpointer, 2);
580
603
                data[0] = user_data;
581
 
                data[1] = newentry;
 
604
                data[1] = g_object_ref(newentry);
 
605
                /* child_realized does an unref */
582
606
 
583
607
                menu_child_realized(NULL, data);
584
608
        }
626
650
        IndicatorObjectEntry * entry = &wmentry->ioentry;
627
651
 
628
652
        wmentry->mi = newentry;
 
653
        g_object_ref(G_OBJECT(wmentry->mi));
629
654
 
630
655
        entry->label = GTK_LABEL(gtk_label_new_with_mnemonic(dbusmenu_menuitem_property_get(newentry, DBUSMENU_MENUITEM_PROP_LABEL)));
631
656
 
664
689
 
665
690
        g_signal_emit(G_OBJECT((((gpointer *)user_data)[0])), signals[ENTRY_ADDED], 0, entry, TRUE);
666
691
 
 
692
        g_object_unref(newentry);
667
693
        g_free(user_data);
668
694
 
669
695
        return;
674
700
menu_entry_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data)
675
701
{
676
702
        g_return_if_fail(IS_WINDOW_MENUS(user_data));
 
703
        g_return_if_fail(DBUSMENU_IS_MENUITEM(oldentry));
677
704
        WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
678
705
 
679
706
        if (priv->entries == NULL || priv->entries->len == 0) {
680
707
                return;
681
708
        }
682
 
        
 
709
 
683
710
        guint position;
684
711
        IndicatorObjectEntry * entry = get_entry(WINDOW_MENUS(user_data), oldentry, &position);
685
 
        if (entry == NULL) {
686
 
                /* Not found */
687
 
                return;
 
712
 
 
713
        if (entry != NULL) {
 
714
                g_array_remove_index(priv->entries, position);
 
715
                g_signal_emit(G_OBJECT(user_data), signals[ENTRY_REMOVED], 0, entry, TRUE);
 
716
                entry_free(entry);
 
717
        } else {
 
718
                /* We've been called before menu_child_realized fired,
 
719
                 * so there isn't a WMEntry yet. Don't be going ahead
 
720
                 * and creating one if this menu item continues to live! */
 
721
                g_signal_handlers_disconnect_by_func(G_OBJECT(oldentry), G_CALLBACK(menu_entry_realized), user_data);
688
722
        }
689
723
 
690
 
        g_array_remove_index(priv->entries, position);
691
 
 
692
 
        g_signal_emit(G_OBJECT(user_data), signals[ENTRY_REMOVED], 0, entry, TRUE);
693
 
 
694
 
        entry_free(entry);
695
 
 
696
724
        return;
697
725
}
698
726