WM: prevent drag events being continually tested

Click-drag events that weren't handled would continually be tested
for each mouse-motion event.

As well as being redundant, this added the overhead of querying
gizmos twice per motion event.

Now click-drag is only tested once when the drag threshold is reached.

This mitigates T87511, although the single drag test still causes
the snap gizmo to flicker.
This commit is contained in:
Campbell Barton 2021-04-16 23:46:21 +10:00
parent 278b19745b
commit 7bbead1e87
3 changed files with 18 additions and 1 deletions

View File

@ -278,8 +278,14 @@ typedef struct wmWindow {
char event_queue_check_click;
/** Enable when #KM_PRESS events are not handled (keyboard/mouse-buttons only). */
char event_queue_check_drag;
/**
* Enable when the drag was handled,
* to avoid mouse-motion continually triggering drag events which are not handled
* but add overhead to gizmo handling (for example), see T87511.
*/
char event_queue_check_drag_handled;
char _pad0[2];
char _pad0[1];
/** Internal, lock pie creation from this event until released. */
short pie_event_type_lock;

View File

@ -186,6 +186,7 @@ static void window_manager_blend_read_data(BlendDataReader *reader, ID *id)
win->addmousemove = true;
win->event_queue_check_click = 0;
win->event_queue_check_drag = 0;
win->event_queue_check_drag_handled = 0;
BLO_read_data_address(reader, &win->stereo3d_format);
/* Multi-view always fallback to anaglyph at file opening

View File

@ -2941,6 +2941,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if (wm_action_not_handled(action)) {
if (win->event_queue_check_drag) {
if (WM_event_drag_test(event, &event->prevclickx)) {
win->event_queue_check_drag_handled = true;
int x = event->x;
int y = event->y;
short val = event->val;
@ -2984,6 +2986,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if (event->is_repeat == false) {
win->event_queue_check_click = true;
win->event_queue_check_drag = true;
win->event_queue_check_drag_handled = false;
}
}
else if (event->val == KM_RELEASE) {
@ -3470,6 +3473,13 @@ void wm_event_do_handlers(bContext *C)
win->event_queue_check_click = false;
}
/* If the drag even was handled, don't attempt to keep re-handing the same
* drag event on every cursor motion, see: T87511. */
if (win->event_queue_check_drag_handled) {
win->event_queue_check_drag = false;
win->event_queue_check_drag_handled = false;
}
/* Update previous mouse position for following events to use. */
win->eventstate->prevx = event->x;
win->eventstate->prevy = event->y;