diff options
author | Julian Eisel <julian@blender.org> | 2022-07-14 20:21:56 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2022-07-14 20:21:56 +0300 |
commit | bdd0ac5bcebd6deb3d590ada9a3f25c6ddd58ea4 (patch) | |
tree | b60a608dc46c970e71eba27b8f753c60e9a030fd | |
parent | 1ef686bd26cc3c89849f41770ce76d7b94f169db (diff) |
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.
-rw-r--r-- | source/blender/editors/interface/interface_drag.cc | 4 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_dragdrop.cc | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 18 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 19 |
4 files changed, 37 insertions, 8 deletions
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) |