Modal Operator Fixes I am studying Python programming for Blender and recently started dealing with modal operators. The question I have is: There is a double call from the event of the modal operator for key-up and key-down of the specific keys. How can that be reduced to one call? Also, this is useful if it runs silently in the background without taking up resources. Is this the case for the modal operator, or are there caveats?

Here is the derivative code I'm working with that displays to the console:

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def execute(self, context):
        print("This is the modal operator")
        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'ESC':  # Confirm
            print("This is finished")
            return {'FINISHED'}
        elif event.alt:
            if event.type == 'P':  # Confirm
                print("This is a continuous pass through")
            return {'PASS_THROUGH'}

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        print("This is the invoker")

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)

bpy.ops.object.modal_operator('INVOKE_DEFAULT')
Thanks again batFINGER

The following works great:

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def execute(self, context):
        print("This is the modal operator")
        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'ESC':  # Confirm
            print("This is finished")
            return {'FINISHED'}
 # .value == 'PRESS' will trigger the event once. 
 # or do: if event.type == 'P' and if.event.value == 'PRESS':
        elif event.alt:
            if event.type == 'P':
                if.event.value == 'PRESS': # Confirm
                    print("This is a continuous pass through")
            return {'PASS_THROUGH'}

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        print("This is the invoker")

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)

bpy.ops.object.modal_operator('INVOKE_DEFAULT')