How to add a pre-draw hook to current context workspace.tools change?
I attempted to get there using bpy.types.SpaceView3D.draw_handler_add(...)
which as it runs on every draw, checks if workspace.tools changed, and if it changed, run my callback, but my callback wants to add its own SpaceView3D.draw_handler_add
and doing it this way adds it a frame-too-late, leaving the view port undrawn until a user event repaints the screen.
I found this post online https://devtalk.blender.org/t/update-property-when-active-tool-changes/11467/12
summary: maybe there is a mainline callback new https://developer.blender.org/D10635
AFWS Jan '20
@kaio
This seem like a better solution. It’s kind of a mystery code, cause I couldn’t figure out where you got that code info ,but then started looking at the space_toolsystem_common.py file. kaio AFWS Jan '20
Just realized there might be a cleaner way of getting callbacks for active tools using the msgbus. Since workspace tools aren’t rna properties themselves, figured it’s possible to monitor the bpy_prop_collection which changes with the tool.
The handle is the workspace itself, so shouldn’t have to worry about keeping a reference. The subscription lasts until a new file is loaded, so add a load_post callback which reapplies it.
Note this doesn’t proactively subscribe to workspaces added afterwards. Might need a separate callback for that :joy:
import bpy def rna_callback(workspace): idname = workspace.tools[-1].idname print(idname) def subscribe(workspace): bpy.msgbus.subscribe_rna( key=ws.path_resolve("tools", False), owner=workspace, args=(workspace,), notify=rna_callback) if __name__ == "__main__": ws = bpy.context.workspace subscribe(bpy.context.workspace) # Subscribe to all workspaces: if 0: for ws in bpy.data.workspaces: subscribe(bpy.context.workspace) # Clear all workspace subscriptions if 0: for ws in bpy.data.workspaces: bpy.msgbus.clear_by_owner(ws)