forked from bartvdbraak/blender
Fix click detection for simulated events
Refactoring event click-drag detection broke click detection for simulated events. Resolve this by sharing logic for update previous values in `wmWindow.eventstate` for regular event handling (no functional changes for non-simulated events). Failure to detect clicks for simulated events broke the undo test `test_undo.view3d_multi_mode_select` in `../lib/tests/ui_simulate/run.py`. All undo tests now pass.
This commit is contained in:
parent
f4ff36431c
commit
a4ed0f51c1
@ -102,6 +102,11 @@ static int wm_operator_call_internal(bContext *C,
|
||||
static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot);
|
||||
static wmEvent *wm_event_add_mousemove_to_head(wmWindow *win);
|
||||
|
||||
static void wm_event_state_update_and_click_set_ex(wmEvent *event,
|
||||
wmEvent *event_state,
|
||||
const bool is_keyboard,
|
||||
const bool check_double_click);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Event Management
|
||||
* \{ */
|
||||
@ -147,17 +152,7 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add)
|
||||
copy_v2_v2_int(event->prev_xy, win->eventstate->xy);
|
||||
}
|
||||
else if (ISKEYBOARD_OR_BUTTON(event->type)) {
|
||||
win->eventstate->prev_val = event->prev_val = win->eventstate->val;
|
||||
win->eventstate->prev_type = event->prev_type = win->eventstate->type;
|
||||
|
||||
win->eventstate->val = event->val;
|
||||
win->eventstate->type = event->type;
|
||||
|
||||
if (event->val == KM_PRESS) {
|
||||
if ((event->flag & WM_EVENT_IS_REPEAT) == 0) {
|
||||
copy_v2_v2_int(win->eventstate->prev_press_xy, event->xy);
|
||||
}
|
||||
}
|
||||
wm_event_state_update_and_click_set_ex(event, win->eventstate, ISKEYBOARD(event->type), false);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
@ -4950,10 +4945,14 @@ static wmEvent *wm_event_add_trackpad(wmWindow *win, const wmEvent *event, int d
|
||||
|
||||
/**
|
||||
* Update the event-state for any kind of event that supports #KM_PRESS / #KM_RELEASE.
|
||||
*
|
||||
* \param check_double_click: Optionally skip checking for double-click events.
|
||||
* Needed for event simulation where the time of click events is not so predictable.
|
||||
*/
|
||||
static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
|
||||
wmEvent *event,
|
||||
wmEvent *event_state)
|
||||
static void wm_event_state_update_and_click_set_ex(wmEvent *event,
|
||||
wmEvent *event_state,
|
||||
const bool is_keyboard,
|
||||
const bool check_double_click)
|
||||
{
|
||||
BLI_assert(ISKEYBOARD_OR_BUTTON(event->type));
|
||||
BLI_assert(ELEM(event->val, KM_PRESS, KM_RELEASE));
|
||||
@ -4969,7 +4968,7 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
|
||||
/* It's important only to write into the `event_state` modifier for keyboard
|
||||
* events because emulate MMB clears one of the modifiers in `event->modifier`,
|
||||
* making the second press not behave as if the modifier is pressed, see T96279. */
|
||||
if (ELEM(type, GHOST_kEventKeyDown, GHOST_kEventKeyUp)) {
|
||||
if (is_keyboard) {
|
||||
event_state->modifier = event->modifier;
|
||||
}
|
||||
event_state->flag = (event->flag & event_state_flag_mask);
|
||||
@ -4977,7 +4976,7 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
|
||||
* since the `event_state` and the `event` are not kept in sync. */
|
||||
|
||||
/* Double click test. */
|
||||
if (wm_event_is_double_click(event)) {
|
||||
if (check_double_click && wm_event_is_double_click(event)) {
|
||||
CLOG_INFO(WM_LOG_HANDLERS, 1, "DBL_CLICK: detected");
|
||||
event->val = KM_DBL_CLICK;
|
||||
}
|
||||
@ -4988,6 +4987,15 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
|
||||
}
|
||||
}
|
||||
|
||||
static void wm_event_state_update_and_click_set(wmEvent *event,
|
||||
wmEvent *event_state,
|
||||
const GHOST_TEventType type)
|
||||
{
|
||||
const bool is_keyboard = ELEM(type, GHOST_kEventKeyDown, GHOST_kEventKeyUp);
|
||||
const bool check_double_click = true;
|
||||
wm_event_state_update_and_click_set_ex(event, event_state, is_keyboard, check_double_click);
|
||||
}
|
||||
|
||||
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void *customdata)
|
||||
{
|
||||
if (UNLIKELY(G.f & G_FLAG_EVENT_SIMULATE)) {
|
||||
@ -5147,7 +5155,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
||||
wm_tablet_data_from_ghost(&bd->tablet, &event.tablet);
|
||||
|
||||
wm_eventemulation(&event, false);
|
||||
wm_event_state_update_and_click_set(type, &event, event_state);
|
||||
wm_event_state_update_and_click_set(&event, event_state, type);
|
||||
|
||||
/* Add to other window if event is there (not to both!). */
|
||||
wmWindow *win_other = wm_event_cursor_other_windows(wm, win, &event);
|
||||
@ -5271,7 +5279,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
||||
}
|
||||
|
||||
/* It's important `event.modifier` has been initialized first. */
|
||||
wm_event_state_update_and_click_set(type, &event, event_state);
|
||||
wm_event_state_update_and_click_set(&event, event_state, type);
|
||||
|
||||
/* If test_break set, it catches this. Do not set with modifier presses.
|
||||
* Exclude modifiers because MS-Windows uses these to bring up the task manager.
|
||||
@ -5345,7 +5353,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
||||
event.custom = 0;
|
||||
event.customdata = NULL;
|
||||
|
||||
wm_event_state_update_and_click_set(type, &event, event_state);
|
||||
wm_event_state_update_and_click_set(&event, event_state, type);
|
||||
|
||||
wm_event_add(win, &event);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user