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()
```