Through testing as well as brief web search it seems to me that switching modes with multiple selected objects only invokes the callback method for the active object for some reason. I hope someone can confirm or deny this so that I know whether or not I have to approach this problem by writing a convoluted spaghetti code to deal with all the edge cases for my project.
import bpy
layer_and_mode_changes = object()
def register_mode_listener(obj):
bpy.msgbus.subscribe_rna(
key=obj.path_resolve("mode", False),
owner=layer_and_mode_changes,
args=(obj,),
notify=on_mode_change,)
def on_mode_change(obj):
print(f"{obj.name}'s has changed")
for obj in bpy.context.selected_objects:
register_mode_listener(obj)
I can’t confirm the callback side, but I checked the data side on 4.5.12 and 5.2.0. Three cubes selected, Cube0 active, and after mode_set all three report obj.mode == ‘EDIT’, so the property genuinely changes on every selected object rather than just the active one. Whatever is going on is on the notify side.
One thing worth knowing if you try to reproduce it in a script: msgbus delivers nothing at all in --background, not even for an explicit publish_rna call. I got an empty callback list there, which looks exactly like a confirmation of your theory and is not one. Only trust what you see in a real UI session.
First of all thank you for taking the time to test out part of the problem as well as to reply back.
As for the obj.mode == ‘EDIT’ test, I’ve done that too and they’re all in edit mode despite the lack of notification to msgbus.
I’ve originally encountered this problem in a VSC project (Blender 4.1) and then tested out via script in both 4.1 and 5.2, and unfortunately the result is always the same.
The reason why it works like this and whatever is going on in the background, is beyond me. But if I had to guess it could just be a result of optimization, in other words, it’s an intended behaviour.