diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 157fe2ca958..257b6392688 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -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;