From 4710f3346ab197db7a46acf4767e931c03f6439d Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 27 Jan 2022 18:31:53 +0100 Subject: Event System: Add debug sanity check "always pass" events Asserts that such events actually always lead to a handler return value that actually keeps the event passing. Reviewed by Campbell Barton as part of https://developer.blender.org/D13539. --- .../blender/windowmanager/intern/wm_event_system.c | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3e30c06ade2..91701a62e00 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -645,6 +645,20 @@ static int wm_event_always_pass(const wmEvent *event) return ISTIMER(event->type) || (event->type == WINDEACTIVATE); } +/** + * Debug only sanity check for the return value of event handlers. Checks that "always pass" events + * don't cause non-passing handler return values, and thus actually pass. + * + * Can't be executed if the handler just loaded a file (typically identified by `CTX_wm_window(C)` + * returning `NULL`), because the event will have been freed then. + */ +BLI_INLINE void wm_event_handler_return_value_check(const wmEvent *event, const int action) +{ + BLI_assert_msg(!wm_event_always_pass(event) || (action != WM_HANDLER_BREAK), + "Return value for events that should always pass should never be BREAK."); + UNUSED_VARS_NDEBUG(event, action); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -2965,9 +2979,9 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis wmWindowManager *wm = CTX_wm_manager(C); int action = WM_HANDLER_CONTINUE; - int always_pass; if (handlers == NULL) { + wm_event_handler_return_value_check(event, action); return action; } @@ -2988,7 +3002,7 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis } else if (handler_base->poll == NULL || handler_base->poll(CTX_wm_region(C), event)) { /* In advance to avoid access to freed event on window close. */ - always_pass = wm_event_always_pass(event); + const int always_pass = wm_event_always_pass(event); /* Modal+blocking handler_base. */ if (handler_base->flag & WM_HANDLER_BLOCKING) { @@ -3130,6 +3144,10 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis wm_cursor_arrow_move(CTX_wm_window(C), event); } + /* Do some extra sanity checking before returning the action. */ + if (CTX_wm_window(C) != NULL) { + wm_event_handler_return_value_check(event, action); + } return action; } @@ -3257,6 +3275,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } + wm_event_handler_return_value_check(event, action); return action; } -- cgit v1.2.3