In my script, I've created an Operator, a PropertiesGroup which holds the properties of my operator and a Panel which lets the user change the properties and start the operator running. My operator uses mouse input, so it returns ```RUNNING_MODAL``` for the ```LEFTMOUSE``` event (and many other events too). Unfortunately, this prevents the user from using the Panel while the operator is running. If I return ```PASS_THROUGH``` from the left mouse event instead, I can use the panel but it has the side effect that my operator never gets the ```RELEASE``` event should the user click within the panel. This has the effect of leaving my operator in a state where it thinks the mouse is permanently held down. Is there some way to balance the UI between these? I'd like to be able to use the panel without having to exit my operator first. In the below program, if you start the operator, you cannot change the panel control until you press enter to exit it: ``` import bpy class NormalToolSettings(bpy.types.PropertyGroup): normal : bpy.props.FloatVectorProperty( name="Normal", description="Direction of normal in Fixed mode", default = (1, 0, 0), subtype="DIRECTION" ) #------------------------------- class ModalDrawOperator(bpy.types.Operator): """Adjust normals""" bl_idname = "kitfox.normal_tool" bl_label = "Normal Tool Kitfox" dragging = False def mouse_move(self, context, event): mouse_pos = (event.mouse_region_x, event.mouse_region_y) ctx = bpy.context if self.dragging: print("mouse drag to " + str(event.mouse_region_x) + ", " + str(event.mouse_region_y)) def mouse_down(self, context, event): if event.value == "PRESS": self.dragging = True elif event.value == "RELEASE": self.dragging = False def modal(self, context, event): context.area.tag_redraw() if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}: # allow navigation return {'PASS_THROUGH'} elif event.type == 'MOUSEMOVE': self.mouse_move(context, event) if self.dragging: return {'RUNNING_MODAL'} else: return {'PASS_THROUGH'} elif event.type == 'LEFTMOUSE': self.mouse_down(context, event) # return {'PASS_THROUGH'} return {'RUNNING_MODAL'} elif event.type in {'RET'}: return {'FINISHED'} elif event.type in {'PAGE_UP', 'RIGHT_BRACKET'}: if event.value == "PRESS": brush_radius = context.scene.my_tool.radius brush_radius = brush_radius + .1 context.scene.my_tool.radius = brush_radius return {'RUNNING_MODAL'} elif event.type in {'PAGE_DOWN', 'LEFT_BRACKET'}: if event.value == "PRESS": brush_radius = context.scene.my_tool.radius brush_radius = max(brush_radius - .1, .1) context.scene.my_tool.radius = brush_radius return {'RUNNING_MODAL'} elif event.type in {'RIGHTMOUSE', 'ESC'}: return {'CANCELLED'} return {'PASS_THROUGH'} def invoke(self, context, event): if context.area.type == 'VIEW_3D': # the arguments we pass the the callback args = (self, context) # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' self._context = context context.area.tag_redraw() context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} else: self.report({'WARNING'}, "View3D not found, cannot run operator") return {'CANCELLED'} #------------------------------- class NormalToolPropsPanel(bpy.types.Panel): """Properties Panel for the Normal Tool on tool shelf""" bl_label = "Normal Tool" bl_idname = "OBJECT_PT_normal_tool_props" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = "Kitfox2" def draw(self, context): layout = self.layout scene = context.scene settings = scene.my_tool col = layout.column(); col.operator("kitfox.normal_tool", text="Start Normal Tool") col.prop(settings, "normal") def register(): bpy.utils.register_class(NormalToolSettings) bpy.utils.register_class(ModalDrawOperator) bpy.utils.register_class(NormalToolPropsPanel) bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=NormalToolSettings) def unregister(): bpy.utils.unregister_class(NormalToolSettings) bpy.utils.unregister_class(ModalDrawOperator) bpy.utils.unregister_class(NormalToolPropsPanel) del bpy.types.Scene.my_tool if __name__ == "__main__": register() ```