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]: 484a914647
Reviewed By: Severin
Ref D14932
This commit is contained in:
parent
cbc024c3ca
commit
05b56d55e8
Notes:
blender-bot
2023-02-14 11:08:33 +01:00
Referenced by issue #97386, Regression: Click Dragging on Socket Labels does not register
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue