[Bf-blender-cvs] [6e4ab5b761b] master: Fix crash handling tool-keymap events

Campbell Barton noreply at git.blender.org
Fri Oct 15 16:19:01 CEST 2021


Commit: 6e4ab5b761b03b52177985ecbeb2c2f576159c74
Author: Campbell Barton
Date:   Sat Oct 16 00:42:19 2021 +1100
Branches: master
https://developer.blender.org/rB6e4ab5b761b03b52177985ecbeb2c2f576159c74

Fix crash handling tool-keymap events

There was a rare crash in WM_event_get_keymap_from_toolsystem_fallback
when wm->winactive was NULL.

This could happen when the event was handled
immediately after closing a window.

===================================================================

M	source/blender/editors/interface/interface_template_search_menu.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_keymap.c

===================================================================

diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 3a5d65475f7..bbb04a9911c 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -351,7 +351,7 @@ static void menu_types_add_from_keymap_items(bContext *C,
       if (handler_base->poll == NULL || handler_base->poll(region, win->eventstate)) {
         wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base;
         wmEventHandler_KeymapResult km_result;
-        WM_event_get_keymaps_from_handler(wm, handler, &km_result);
+        WM_event_get_keymaps_from_handler(wm, win, handler, &km_result);
         for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) {
           wmKeyMap *keymap = km_result.keymaps[km_index];
           if (keymap && WM_keymap_poll(C, keymap)) {
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 26406966952..4ee514edb3c 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -272,13 +272,16 @@ typedef struct wmEventHandler_KeymapResult {
 } wmEventHandler_KeymapResult;
 
 typedef void(wmEventHandler_KeymapDynamicFn)(wmWindowManager *wm,
+                                             struct wmWindow *win,
                                              struct wmEventHandler_Keymap *handler,
                                              struct wmEventHandler_KeymapResult *km_result);
 
 void WM_event_get_keymap_from_toolsystem_fallback(struct wmWindowManager *wm,
+                                                  struct wmWindow *win,
                                                   struct wmEventHandler_Keymap *handler,
                                                   wmEventHandler_KeymapResult *km_result);
 void WM_event_get_keymap_from_toolsystem(struct wmWindowManager *wm,
+                                         struct wmWindow *win,
                                          struct wmEventHandler_Keymap *handler,
                                          wmEventHandler_KeymapResult *km_result);
 
@@ -293,6 +296,7 @@ void WM_event_set_keymap_handler_post_callback(struct wmEventHandler_Keymap *han
                                                                 void *user_data),
                                                void *user_data);
 void WM_event_get_keymaps_from_handler(wmWindowManager *wm,
+                                       struct wmWindow *win,
                                        struct wmEventHandler_Keymap *handler,
                                        struct wmEventHandler_KeymapResult *km_result);
 
@@ -302,6 +306,7 @@ wmKeyMapItem *WM_event_match_keymap_item(struct bContext *C,
 
 wmKeyMapItem *WM_event_match_keymap_item_from_handlers(struct bContext *C,
                                                        struct wmWindowManager *wm,
+                                                       struct wmWindow *win,
                                                        struct ListBase *handlers,
                                                        const struct wmEvent *event);
 
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index ef86df4a8e8..df4d2c13ba7 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2977,7 +2977,7 @@ static int wm_handlers_do_gizmo_handler(bContext *C,
 /** \name Handle Single Event (All Handler Types)
  * \{ */
 
-static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
+static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, ListBase *handlers)
 {
   const bool do_debug_handler =
       (G.debug & G_DEBUG_HANDLERS) &&
@@ -3020,7 +3020,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
       if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) {
         wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base;
         wmEventHandler_KeymapResult km_result;
-        WM_event_get_keymaps_from_handler(wm, handler, &km_result);
+        WM_event_get_keymaps_from_handler(wm, win, handler, &km_result);
         int action_iter = WM_HANDLER_CONTINUE;
         for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) {
           wmKeyMap *keymap = km_result.keymaps[km_index];
@@ -3161,10 +3161,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
 /* This calls handlers twice - to solve (double-)click events. */
 static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 {
-  int action = wm_handlers_do_intern(C, event, handlers);
-
   /* Will be NULL in the file read case. */
   wmWindow *win = CTX_wm_window(C);
+  int action = wm_handlers_do_intern(C, win, event, handlers);
+
   if (win == NULL) {
     return action;
   }
@@ -3188,7 +3188,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 
           CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG");
 
-          action |= wm_handlers_do_intern(C, event, handlers);
+          action |= wm_handlers_do_intern(C, win, event, handlers);
 
           event->val = val;
           event->type = type;
@@ -3247,7 +3247,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 
                 CLOG_INFO(WM_LOG_HANDLERS, 1, "handling CLICK");
 
-                action |= wm_handlers_do_intern(C, event, handlers);
+                action |= wm_handlers_do_intern(C, win, event, handlers);
 
                 event->val = KM_RELEASE;
                 event->x = x;
@@ -3259,7 +3259,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
         else if (event->val == KM_DBL_CLICK) {
           /* The underlying event is a press, so try and handle this. */
           event->val = KM_PRESS;
-          action |= wm_handlers_do_intern(C, event, handlers);
+          action |= wm_handlers_do_intern(C, win, event, handlers);
 
           /* revert value if not handled */
           if (wm_action_not_handled(action)) {
@@ -4020,6 +4020,7 @@ wmEventHandler_Keymap *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap
  * Follow #wmEventHandler_KeymapDynamicFn signature.
  */
 void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
+                                                  wmWindow *win,
                                                   wmEventHandler_Keymap *handler,
                                                   wmEventHandler_KeymapResult *km_result)
 {
@@ -4028,7 +4029,13 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
   const char *keymap_id_list[ARRAY_SIZE(km_result->keymaps)];
   int keymap_id_list_len = 0;
 
-  const Scene *scene = wm->winactive->scene;
+  /* NOTE(@campbellbarton): If `win` is NULL, this function may not behave as expected.
+   * Assert since this should not happen in practice.
+   * If it does, the window could be looked up in `wm` using the `area`.
+   * Keep NULL checks in run-time code since any crashes here are difficult to redo. */
+  BLI_assert_msg(win != NULL, "The window should always be set for tool interactions!");
+  const Scene *scene = win ? win->scene : NULL;
+
   ScrArea *area = handler->dynamic.user_data;
   handler->keymap_tool = NULL;
   bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL;
@@ -4041,7 +4048,7 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
   bool is_gizmo_highlight = false;
 
   if ((tref_rt && tref_rt->keymap_fallback[0]) &&
-      (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK)) {
+      (scene && (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK))) {
     bool add_keymap = false;
     /* Support for the gizmo owning the tool keymap. */
 
@@ -4100,6 +4107,7 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
 }
 
 void WM_event_get_keymap_from_toolsystem(wmWindowManager *wm,
+                                         wmWindow *UNUSED(win),
                                          wmEventHandler_Keymap *handler,
                                          wmEventHandler_KeymapResult *km_result)
 {
@@ -5257,11 +5265,12 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock)
  * \{ */
 
 void WM_event_get_keymaps_from_handler(wmWindowManager *wm,
+                                       wmWindow *win,
                                        wmEventHandler_Keymap *handler,
                                        wmEventHandler_KeymapResult *km_result)
 {
   if (handler->dynamic.keymap_fn != NULL) {
-    handler->dynamic.keymap_fn(wm, handler, km_result);
+    handler->dynamic.keymap_fn(wm, win, handler, km_result);
     BLI_assert(handler->keymap == NULL);
   }
   else {
@@ -5287,10 +5296,8 @@ wmKeyMapItem *WM_event_match_keymap_item(bContext *C, wmKeyMap *keymap, const wm
   return NULL;
 }
 
-wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C,
-                                                       wmWindowManager *wm,
-                                                       ListBase *handlers,
-                                                       const wmEvent *event)
+wmKeyMapItem *WM_event_match_keymap_item_from_handlers(
+    bContext *C, wmWindowManager *wm, wmWindow *win, ListBase *handlers, const wmEvent *event)
 {
   LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
     /* During this loop, UI handlers for nested menus can tag multiple handlers free. */
@@ -5301,7 +5308,7 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C,
       if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) {
         wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base;
         wmEventHandler_KeymapResult km_result;
-        WM_event_get_keymaps_from_handler(wm, handler, &km_result);
+        WM_event_get_keymaps_from_handler(wm, win, handler, &km_result);
         for (int km_index = 0; km_ind

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list