# Modal Operators: Click Object Event

I'm currently working on a python tool using a modal operator. Now I know to finish the operation I can use:

if event.type == 'LEFTMOUSE':
return {'FINISHED'}


However it seems not to count as a 'LEFTMOUSE' when I click (select) an object! I also tried 'SELECTMOUSE' which doesn't do anything.

What I would like to do is store the clicked object, and then automatically finish the modal operator.

Why type.event ?

You should get your event.type, and you may want to compare the event.value as well:

def modal(self, context, event):
if event.type in {"LEFTMOUSE"} and event.value == "RELEASE":
return {'FINISHED'}
return {'PASS_THROUGH'}


Also, it might be possible that an event been stop propagate in most of the event handling system. You might need to check the context carefully to see what is the main problem.

• sorry I actually meant event.type and also got that right in my script. when I use the value RELEASE, clicking an object does end the modal but therefore doesn't select the object... – Mantikator May 14 at 8:32
• So you want to check something after you click and select an object? I don't know if it is safe to do relative thing in a same event loop. Interesting problem, I will test a little bit for it. – Hikariztw May 14 at 11:59

I have a solution and it's actually very simple:

class OBJECT_OT_do_stuff(bpy.types.Operator):
bl_idname = "object.do_stuff"
bl_label = "Do Stuff"

origSel: None

@classmethod
def poll(cls, context):
return context.active_object is not None

def modal(self, context, event):
# Update selection
curSel = context.selected_objects[-1]

# On selecting new object
if curSel is not self.origSel:
print("selection was changed")
return {'FINISHED'}

elif event.type in {'RIGHTMOUSE', 'ESC'}:
print("cancelled operation")
return {'CANCELLED'}

else:
return {'PASS_THROUGH'}

return {'RUNNING_MODAL'}

def invoke(self, context, event):
self.origSel = context.object
# Execute Modal Operation

An important thing to note is that in order for that to work you need to call the function with the invoke argument :bpy.ops.object.do_stuff('INVOKE_DEFAULT')
• Using the last in the selected list could make this a little random, Would use curSel = context.object – batFINGER May 15 at 8:50