diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 2131d5aae4a..5491769fac2 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -182,8 +182,15 @@ void WM_report_banner_show(const struct bContext *C); void WM_report(const struct bContext *C, ReportType type, const char *message); void WM_reportf(const struct bContext *C, ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(3, 4); -void wm_event_add(struct wmWindow *win, const struct wmEvent *event_to_add); -void wm_event_init_from_window(struct wmWindow *win, struct wmEvent *event); +void wm_event_add_ex( + struct wmWindow *win, const struct wmEvent *event_to_add, + const struct wmEvent *event_to_add_after) + ATTR_NONNULL(1, 2); +void wm_event_add( + struct wmWindow *win, const struct wmEvent *event_to_add) + ATTR_NONNULL(1, 2); + +void wm_event_init_from_window(struct wmWindow *win, struct wmEvent *event); /* at maximum, every timestep seconds it triggers event_type events */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 516e9907b7e..06449f5d45e 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -97,7 +97,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA /* ************ event management ************** */ -void wm_event_add(wmWindow *win, const wmEvent *event_to_add) +void wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *event_to_add_after) { wmEvent *event = MEM_mallocN(sizeof(wmEvent), "wmEvent"); @@ -105,7 +105,18 @@ void wm_event_add(wmWindow *win, const wmEvent *event_to_add) update_tablet_data(win, event); - BLI_addtail(&win->queue, event); + if (event_to_add_after == NULL) { + BLI_addtail(&win->queue, event); + } + else { + /* note, strictly speaking this breaks const-correctness, however we're only changing 'next' member */ + BLI_insertlinkafter(&win->queue, (void *)event_to_add_after, event); + } +} + +void wm_event_add(wmWindow *win, const wmEvent *event_to_add) +{ + wm_event_add_ex(win, event_to_add, NULL); } void wm_event_free(wmEvent *event) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 6820493132b..1ab1ac8a28d 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3467,7 +3467,10 @@ static void tweak_gesture_modal(bContext *C, const wmEvent *event) tevent.type = EVT_TWEAK_M; tevent.val = val; /* mouse coords! */ - wm_event_add(window, &tevent); + + /* important we add immediately after this event, so future mouse releases + * (which may be in the queue already), are handled in order, see T44740 */ + wm_event_add_ex(window, &tevent, event); WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */ }