UI: Padding When Opening Menu When One is Already Open

When you open a menu or popover, moving your mouse to a neighboring
root menu button will switch to that one. For example when you open the
"File" menu and move to the right to have "Edit" open automatically.
This currently causes problems with some neighboring menus. This PR
adds a safety padding to the open item. This generally means that once
you open a menu, you will need to move your mouse into the neighbor's
content, not just hit the edge.

Pull Request: https://projects.blender.org/blender/blender/pulls/135692
This commit is contained in:
Harley Acheson
2025-04-08 22:45:39 +02:00
committed by Harley Acheson
parent a0eedd2193
commit 166d45b80f

View File

@@ -12039,7 +12039,7 @@ static int ui_handle_region_semi_modal_buttons(bContext *C, const wmEvent *event
}
/* Return true if we should open another menu while one is already open. */
static bool ui_can_activate_other_menu(uiBut *but, uiBut *but_other)
static bool ui_can_activate_other_menu(uiBut *but, uiBut *but_other, const wmEvent *event)
{
if (but_other->flag & UI_BUT_DISABLED) {
return false;
@@ -12057,7 +12057,42 @@ static bool ui_can_activate_other_menu(uiBut *but, uiBut *but_other)
return false;
}
return true;
float safety = 4.0f * UI_SCALE_FAC;
if (!but_other->str.empty()) {
safety += 4.0f * UI_SCALE_FAC;
}
float left, right;
if (but_other->rect.xmin < but->rect.xmin) {
/* Right to Left. */
if (but->rect.xmin - but_other->rect.xmax > (24.0f * UI_SCALE_FAC)) {
/* If they are far enough part just switch. */
return true;
}
right = but->rect.xmax;
left = but_other->rect.xmax;
if (ELEM(but_other->type, UI_BTYPE_POPOVER, UI_BTYPE_MENU)) {
/* Skip the dropdown arrow on the right of it. */
safety += 8.0f * UI_SCALE_FAC;
}
left -= safety;
}
else {
/* Left to Right. */
if (but_other->rect.xmin - but->rect.xmax > (24.0f * UI_SCALE_FAC)) {
/* If they are far enough part just switch. */
return true;
}
left = but->rect.xmin;
right = but_other->rect.xmin;
if (but_other->icon && !but_other->str.empty()) {
/* Skip the icon on the left of it. */
safety += 16.0f * UI_SCALE_FAC;
}
right += safety;
}
return (event->mval[0] < int(left) || event->mval[0] > int(right));
}
/* handle buttons at the window level, modal, for example while
@@ -12096,7 +12131,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void * /*us
{
/* if mouse moves to a different root-level menu button,
* open it to replace the current menu */
if (ui_can_activate_other_menu(but, but_other)) {
if (ui_can_activate_other_menu(but, but_other, event)) {
ui_handle_button_activate(C, region, but_other, BUTTON_ACTIVATE_OVER);
button_activate_state(C, but_other, BUTTON_STATE_MENU_OPEN);
retval = WM_UI_HANDLER_BREAK;