@@ -25,6 +25,8 @@ struct _ExmExtensionRow
25
25
GtkImage * update_icon ;
26
26
GtkImage * error_icon ;
27
27
GtkImage * out_of_date_icon ;
28
+
29
+ guint signal_handler ;
28
30
};
29
31
30
32
G_DEFINE_FINAL_TYPE (ExmExtensionRow , exm_extension_row , ADW_TYPE_EXPANDER_ROW )
@@ -37,6 +39,10 @@ enum {
37
39
38
40
static GParamSpec * properties [N_PROPS ];
39
41
42
+ static void
43
+ bind_extension (ExmExtensionRow * self ,
44
+ ExmExtension * extension );
45
+
40
46
ExmExtensionRow *
41
47
exm_extension_row_new (ExmExtension * extension )
42
48
{
@@ -82,14 +88,7 @@ exm_extension_row_set_property (GObject *object,
82
88
switch (prop_id )
83
89
{
84
90
case PROP_EXTENSION :
85
- self -> extension = g_value_get_object (value );
86
- if (self -> extension )
87
- {
88
- // TODO: Bind here, rather than in constructed()
89
- g_object_get (self -> extension ,
90
- "uuid" , & self -> uuid ,
91
- NULL );
92
- }
91
+ bind_extension (self , g_value_get_object (value ));
93
92
break ;
94
93
default :
95
94
G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
@@ -168,17 +167,26 @@ set_error_label_visible (ExmExtensionRow *self,
168
167
}
169
168
170
169
static void
171
- exm_extension_row_bind_extension ( GObject * object ,
172
- GParamSpec * pspec )
170
+ bind_extension ( ExmExtensionRow * self ,
171
+ ExmExtension * extension )
173
172
{
174
173
// TODO: This big block of property assignments is currently copy/pasted
175
174
// from ExmExtension. We can replace this with GtkExpression lookups
176
175
// once blueprint-compiler supports expressions.
177
176
// (See https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/5)
178
177
179
- ExmExtensionRow * self = EXM_EXTENSION_ROW (object );
178
+ g_return_if_fail (EXM_IS_EXTENSION_ROW (self ));
179
+
180
+ // First, remove traces of the old extension
181
+ if (self -> extension != NULL )
182
+ {
183
+ g_signal_handler_disconnect (self -> extension , self -> signal_handler );
184
+ g_clear_object (& self -> extension );
185
+ g_clear_pointer (& self -> uuid , g_free );
186
+ }
180
187
181
- g_return_if_fail (pspec == properties [PROP_EXTENSION ]);
188
+ // Now, bind the new one
189
+ self -> extension = extension ;
182
190
183
191
if (self -> extension == NULL )
184
192
return ;
@@ -198,6 +206,8 @@ exm_extension_row_bind_extension (GObject *object,
198
206
"error-msg" , & error_msg ,
199
207
NULL );
200
208
209
+ self -> uuid = g_strdup (uuid );
210
+
201
211
g_object_set (self , "title" , name , "subtitle" , uuid , NULL );
202
212
g_object_set (self -> prefs_btn , "visible" , has_prefs , NULL );
203
213
g_object_set (self -> remove_btn , "visible" , is_user , NULL );
@@ -214,11 +224,13 @@ exm_extension_row_bind_extension (GObject *object,
214
224
gboolean has_error = (error_msg != NULL ) && (strlen (error_msg ) != 0 );
215
225
set_error_label_visible (self , has_error );
216
226
217
-
218
227
gtk_actionable_set_action_target (GTK_ACTIONABLE (self -> details_btn ), "s" , uuid );
219
228
220
229
// One way binding from extension ("source of truth") to switch
221
- g_signal_connect (self -> extension , "notify::state" , G_CALLBACK (update_state ), self );
230
+ self -> signal_handler = g_signal_connect (self -> extension ,
231
+ "notify::state" ,
232
+ G_CALLBACK (update_state ),
233
+ self );
222
234
223
235
GAction * action ;
224
236
@@ -323,11 +335,6 @@ exm_extension_row_init (ExmExtensionRow *self)
323
335
324
336
gtk_widget_init_template (GTK_WIDGET (self ));
325
337
326
- g_signal_connect (self ,
327
- "notify::extension" ,
328
- G_CALLBACK (exm_extension_row_bind_extension ),
329
- NULL );
330
-
331
338
// Define Actions
332
339
self -> action_group = g_simple_action_group_new ();
333
340
0 commit comments