diff -r d218b70e1499 -r 4f7e335a95ca ui/gtk/button.c --- a/ui/gtk/button.c Thu Dec 25 10:40:35 2025 +0100 +++ b/ui/gtk/button.c Fri Dec 26 10:19:17 2025 +0100 @@ -505,41 +505,33 @@ #define RADIOBUTTON_GET_ACTIVE(button) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) #endif -static void radiobutton_toggled(void *widget, UiVarEventData *event) { - gboolean active = RADIOBUTTON_GET_ACTIVE(widget); - +static void radiobutton_toggled(void *widget, UiEventData *event) { UiEvent e; e.obj = event->obj; e.window = event->obj->window; e.document = event->obj->ctx->document; e.eventdata = NULL; e.eventdatatype = 0; - e.intval = active; + e.intval = RADIOBUTTON_GET_ACTIVE(widget); e.set = ui_get_setop(); - - if(event->callback) { - event->callback(&e, event->userdata); - } - - if(active && event->var) { - UiInteger *i = event->var->value; - - e.intval = i->get(i); - ui_notify_evt(i->observers, &e); - } + event->callback(&e, event->userdata); } typedef struct UiRadioButtonData { - UiObject *obj; - UiVar *var; + UiInteger *value; + UiVarEventData *eventdata; UiBool first; } UiRadioButtonData; static void destroy_radiobutton(GtkWidget *w, UiRadioButtonData *data) { if(data->first) { - UiInteger *value = data->var->value; - ui_destroy_boundvar(data->obj->ctx, data->var); - g_slist_free(value->obj); + ui_destroy_vardata(w, data->eventdata); + g_slist_free(data->value->obj); + data->value->obj = NULL; + data->value->get = NULL; + data->value->set = NULL; + } else { + free(data->eventdata); } free(data); } @@ -562,16 +554,6 @@ GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args->label); ui_set_name_and_style(rbutton, args->name, args->style_class); ui_set_widget_states(obj->ctx, rbutton, args->states); - - UiVarEventData *event = malloc(sizeof(UiVarEventData)); - event->obj = obj; - event->var = var; - event->observers = NULL; - event->callback = args->onchange; - event->userdata = args->onchangedata; - event->customint1 = 0; - event->customint2 = 0; - if(rgroup) { #if GTK_MAJOR_VERSION >= 4 if(rg) { @@ -589,28 +571,52 @@ ui_radiobutton_set(rgroup, rgroup->value); + UiVarEventData *event = malloc(sizeof(UiVarEventData)); + event->obj = obj; + event->var = var; + event->observers = NULL; + event->callback = NULL; + event->userdata = NULL; + event->customint1 = 0; + event->customint2 = 0; + UiRadioButtonData *rbdata = malloc(sizeof(UiRadioButtonData)); - rbdata->obj = obj; - rbdata->var = var; + rbdata->value = rgroup; + rbdata->eventdata = event; rbdata->first = first; g_signal_connect( rbutton, + "toggled", + G_CALLBACK(ui_radio_obs), + event); + g_signal_connect( + rbutton, "destroy", G_CALLBACK(destroy_radiobutton), rbdata); } + + if(args->onchange) { + UiEventData *event = malloc(sizeof(UiEventData)); + event->obj = obj; + event->userdata = args->onchangedata; + event->callback = args->onchange; + event->value = 0; + event->customdata = NULL; + event->customint = 0; - g_signal_connect( - rbutton, - "toggled", - G_CALLBACK(radiobutton_toggled), - event); - g_signal_connect( - rbutton, - "destroy", - G_CALLBACK(ui_destroy_userdata), - event); + g_signal_connect( + rbutton, + "toggled", + G_CALLBACK(radiobutton_toggled), + event); + g_signal_connect( + rbutton, + "destroy", + G_CALLBACK(ui_destroy_userdata), + event); + } UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; UiLayout layout = UI_ARGS2LAYOUT(args); @@ -619,6 +625,20 @@ return rbutton; } +void ui_radio_obs(GtkToggleButton *widget, UiVarEventData *event) { + UiInteger *i = event->var->value; + + UiEvent e; + e.obj = event->obj; + e.window = event->obj->window; + e.document = event->obj->ctx->document; + e.eventdata = NULL; + e.eventdatatype = 0; + e.intval = i->get(i); + + ui_notify_evt(i->observers, &e); +} + #if GTK_MAJOR_VERSION >= 4 int64_t ui_radiobutton_get(UiInteger *value) { int selection = 0;