[Bf-blender-cvs] [bdd0ac5bceb] master: Fix `on_drag_start` handler not getting ID when dragging from Outliner

Julian Eisel noreply at git.blender.org
Thu Jul 14 20:03:18 CEST 2022


Commit: bdd0ac5bcebd6deb3d590ada9a3f25c6ddd58ea4
Author: Julian Eisel
Date:   Thu Jul 14 19:21:56 2022 +0200
Branches: master
https://developer.blender.org/rBbdd0ac5bcebd6deb3d590ada9a3f25c6ddd58ea4

Fix `on_drag_start` handler not getting ID when dragging from Outliner

We would first invoke the dragging, and then set the drag data (like the
ID or the dragged modifier), so the `wmDropBox.on_drag_start()` handler
wouldn't be able to access this. This broke dragging some IDs from the
Outliner, noticed in D15333.

It's now possible to first create/request drag data, extend it, and then
invoke the actual dragging. The normal function to start dragging
returns `void` now instead of `wmDrag *`, so the drag data can't easily
be modified after starting anymore.

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

M	source/blender/editors/interface/interface_drag.cc
M	source/blender/editors/space_outliner/outliner_dragdrop.cc
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_dragdrop.c

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

diff --git a/source/blender/editors/interface/interface_drag.cc b/source/blender/editors/interface/interface_drag.cc
index 4c68870b2c7..1db3db32411 100644
--- a/source/blender/editors/interface/interface_drag.cc
+++ b/source/blender/editors/interface/interface_drag.cc
@@ -122,7 +122,7 @@ bool ui_but_drag_is_draggable(const uiBut *but)
 
 void ui_but_drag_start(bContext *C, uiBut *but)
 {
-  wmDrag *drag = WM_event_start_drag(C,
+  wmDrag *drag = WM_drag_data_create(C,
                                      but->icon,
                                      but->dragtype,
                                      but->dragpoin,
@@ -136,6 +136,8 @@ void ui_but_drag_start(bContext *C, uiBut *but)
     WM_event_drag_image(drag, but->imb, but->imb_scale);
   }
 
+  WM_event_start_prepared_drag(C, drag);
+
   /* Special feature for assets: We add another drag item that supports multiple assets. It
    * gets the assets from context. */
   if (ELEM(but->dragtype, WM_DRAG_ASSET, WM_DRAG_ID)) {
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc
index c72080be811..7435fa50a93 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.cc
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc
@@ -1455,7 +1455,7 @@ static int outliner_item_drag_drop_invoke(bContext *C,
                                        TSE_GPENCIL_EFFECT_BASE);
 
   const int wm_drag_type = use_datastack_drag ? WM_DRAG_DATASTACK : WM_DRAG_ID;
-  wmDrag *drag = WM_event_start_drag(C, data.icon, wm_drag_type, nullptr, 0.0, WM_DRAG_NOP);
+  wmDrag *drag = WM_drag_data_create(C, data.icon, wm_drag_type, nullptr, 0.0, WM_DRAG_NOP);
 
   if (use_datastack_drag) {
     TreeElement *te_bone = nullptr;
@@ -1545,6 +1545,8 @@ static int outliner_item_drag_drop_invoke(bContext *C,
     WM_drag_add_local_ID(drag, data.drag_id, data.drag_parent);
   }
 
+  WM_event_start_prepared_drag(C, drag);
+
   ED_outliner_select_sync_from_outliner(C, space_outliner);
 
   return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index f337dd9d89a..44c5b86857d 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -1214,10 +1214,24 @@ int WM_operator_flag_only_pass_through_on_press(int retval, const struct wmEvent
 /* Drag and drop. */
 
 /**
- * Note that the pointer should be valid allocated and not on stack.
+ * Start dragging immediately with the given data.
+ * Note that \a poin should be valid allocated and not on stack.
  */
-struct wmDrag *WM_event_start_drag(
+void WM_event_start_drag(
     struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
+/**
+ * Create and fill the dragging data, but don't start dragging just yet (unlike
+ * #WM_event_start_drag()). Must be followed up by #WM_event_start_prepared_drag(), otherwise the
+ * returned pointer will leak memory.
+ *
+ * Note that \a poin should be valid allocated and not on stack.
+ */
+wmDrag *WM_drag_data_create(
+    struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
+/**
+ * Invoke dragging using the given \a drag data.
+ */
+void WM_event_start_prepared_drag(struct bContext *C, wmDrag *drag);
 void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale);
 void WM_drag_free(struct wmDrag *drag);
 void WM_drag_data_free(int dragtype, void *poin);
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 546ba795892..36bd69a9b25 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -175,16 +175,14 @@ static void wm_dropbox_invoke(bContext *C, wmDrag *drag)
   }
 }
 
-wmDrag *WM_event_start_drag(
+wmDrag *WM_drag_data_create(
     struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
 {
-  wmWindowManager *wm = CTX_wm_manager(C);
   wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
 
   /* Keep track of future multi-touch drag too, add a mouse-pointer id or so. */
   /* if multiple drags are added, they're drawn as list */
 
-  BLI_addtail(&wm->drags, drag);
   drag->flags = flags;
   drag->icon = icon;
   drag->type = type;
@@ -226,9 +224,22 @@ wmDrag *WM_event_start_drag(
   }
   drag->value = value;
 
+  return drag;
+}
+
+void WM_event_start_prepared_drag(bContext *C, wmDrag *drag)
+{
+  wmWindowManager *wm = CTX_wm_manager(C);
+
+  BLI_addtail(&wm->drags, drag);
   wm_dropbox_invoke(C, drag);
+}
 
-  return drag;
+void WM_event_start_drag(
+    struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
+{
+  wmDrag *drag = WM_drag_data_create(C, icon, type, poin, value, flags);
+  WM_event_start_prepared_drag(C, drag);
 }
 
 void wm_drags_exit(wmWindowManager *wm, wmWindow *win)



More information about the Bf-blender-cvs mailing list