diff options
author | Campbell Barton <campbell@blender.org> | 2022-05-13 16:41:03 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-05-13 16:41:03 +0300 |
commit | 05b56d55e8578c79080083cb4177a8846f82af14 (patch) | |
tree | bc108b1a0bb00a7ddcbd2b7b71864e1705d2a9ab /source/blender/editors/interface | |
parent | cbc024c3cac29dd17a9e5338162792d8fadc82ee (diff) |
Fix T97386: Node socket labels swallow click/drag events
Regression caused by [0] which made `ui_but_is_interactive` consider
label buttons with tool-tips to be interactive. This prevented
the clicks to pass through to the nodes for selecting/dragging.
Resolve this by allowing buttons to be activated for the purpose
of showing tool-tips but otherwise considering them disabled
(as if the UI_BUT_DISABLED is set when handling events).
[0]: 484a9146479e05946d291e9886cdf3febca6d05d
Reviewed By: Severin
Ref D14932
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 27 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_query.cc | 32 |
3 files changed, 48 insertions, 13 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2c408619fe7..26b9b82d67f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -384,6 +384,12 @@ typedef struct uiHandleButtonData { /* True when alt is held and the preference for displaying tooltips should be ignored. */ bool tooltip_force; + /** + * Behave as if #UI_BUT_DISABLED is set (without drawing grayed out). + * Needed so non-interactive labels can be activated for the purpose of showing tool-tips, + * without them blocking interaction with nodes, see: T97386. + */ + bool disable_force; /* auto open */ bool used_mouse; @@ -1669,7 +1675,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const */ if (drag_info->is_xy_lock_init == false) { /* first store the buttons original coords */ - uiBut *but = ui_but_find_mouse_over_ex(region, xy_input, true, NULL, NULL); + uiBut *but = ui_but_find_mouse_over_ex(region, xy_input, true, false, NULL, NULL); if (but) { if (but->flag & UI_BUT_DRAG_LOCK) { @@ -1739,7 +1745,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void if (done) { wmWindow *win = CTX_wm_window(C); const ARegion *region = CTX_wm_region(C); - uiBut *but = ui_but_find_mouse_over_ex(region, drag_info->xy_init, true, NULL, NULL); + uiBut *but = ui_but_find_mouse_over_ex(region, drag_info->xy_init, true, false, NULL, NULL); if (but) { ui_apply_but_undo(but); @@ -4324,7 +4330,7 @@ static uiBut *ui_but_list_row_text_activate(bContext *C, uiButtonActivateType activate_type) { ARegion *region = CTX_wm_region(C); - uiBut *labelbut = ui_but_find_mouse_over_ex(region, event->xy, true, NULL, NULL); + uiBut *labelbut = ui_but_find_mouse_over_ex(region, event->xy, true, false, NULL, NULL); if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) { /* exit listrow */ @@ -7899,7 +7905,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * uiHandleButtonData *data = but->active; int retval = WM_UI_HANDLER_CONTINUE; - const bool is_disabled = but->flag & UI_BUT_DISABLED; + const bool is_disabled = but->flag & UI_BUT_DISABLED || data->disable_force; /* if but->pointype is set, but->poin should be too */ BLI_assert(!but->pointype || but->poin); @@ -8947,7 +8953,12 @@ static uiBut *ui_but_find_open_event(ARegion *region, const wmEvent *event) static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *region) { if (event->type == MOUSEMOVE) { - uiBut *but = ui_but_find_mouse_over(region, event); + const bool labeledit = event->modifier & KM_CTRL; + /* Allow buttons to be activated to show the tool-tip, + * then force-disable them if they're not considered interactive + * so they don't swallow events but can still display tips. */ + const bool for_tooltip = true; + uiBut *but = ui_but_find_mouse_over_ex(region, event->xy, labeledit, for_tooltip, NULL, NULL); if (but) { button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER); @@ -8956,6 +8967,10 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg * preferences. */ but->active->tooltip_force = true; } + + if (but->active && !ui_but_is_interactive(but, labeledit)) { + but->active->disable_force = true; + } } } else if (event->type == EVT_BUT_OPEN) { @@ -9435,7 +9450,7 @@ static bool ui_list_is_hovering_draggable_but(bContext *C, int mouse_xy[2]; WM_event_drag_start_xy(event, mouse_xy); - const uiBut *hovered_but = ui_but_find_mouse_over_ex(region, mouse_xy, false, NULL, NULL); + const uiBut *hovered_but = ui_but_find_mouse_over_ex(region, mouse_xy, false, false, NULL, NULL); if (list->dyn_data->custom_drag_optype) { if (ui_but_context_poll_operator(C, list->dyn_data->custom_drag_optype, hovered_but)) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index c09ff68bbca..b1ca0fa4e92 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -1352,6 +1352,7 @@ bool ui_but_is_toggle(const uiBut *but) ATTR_WARN_UNUSED_RESULT; * \note ctrl is kind of a hack currently, * so that non-embossed UI_BTYPE_TEXT button behaves as a label when ctrl is not pressed. */ +bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool for_tooltip); bool ui_but_is_interactive(const uiBut *but, bool labeledit) ATTR_WARN_UNUSED_RESULT; bool ui_but_is_popover_once_compat(const uiBut *but) ATTR_WARN_UNUSED_RESULT; bool ui_but_has_array_value(const uiBut *but) ATTR_WARN_UNUSED_RESULT; @@ -1388,6 +1389,7 @@ typedef bool (*uiButFindPollFn)(const uiBut *but, const void *customdata); uiBut *ui_but_find_mouse_over_ex(const struct ARegion *region, const int xy[2], bool labeledit, + bool for_tooltip, const uiButFindPollFn find_poll, const void *find_custom_data) ATTR_NONNULL(1, 2) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index 337b2852d57..ea1fe3923e4 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -58,12 +58,23 @@ bool ui_but_is_toggle(const uiBut *but) UI_BTYPE_TREEROW); } -bool ui_but_is_interactive(const uiBut *but, const bool labeledit) +bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool for_tooltip) { /* NOTE: #UI_BTYPE_LABEL is included for highlights, this allows drags. */ - if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == nullptr && but->tip_func == nullptr) { - return false; + if (but->type == UI_BTYPE_LABEL) { + if (for_tooltip) { + /* It's important labels are considered interactive for the purpose of showing tooltip. */ + if (but->dragpoin == nullptr && but->tip_func == nullptr) { + return false; + } + } + else { + if (but->dragpoin == nullptr) { + return false; + } + } } + if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX)) { return false; } @@ -84,6 +95,11 @@ bool ui_but_is_interactive(const uiBut *but, const bool labeledit) return true; } +bool ui_but_is_interactive(const uiBut *but, const bool labeledit) +{ + return ui_but_is_interactive_ex(but, labeledit, false); +} + bool UI_but_is_utf8(const uiBut *but) { if (but->rnaprop) { @@ -266,6 +282,7 @@ static uiBut *ui_but_find(const ARegion *region, uiBut *ui_but_find_mouse_over_ex(const ARegion *region, const int xy[2], const bool labeledit, + const bool for_tooltip, const uiButFindPollFn find_poll, const void *find_custom_data) { @@ -282,7 +299,7 @@ uiBut *ui_but_find_mouse_over_ex(const ARegion *region, if (find_poll && find_poll(but, find_custom_data) == false) { continue; } - if (ui_but_is_interactive(but, labeledit)) { + if (ui_but_is_interactive_ex(but, labeledit, for_tooltip)) { if (but->pie_dir != UI_RADIAL_NONE) { if (ui_but_isect_pie_seg(block, but)) { butover = but; @@ -310,7 +327,8 @@ uiBut *ui_but_find_mouse_over_ex(const ARegion *region, uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event) { - return ui_but_find_mouse_over_ex(region, event->xy, event->modifier & KM_CTRL, nullptr, nullptr); + return ui_but_find_mouse_over_ex( + region, event->xy, event->modifier & KM_CTRL, false, nullptr, nullptr); } uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) @@ -414,7 +432,7 @@ static bool ui_but_is_listrow(const uiBut *but, const void *UNUSED(customdata)) uiBut *ui_list_row_find_mouse_over(const ARegion *region, const int xy[2]) { - return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_listrow, nullptr); + return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_listrow, nullptr); } struct ListRowFindIndexData { @@ -446,7 +464,7 @@ static bool ui_but_is_treerow(const uiBut *but, const void *UNUSED(customdata)) uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int xy[2]) { - return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_treerow, nullptr); + return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_treerow, nullptr); } static bool ui_but_is_active_treerow(const uiBut *but, const void *customdata) |