The same problem here a few months ago when workspace was changed by script. The sticking point: bpy.context.window.workspace = bpy.data.workspaces[ANY]
toggles the workspace not before the script is finished.
"It’s not supported to immediately refresh the UI. That happens
delayed after scripts (and built-in operators) finish executing."
https://devtalk.blender.org/t/set-a-choosed-workspace-to-active/3318/3
Try:
import bpy
print("before:" , bpy.context.workspace)
bpy.context.window.workspace = bpy.data.workspaces['Layout']
print("after", bpy.context.workspace)
the same workspace will be returned.
So we need a trigger that will operate when script is finished. The message bus system is suitable for this. https://docs.blender.org/api/current/bpy.msgbus.html#module-bpy.msgbus
The script attaches an msgbus to window.workspace and saves the region_data of Scripting workspace before changed. Function msgbus_event
is called after the script and sets the saved values in region_data of workspace Layout (tested 2.9.3 and 3.3.2)
import bpy
# get region_data from active ws
def get_region_data():
area_v3d = [a for a in bpy.context.screen.areas if a.type == 'VIEW_3D'] # area View3D
if area_v3d:
region_v3d = [r for r in area_v3d[0].regions if r.type == 'WINDOW'][0] # main region
region_data_v3d = region_v3d.data # region_data
return region_data_v3d
else:
print("no 3DView in workspace '%s'" % bpy.context.workspace.name) # e.g. ws Rendering
return None
# msgbus callback
def msgbus_event():
rv3d_new = get_region_data() # get new region_data
if rv3d_new:
print_region_datas(rv3d_new)
# set values
rv3d_new.view_location = rv3d_old.view_location
rv3d_new.view_matrix = rv3d_old.view_matrix
# clear if only first change
bpy.msgbus.clear_by_owner(bpy)
# print region values
def print_region_datas(rv3d):
print("[%s]" % bpy.context.window.workspace.name)
print("view location:", rv3d.view_location)
print("view matrix:", rv3d.view_matrix)
# prevent double entries
def register():
# msgbus clear
bpy.msgbus.clear_by_owner(bpy)
# msgbus new
bpy.msgbus.subscribe_rna(key=(bpy.types.Window,"workspace"), owner=bpy, args=(), notify=msgbus_event,)
def unregister():
bpy.msgbus.clear_by_owner(bpy)
if __name__ == "__main__":
register()
# testcall from ws Scripting
global rv3d_old # available for msgbus_event
rv3d_old = get_region_data() # region_data Scripting
print_region_datas(rv3d_old)
bpy.context.window.workspace = bpy.data.workspaces['Layout'] # change ws
context.area.tag_redraw()
$\endgroup$rv3d_location = context.region_data.view_location.copy()
$\endgroup$