From 0cba6c4bdafa5dce0000d23e74da1176bd425599 Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 7 Jun 2026 17:42:06 +0200 Subject: [PATCH] popup: insideMenu set by motion/click on menuView, not enter; release guard uses insideMenu only Three changes to fix press-drag-release vs simple click semantics: 1. WME_ENTER no longer sets insideMenu. On Wayland, the enter event for the menu surface fires too early (menu overlaps button), incorrectly marking simple clicks as drag interactions. 2. WME_MOTION on menuView sets insideMenu=1 on the first motion, initiating drag interaction. This matches the desired semantics: moving the pointer into the menu after press establishes intent. 3. BUTTON_RELEASE close/select guard checks insideMenu only, not event->window == menuView. A release on the menu surface without prior motion (simple click on button where menu happens to be under the pointer) no longer triggers selection. --- WINGs/wpopupbutton.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/WINGs/wpopupbutton.c b/WINGs/wpopupbutton.c index 8cbbac7..98edd01 100644 --- a/WINGs/wpopupbutton.c +++ b/WINGs/wpopupbutton.c @@ -653,17 +653,21 @@ static void handleActionEvents(WMEvent * event, void *data) case WME_ENTER: wwarning("popup: ENTER window=0x%lx insideMenu=%d", (unsigned long)event->window, bPtr->flags.insideMenu); - /* Only set insideMenu on enter to the menu view itself; enter - * on the main button is not a menu interaction. */ - if (event->window == bPtr->menuView->window) - bPtr->flags.insideMenu = 1; + /* WME_ENTER is not a reliable indicator of menu interaction on + * Wayland because the popup may overlap the button, triggering + * an enter event for the menu surface on a simple button click. + * Only WME_MOTION on the menu view initiates drag interaction. */ break; case WME_MOTION: wwarning("popup: MOTION window=0x%lx y=%d highlightedItem prev=%d new=%d insideMenu=%d", (unsigned long)event->window, event->u.motion.y, oldItem, bPtr->highlightedItem, bPtr->flags.insideMenu); - if (bPtr->flags.insideMenu) { + /* First motion on the menu view initiates drag interaction; sets + * insideMenu so release-on-item selects and closes. WME_ENTER + * is not used because it fires too early (menu overlaps button). */ + if (event->window == bPtr->menuView->window) { + bPtr->flags.insideMenu = 1; oldItem = bPtr->highlightedItem; bPtr->highlightedItem = event->u.motion.y / bPtr->view->size.height; if (oldItem != bPtr->highlightedItem) { @@ -771,10 +775,11 @@ static void handleActionEvents(WMEvent * event, void *data) } } - /* 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) + /* Close/select on release only when insideMenu is active (set by + * motion or press on the menu view). A simple press-release on the + * button does not initiate drag interaction even if the release ends + * on the menu surface (menu overlaps button on Wayland). */ + if (bPtr->flags.insideMenu) popDownMenu(bPtr); if (bPtr->timer) {