diff -r 4681df3739f7 -r da0899b1699d ui/gtk/list.c --- a/ui/gtk/list.c Sun Sep 13 11:50:14 2026 +0200 +++ b/ui/gtk/list.c Sun Sep 13 14:30:34 2026 +0200 @@ -3084,6 +3084,10 @@ cxListFree(v->rows); free(v->onactivate_action); free(v->onbuttonclick_action); + free(v->oncontextmenupopup_action); + if(v->contextmenu) { + ui_menubuilder_unref(v->contextmenu); + } free(v); } @@ -3126,6 +3130,15 @@ uilistbox->onbuttonclick = args->onbuttonclick; uilistbox->onbuttonclickdata = args->onbuttonclickdata; uilistbox->onbuttonclick_action = args->onbuttonclick_action ? strdup(args->onbuttonclick_action) : NULL; + uilistbox->oncontextmenupopup = args->oncontextmenupopup; + uilistbox->oncontextmenupopupdata = args->oncontextmenupopupdata; + uilistbox->oncontextmenupopup_action = args->oncontextmenupopup_action ? strdup(args->oncontextmenupopup_action) : NULL; + uilistbox->contextmenu = NULL; + + if(args->contextmenu) { + uilistbox->contextmenu = args->contextmenu; + ui_menubuilder_ref(args->contextmenu); + } UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); uilistbox->var = var; @@ -3143,11 +3156,6 @@ g_object_set_data(G_OBJECT(scroll_area), "ui_listbox", uilistbox); g_object_set_data(G_OBJECT(listbox), "ui_listbox", uilistbox); - if(args->contextmenu) { - UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, listbox); - ui_widget_set_contextmenu(listbox, menu); - } - // signals g_signal_connect( listbox, @@ -3231,10 +3239,34 @@ #endif +static void listbox2_on_contextmenu_popup(UiEvent *ununsed, void *userdata) { + UiListBox2Row *row = userdata; + + UiListSelection sel; + sel.count = 1; + sel.rows = &row->index; + + UiEvent event; + event.obj = row->listbox->obj; + event.window = event.obj->window; + event.document = event.obj->ctx->document; + event.eventdata = &sel; + event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; + event.intval = row->index; + event.set = 0; + + if(row->listbox->oncontextmenupopup) { + row->listbox->oncontextmenupopup(&event, row->listbox->oncontextmenupopupdata); + } + if(row->listbox->oncontextmenupopup_action) { + uic_action_callback(&event, row->listbox->oncontextmenupopup_action); + } +} + #define LISTBOX2_ITEM_HBOX_SPACING 10 static void listbox2_update_item(UiListBox2Row *rowdata, GtkWidget *row, UiSourceListItem *item, int identation) { GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, LISTBOX2_ITEM_HBOX_SPACING); - + rowdata->expanded = 1; GtkWidget *expander = gtk_image_new(); GtkWidget *expander0 = expander; @@ -3370,6 +3402,14 @@ UiListBox2Row *row_data_ptr = cxListLast(listbox->rows); listbox2_update_item(row_data_ptr, row0, &item, item.depth - (item.depth > 0 ? heading : 0)); + if(listbox->contextmenu) { + row_data_ptr->contextmenu_popup_handler.callback = listbox2_on_contextmenu_popup; + row_data_ptr->contextmenu_popup_handler.userdata = row_data_ptr; + g_object_set_data(G_OBJECT(row), "ui_contextmenu_handler", &row_data_ptr->contextmenu_popup_handler); + UIMENU menu = ui_contextmenu_create(listbox->contextmenu, listbox->obj, row); + ui_widget_set_contextmenu(row, menu); + } + if(item.depth >= stack_size) { stack_size += 8; stack = realloc(stack, stack_size * sizeof(UiListBox2Row*));