From 5953ff318c2e8b5093b5fe98b1b098a630bf67ff Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Mon, 6 Oct 2025 20:19:12 +0200 Subject: [PATCH] UI: Add Preference for Menu Close on Leave This PR changes the current behavior that closes menus that are open when your mouse is moved out of its "safe" area (a bit wider than its visible bounds). With this PR applied menus stay open unless you click elsewhere, hover a neighboring menu, press escape, or select an item. Although this PR turns off menu mouse leave, it also adds a preference that can be used to turn it back on. Pull Request: https://projects.blender.org/blender/blender/pulls/145523 --- scripts/startup/bl_ui/space_userpref.py | 9 ++++++--- source/blender/blenloader/intern/versioning_userdef.cc | 2 +- source/blender/editors/interface/interface_handlers.cc | 5 +++-- .../editors/interface/regions/interface_region_popup.cc | 2 +- source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/makesrna/intern/rna_userdef.cc | 5 +++++ 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index d673e91cc7f..2096d8c4134 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -344,12 +344,15 @@ class USERPREF_PT_interface_statusbar(InterfacePanel, CenterAlignMixIn, Panel): col.prop(view, "show_statusbar_version", text="Blender Version") -class USERPREF_PT_interface_menus(InterfacePanel, Panel): +class USERPREF_PT_interface_menus(InterfacePanel, CenterAlignMixIn, Panel): bl_label = "Menus" bl_options = {'DEFAULT_CLOSED'} - def draw(self, context): - pass + def draw_centered(self, context, layout): + prefs = context.preferences + view = prefs.view + col = layout.column() + col.prop(view, "menu_close_leave") class USERPREF_PT_interface_menus_mouse_over(InterfacePanel, CenterAlignMixIn, Panel): diff --git a/source/blender/blenloader/intern/versioning_userdef.cc b/source/blender/blenloader/intern/versioning_userdef.cc index 4e997b75b39..8b04d298c1c 100644 --- a/source/blender/blenloader/intern/versioning_userdef.cc +++ b/source/blender/blenloader/intern/versioning_userdef.cc @@ -1026,7 +1026,7 @@ void blo_do_versions_userdef(UserDef *userdef) if (!USER_VERSION_ATLEAST(278, 6)) { /* Clear preference flags for re-use. */ - userdef->flag &= ~(USER_FLAG_NUMINPUT_ADVANCED | (1 << 2) | USER_FLAG_UNUSED_3 | + userdef->flag &= ~(USER_FLAG_NUMINPUT_ADVANCED | (1 << 2) | USER_MENU_CLOSE_LEAVE | USER_FLAG_UNUSED_6 | USER_FLAG_UNUSED_7 | USER_INTERNET_ALLOW | USER_DEVELOPER_UI); userdef->uiflag &= ~USER_HEADER_BOTTOM; diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 9f7813c3a82..ef6fda03aaf 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -11241,7 +11241,8 @@ static int ui_handle_menu_event(bContext *C, menu->menuretval = UI_RETURN_OK; } else { - menu->menuretval = UI_RETURN_OUT; + menu->menuretval = (U.flag & USER_MENU_CLOSE_LEAVE) ? UI_RETURN_OUT : + UI_RETURN_CANCEL; } } } @@ -11339,7 +11340,7 @@ static int ui_handle_menu_event(bContext *C, } /* strict check, and include the parent rect */ - if (!menu->dotowards && !saferct) { + if (!menu->dotowards && !saferct && ((U.flag & USER_MENU_CLOSE_LEAVE) || level > 0)) { if (block->flag & UI_BLOCK_OUT_1) { menu->menuretval = UI_RETURN_OK; } diff --git a/source/blender/editors/interface/regions/interface_region_popup.cc b/source/blender/editors/interface/regions/interface_region_popup.cc index ed747c101fb..dcbf3638d1f 100644 --- a/source/blender/editors/interface/regions/interface_region_popup.cc +++ b/source/blender/editors/interface/regions/interface_region_popup.cc @@ -331,7 +331,7 @@ static void ui_popup_block_position(wmWindow *window, /* when you are outside parent button, safety there should be smaller */ - const int s1 = 40 * UI_SCALE_FAC; + const int s1 = (U.flag & USER_MENU_CLOSE_LEAVE) ? 40 * UI_SCALE_FAC : win_size[0]; const int s2 = 3 * UI_SCALE_FAC; /* parent button to left */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 1f5e44f4dc6..cfc0dd61ef7 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -685,7 +685,7 @@ typedef enum eUserPref_Flag { USER_AUTOSAVE = (1 << 0), USER_FLAG_NUMINPUT_ADVANCED = (1 << 1), USER_FLAG_RECENT_SEARCHES_DISABLE = (1 << 2), - USER_FLAG_UNUSED_3 = (1 << 3), /* cleared */ + USER_MENU_CLOSE_LEAVE = (1 << 3), USER_FLAG_UNUSED_4 = (1 << 4), /* cleared */ USER_TRACKBALL = (1 << 5), USER_FLAG_UNUSED_6 = (1 << 6), /* cleared */ diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index 5a85f91a78d..2ebd31d0519 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -5074,6 +5074,11 @@ static void rna_def_userdef_view(BlenderRNA *brna) "Open on Mouse Over", "Open menu buttons and pull-downs automatically when the mouse is hovering"); + prop = RNA_def_property(srna, "menu_close_leave", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "flag", USER_MENU_CLOSE_LEAVE); + RNA_def_property_ui_text( + prop, "Close Menu on Leave", "Close menus when the mouse is moved out of the region."); + prop = RNA_def_property(srna, "open_toplevel_delay", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, nullptr, "menuthreshold1"); RNA_def_property_range(prop, 1, 40);