From cfddd2ebfc9f38e254981d0dd7096b03344d8c70 Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 7 Jun 2026 17:38:05 +0200 Subject: [PATCH] BUTTON_RELEASE: capture selection before popDownMenu clears insideMenu/highlightedItem popDownMenu() resets insideMenu=0 and highlightedItem=-1. When called before the selection logic, the guard (insideMenu && highlightedItem >= 0) is always false, so WMSetPopUpButtonSelectedItem is never called and the closed-button display never updates. Fix: capture the selection state (insideMenu, highlightedItem, enabled item) into local variables BEFORE calling popDownMenu. Apply the selection (WMSetPopUpButtonSelectedItem + action callback) AFTER popDownMenu. --- WINGs/wpopupbutton.c | 62 ++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/WINGs/wpopupbutton.c b/WINGs/wpopupbutton.c index 53ab5a5..8cbbac7 100644 --- a/WINGs/wpopupbutton.c +++ b/WINGs/wpopupbutton.c @@ -751,48 +751,60 @@ static void handleActionEvents(WMEvent * event, void *data) } bPtr->view->screen->viewBackend->pointer_ungrab( bPtr->view->screen->viewBackendCtx, event->u.button.time); - /* Only close on release from menu view (drag-select) or insideMenu active. - * A plain click on the button without entering the menu keeps it open. */ - if (!bPtr->flags.pullsDown - && (event->window == bPtr->menuView->window - || bPtr->flags.insideMenu)) - popDownMenu(bPtr); - if (bPtr->timer) { - WMDeleteTimerHandler(bPtr->timer); - bPtr->timer = NULL; - } + /* Capture selection state BEFORE popDownMenu clears it. */ + int do_select = (bPtr->flags.insideMenu + && bPtr->highlightedItem >= 0 + && !bPtr->flags.pullsDown); + int sel_index = bPtr->highlightedItem; + int has_sel_item = 0; + WMMenuItem *sel_item = NULL; + if (do_select) { + int count = WMGetArrayItemCount(bPtr->items); + if (sel_index >= 0 && sel_index < count) { + WMMenuItem *mi = WMGetPopUpButtonMenuItem(bPtr, sel_index); + if (mi && WMGetMenuItemEnabled(mi)) { + do_select = 1; + sel_item = mi; + has_sel_item = 1; + } + } + } - if (bPtr->flags.insideMenu && bPtr->highlightedItem >= 0) { - WMMenuItem *item; + /* Only close on release from menu view (drag-select) or insideMenu active. + * A plain click on the button without entering the menu keeps it open. */ + if (event->window == bPtr->menuView->window + || bPtr->flags.insideMenu) + popDownMenu(bPtr); - item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem); + if (bPtr->timer) { + WMDeleteTimerHandler(bPtr->timer); + bPtr->timer = NULL; + } - if (WMGetMenuItemEnabled(item)) { - int i; - WMSetPopUpButtonSelectedItem(bPtr, bPtr->highlightedItem); + /* Apply selection after popDownMenu (which resets insideMenu/highlightedItem). */ + if (has_sel_item) { + WMSetPopUpButtonSelectedItem(bPtr, sel_index); if (bPtr->flags.pullsDown) { + int i; for (i = 0; i < MENU_BLINK_COUNT; i++) { - paintMenuEntry(bPtr, bPtr->highlightedItem, False); + paintMenuEntry(bPtr, sel_index, False); bPtr->view->screen->viewBackend->flush(bPtr->view->screen->viewBackendCtx); wusleep(MENU_BLINK_DELAY); - paintMenuEntry(bPtr, bPtr->highlightedItem, True); + paintMenuEntry(bPtr, sel_index, True); bPtr->view->screen->viewBackend->flush(bPtr->view->screen->viewBackendCtx); wusleep(MENU_BLINK_DELAY); } } - paintMenuEntry(bPtr, bPtr->highlightedItem, False); + paintMenuEntry(bPtr, sel_index, False); popDownMenu(bPtr); if (bPtr->action) (*bPtr->action) (bPtr, bPtr->clientData); } - } - if (bPtr->menuView->flags.mapped - && (event->window == bPtr->menuView->window - || bPtr->flags.insideMenu)) - popDownMenu(bPtr); - break; + if (bPtr->menuView->flags.mapped && !has_sel_item) + popDownMenu(bPtr); + break; } }