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.
This commit is contained in:
lkn 2026-06-07 17:42:06 +02:00
parent cfddd2ebfc
commit 0cba6c4bda
1 changed files with 14 additions and 9 deletions

View File

@ -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) {