Changeset 05ca0d8
- Timestamp:
- Jun 1, 2010, 3:30:12 AM (14 years ago)
- Branches:
- master, release-1.10, release-1.7, release-1.8, release-1.9
- Children:
- d2a4534
- Parents:
- 7a6e6c7
- git-author:
- David Benjamin <davidben@mit.edu> (06/01/10 02:41:55)
- git-committer:
- David Benjamin <davidben@mit.edu> (06/01/10 03:30:12)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
owl.h
r7a6e6c7 r05ca0d8 410 410 411 411 typedef struct _owl_popwin { 412 gulong screen_resize_id;413 412 owl_window *border; 414 413 owl_window *content; -
popwin.c
r7a6e6c7 r05ca0d8 12 12 pw->content = owl_window_new(pw->border); 13 13 g_signal_connect(pw->border, "redraw", G_CALLBACK(owl_popwin_draw_border), 0); 14 pw->screen_resize_id = g_signal_connect_object(owl_window_get_screen(), "resized", G_CALLBACK(owl_popwin_size_border), pw->border, 0);15 g_signal_connect_object(pw->border, "resized", G_CALLBACK(owl_popwin_size_content), pw->content, 0);14 owl_signal_connect_object(owl_window_get_screen(), "resized", G_CALLBACK(owl_popwin_size_border), pw->border, 0); 15 owl_signal_connect_object(pw->border, "resized", G_CALLBACK(owl_popwin_size_content), pw->content, 0); 16 16 17 17 /* bootstrap sizing */ … … 73 73 g_object_unref(pw->content); 74 74 75 /* See comment on g_signal_connect_object; it only prevents the closure from76 * being invoked. The signal handler itself still gets leaked. The other77 * signal is okay, since we delete both at the same time. */78 if (g_signal_handler_is_connected(owl_window_get_screen(), pw->screen_resize_id))79 g_signal_handler_disconnect(owl_window_get_screen(), pw->screen_resize_id);80 81 75 pw->border = 0; 82 76 pw->content = 0; -
util.c
r4e33cb2 r05ca0d8 7 7 #include <sys/stat.h> 8 8 #include <sys/types.h> 9 10 #include <glib-object.h> 9 11 10 12 void sepbar(const char *in) … … 787 789 return buf; 788 790 } 791 792 typedef struct { /*noproto*/ 793 GObject *sender; 794 gulong signal_id; 795 } SignalData; 796 797 static void _closure_invalidated(gpointer data, GClosure *closure); 798 799 /* 800 * GObject's g_signal_connect_object has a documented bug. This function is 801 * identical except it does not leak the signal handler. 802 */ 803 gulong owl_signal_connect_object(gpointer sender, const gchar *detailed_signal, GCallback c_handler, gpointer receiver, GConnectFlags connect_flags) 804 { 805 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (sender), 0); 806 g_return_val_if_fail (detailed_signal != NULL, 0); 807 g_return_val_if_fail (c_handler != NULL, 0); 808 809 if (receiver) { 810 SignalData *sdata; 811 GClosure *closure; 812 gulong signal_id; 813 814 g_return_val_if_fail (G_IS_OBJECT (receiver), 0); 815 816 closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, receiver); 817 signal_id = g_signal_connect_closure (sender, detailed_signal, closure, connect_flags & G_CONNECT_AFTER); 818 819 /* Register the missing hooks */ 820 sdata = g_slice_new0(SignalData); 821 sdata->sender = sender; 822 sdata->signal_id = signal_id; 823 824 g_closure_add_invalidate_notifier(closure, sdata, _closure_invalidated); 825 826 return signal_id; 827 } else { 828 return g_signal_connect_data(sender, detailed_signal, c_handler, NULL, NULL, connect_flags); 829 } 830 } 831 832 /* 833 * There are three ways the signal could come to an end: 834 * 835 * 1. The user explicitly disconnects it with the returned signal_id. 836 * - In that case, the disconnection unref's the closure, causing it 837 * to first be invalidated. The handler's already disconnected, so 838 * we have no work to do. 839 * 2. The sender gets destroyed. 840 * - GObject will disconnect each signal which then goes into the above 841 * case. Our handler does no work. 842 * 3. The receiver gets destroyed. 843 * - The GClosure was created by g_cclosure_new_object_{,swap} which gets 844 * invalidated when the receiver is destroyed. We then follow through case 1 845 * again, but *this* time, the handler has not been disconnected. We then 846 * clean up ourselves. 847 * 848 * We can't actually hook into this process earlier with weakrefs as GObject 849 * will, on object dispose, first disconnect signals, then invalidate closures, 850 * and notify weakrefs last. 851 */ 852 static void _closure_invalidated(gpointer data, GClosure *closure) 853 { 854 SignalData *sdata = data; 855 if (g_signal_handler_is_connected(sdata->sender, sdata->signal_id)) { 856 g_signal_handler_disconnect(sdata->sender, sdata->signal_id); 857 } 858 g_slice_free(SignalData, sdata); 859 } 860
Note: See TracChangeset
for help on using the changeset viewer.