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 bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot);
|
||||||
static wmEvent *wm_event_add_mousemove_to_head(wmWindow *win);
|
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
|
/** \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);
|
copy_v2_v2_int(event->prev_xy, win->eventstate->xy);
|
||||||
}
|
}
|
||||||
else if (ISKEYBOARD_OR_BUTTON(event->type)) {
|
else if (ISKEYBOARD_OR_BUTTON(event->type)) {
|
||||||
win->eventstate->prev_val = event->prev_val = win->eventstate->val;
|
wm_event_state_update_and_click_set_ex(event, win->eventstate, ISKEYBOARD(event->type), false);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return event;
|
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.
|
* 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,
|
static void wm_event_state_update_and_click_set_ex(wmEvent *event,
|
||||||
wmEvent *event,
|
wmEvent *event_state,
|
||||||
wmEvent *event_state)
|
const bool is_keyboard,
|
||||||
|
const bool check_double_click)
|
||||||
{
|
{
|
||||||
BLI_assert(ISKEYBOARD_OR_BUTTON(event->type));
|
BLI_assert(ISKEYBOARD_OR_BUTTON(event->type));
|
||||||
BLI_assert(ELEM(event->val, KM_PRESS, KM_RELEASE));
|
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
|
/* 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`,
|
* 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. */
|
* 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->modifier = event->modifier;
|
||||||
}
|
}
|
||||||
event_state->flag = (event->flag & event_state_flag_mask);
|
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. */
|
* since the `event_state` and the `event` are not kept in sync. */
|
||||||
|
|
||||||
/* Double click test. */
|
/* 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");
|
CLOG_INFO(WM_LOG_HANDLERS, 1, "DBL_CLICK: detected");
|
||||||
event->val = KM_DBL_CLICK;
|
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)
|
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void *customdata)
|
||||||
{
|
{
|
||||||
if (UNLIKELY(G.f & G_FLAG_EVENT_SIMULATE)) {
|
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_tablet_data_from_ghost(&bd->tablet, &event.tablet);
|
||||||
|
|
||||||
wm_eventemulation(&event, false);
|
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!). */
|
/* Add to other window if event is there (not to both!). */
|
||||||
wmWindow *win_other = wm_event_cursor_other_windows(wm, win, &event);
|
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. */
|
/* 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.
|
/* 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.
|
* 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.custom = 0;
|
||||||
event.customdata = NULL;
|
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);
|
wm_event_add(win, &event);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user