menu: fix infinite recursion in findMenuWalk via brother

A WMenu's brother is a parallel copy of the same menu used when the
menu is torn off / buttoned.  The brother shares cascade pointers
that reference back into the original tree, so recursing into both
m->brother and m->cascades[i] cycled (brother->cascades[i] == m's
own cascade entry, which has its own brother, etc.) and overflowed
the stack on any cascaded menu.

Inline the brother hit-test instead of recursing into it.  Cascades
themselves are walked recursively as before so sub-sub-menus remain
reachable.
This commit is contained in:
Window Maker 2026-05-24 08:25:14 +02:00
parent 3fb9f3925f
commit f2e49a8b67
1 changed files with 12 additions and 2 deletions

View File

@ -1113,6 +1113,11 @@ static void selectEntry(WMenu * menu, int entry_no)
* the pointer is over the entries area. Updates *deepest_p to the
* deepest mapped menu under (x,y) so that sub-sub-menus (cascade-of-
* cascade-...) are reachable.
*
* Brother menus are checked but NOT recursed into — a brother's
* cascade pointers reference back into the original tree and would
* cycle (brother->cascades[i] is the same WMenu as menu->cascades[i],
* which has its own brother, etc.).
*/
static void findMenuWalk(WMenu *m, int x, int y,
WMenu **deepest_p, int *dx_p, int *dy_p)
@ -1125,8 +1130,13 @@ static void findMenuWalk(WMenu *m, int x, int y,
*dx_p = x - m->frame_x;
*dy_p = y - m->frame_y - m->frame->top_width;
}
if (m->brother)
findMenuWalk(m->brother, x, y, deepest_p, dx_p, dy_p);
if (m->brother && m->brother->flags.mapped &&
x >= m->brother->frame_x && x < m->brother->frame_x + MENUW(m->brother) &&
y >= m->brother->frame_y && y < m->brother->frame_y + MENUH(m->brother)) {
*deepest_p = m->brother;
*dx_p = x - m->brother->frame_x;
*dy_p = y - m->brother->frame_y - m->brother->frame->top_width;
}
for (int i = 0; i < m->cascade_no; i++)
findMenuWalk(m->cascades[i], x, y, deepest_p, dx_p, dy_p);
}