--- a/ui/gtk/list.c Sat Jun 06 18:47:45 2026 +0200 +++ b/ui/gtk/list.c Sun Jun 07 13:11:09 2026 +0200 @@ -1259,6 +1259,11 @@ return store; } +static void ui_destroy_tree_eventdata(GtkWidget *object, UiTreeEventData *data) { + free(data->activate_action); + free(data->selection_action); + free(data); +} UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { // create treeview @@ -1316,22 +1321,23 @@ event->obj = obj; event->activate = args->onactivate; event->activatedata = args->onactivatedata; + event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL; event->selection = args->onselection; event->selectiondata = args->onselectiondata; + event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL; g_signal_connect( view, "destroy", - G_CALLBACK(ui_destroy_userdata), + G_CALLBACK(ui_destroy_tree_eventdata), event); - - if(args->onactivate) { + if(args->onactivate || args->onactivate_action) { g_signal_connect( view, "row-activated", G_CALLBACK(ui_listview_activate_event), event); } - if(args->onselection) { + if(args->onselection || args->onselection_action) { GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(view)); g_signal_connect( @@ -1543,20 +1549,27 @@ list->obj = tableview; // add callback - UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData)); + UiTreeEventData *event = malloc(sizeof(UiTreeEventData)); event->obj = obj; event->activate = args->onactivate; + event->activatedata = args->onactivatedata; + event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL; event->selection = args->onselection; - event->activatedata = args->onactivatedata; event->selectiondata = args->onselectiondata; - if(args->onactivate) { + event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL; + g_signal_connect( + view, + "destroy", + G_CALLBACK(ui_destroy_tree_eventdata), + event); + if(args->onactivate || args->onactivate_action) { g_signal_connect( view, "row-activated", G_CALLBACK(ui_listview_activate_event), event); } - if(args->onselection) { + if(args->onselection || args->onselection_action) { GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(view)); g_signal_connect( @@ -1565,8 +1578,6 @@ G_CALLBACK(ui_listview_selection_event), event); } - // TODO: destroy callback - if(args->ondragstart) { ui_listview_add_dnd(tableview, args); @@ -1800,11 +1811,15 @@ e.eventdata = &selection; e.intval = selection.count > 0 ? selection.rows[0] : -1; e.set = ui_get_setop(); - event->activate(&e, event->activatedata); - if(selection.count > 0) { - free(selection.rows); + if(event->activate) { + event->activate(&e, event->activatedata); } + if(event->activate_action) { + uic_action_callback(&e, event->activate_action); + } + + free(selection.rows); } void ui_listview_selection_event( @@ -1824,11 +1839,14 @@ e.eventdata = &selection; e.intval = selection.count > 0 ? selection.rows[0] : -1; e.set = ui_get_setop(); - event->selection(&e, event->selectiondata); + if(event->selection) { + event->selection(&e, event->selectiondata); + } + if(event->selection_action) { + uic_action_callback(&e, event->selection_action); + } - if(selection.count > 0) { - free(selection.rows); - } + free(selection.rows); } UiListSelection ui_listview_get_selection(