Page MenuHome

Workspace duplicate resets my tweak tool back to default select box
Confirmed, NormalPublicTO DO


System Information
Operating system: Windows-7-6.1.7601-SP1 64 Bits
Graphics card: GeForce GTX 660 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 442.59

Blender Version
Broken: version: 2.83 (sub 11), branch: master, commit date: 2020-03-30 22:07, hash: rBb555b8dedce0
Worked: ???

Short description of error
And EACH time I create new workspace I forced to change it back to tweak, because i prefer it.
It is a pain in the … code.

Why do I think it is a bug? Because scale cage or annotation are saved.

Event Timeline

Vyacheslav (hitrpr) updated the task description. (Show Details)
Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Confirmed.Apr 3 2020, 2:46 PM

Not really sure how this is supposed to work...

Because scale cage or annotation are saved

These dont seem to be unique/saved per workspace in general.
For example: If you choose different scale tools [Scale for one Scale Cage for the other] for different workspaces, then switch between the workspaces back and forth:

  • these are kept separate if the scale category is selected in both workspaces
  • these magically sync between the workspaces again if different categories are selected [lets say scale category in one, annotate category in the other...]

note there is a TODO comment in ED_workspace_duplicate()

/* TODO(campbell): tools */

CC @Campbell Barton (campbellbarton)
CC @Julian Eisel (Severin)

Will confirm for now [without saying it is a bug].

@Philipp Oeser (lichtwerk) I see syncrinization for scale/annotation and, perhaps, it is good.
But tweak tool is not syncronized and do not inherit previous state.
So, at least, it is inconsistency and annoying thing. And may be error/flaw/missing in the code.

Julian Eisel (Severin) changed the subtype of this task from "Report" to "To Do".May 19 2020, 7:28 PM

This seems to work, but I'd prefer @Campbell Barton (campbellbarton) to check over this. I'm not sure at all which members need to be copied over exactly.

diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index bc6a4b23609..33a7a8800cf 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -279,7 +279,8 @@ bool ED_workspace_change(struct WorkSpace *workspace_new,
                          struct bContext *C,
                          struct wmWindowManager *wm,
                          struct wmWindow *win) ATTR_NONNULL();
-struct WorkSpace *ED_workspace_duplicate(struct WorkSpace *workspace_old,
+struct WorkSpace *ED_workspace_duplicate(struct bContext *C,
+                                         struct WorkSpace *workspace_old,
                                          struct Main *bmain,
                                          struct wmWindow *win);
 bool ED_workspace_delete(struct WorkSpace *workspace,
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 8feef0c675a..4dc201bf809 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -53,6 +53,7 @@
 #include "BLT_translation.h"
 #include "WM_api.h"
+#include "WM_toolsystem.h"
 #include "WM_types.h"
 #include "screen_intern.h"
@@ -185,7 +186,10 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager
  * Duplicate a workspace including its layouts. Does not activate the workspace, but
  * it stores the screen-layout to be activated (BKE_workspace_temp_layout_store)
-WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindow *win)
+WorkSpace *ED_workspace_duplicate(bContext *C,
+                                  WorkSpace *workspace_old,
+                                  Main *bmain,
+                                  wmWindow *win)
   WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook);
   ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old);
@@ -196,7 +200,7 @@ WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindo
   workspace_new->order = workspace_old->order;
   BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids);
-  /* TODO(campbell): tools */
+  WM_toolsystem_refs_duplicate_to_workspace(C, workspace_old, workspace_new);
   LISTBASE_FOREACH (WorkSpaceLayout *, layout_old, layouts_old) {
     WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(
@@ -279,7 +283,7 @@ static int workspace_new_exec(bContext *C, wmOperator *UNUSED(op))
   wmWindow *win = CTX_wm_window(C);
   WorkSpace *workspace = workspace_context_get(C);
-  workspace = ED_workspace_duplicate(workspace, bmain, win);
+  workspace = ED_workspace_duplicate(C, workspace, bmain, win);
   WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace);
diff --git a/source/blender/windowmanager/WM_toolsystem.h b/source/blender/windowmanager/WM_toolsystem.h
index 163f37be974..d4582b5c9c3 100644
--- a/source/blender/windowmanager/WM_toolsystem.h
+++ b/source/blender/windowmanager/WM_toolsystem.h
@@ -54,6 +54,9 @@ struct bToolRef *WM_toolsystem_ref_find(struct WorkSpace *workspace, const bTool
 bool WM_toolsystem_ref_ensure(struct WorkSpace *workspace,
                               const bToolKey *tkey,
                               struct bToolRef **r_tref);
+void WM_toolsystem_refs_duplicate_to_workspace(struct bContext *C,
+                                               const struct WorkSpace *from_workspace,
+                                               struct WorkSpace *to_workspace);
 struct bToolRef *WM_toolsystem_ref_set_by_id_ex(struct bContext *C,
                                                 struct WorkSpace *workspace,
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index 72969f34162..22f69b8ef40 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -126,6 +126,19 @@ bool WM_toolsystem_ref_ensure(struct WorkSpace *workspace, const bToolKey *tkey,
   return true;
+void WM_toolsystem_refs_duplicate_to_workspace(bContext *C,
+                                               const WorkSpace *from_workspace,
+                                               WorkSpace *to_workspace)
+  LISTBASE_FOREACH (bToolRef *, tref, &from_workspace->tools) {
+    bToolRef *new_tref;
+    WM_toolsystem_ref_ensure(
+        to_workspace, &(bToolKey){.space_type = tref->space_type, .mode = tref->mode}, &new_tref);
+    STRNCPY(new_tref->idname_fallback, tref->idname_fallback);
+    WM_toolsystem_ref_set_from_runtime(C, to_workspace, new_tref, tref->runtime, tref->idname);
+  }
 /** \} */
 static void toolsystem_unlink_ref(bContext *C, WorkSpace *UNUSED(workspace), bToolRef *tref)