Close a popup with an OP call I have a invoke_props_dialog popup that shows a list of modifiers. It has a OK button that calls execute() and closes it:

I want to have a similar popup with two buttons, that'd do different stuff but still close the popup. So it's like having two executes:

So I changed popup type to invoke_popup and added two buttons as operators (screenshot above), however I can't figure out how to close the popup after I press a button. I know that with invoke_popup I can simply click anywhere outide the popup area to close it however I wonder if it's possible to imidiately close it with a single click.
Here's my code:
import bpy
from bpy.props import (
    BoolVectorProperty,
)

class TestOpA(bpy.types.Operator):
  bl_idname = &quot;object.test_op_a&quot;
  bl_label = &quot;My Button A&quot;
  
  def execute(self, context):
    print('executed A') 
    return {'FINISHED'}

class TestOpB(bpy.types.Operator):
  bl_idname = &quot;object.test_op_b&quot;
  bl_label = &quot;My Button B&quot;

  def execute(self, context):
    print('executed B')
    return {'FINISHED'}

class TestMainOp(bpy.types.Operator):
    &quot;&quot;&quot;&quot;&quot;&quot;
    bl_idname = &quot;object.test_main_op&quot;
    bl_label = &quot;Test Popup&quot;
    bl_options = {'REGISTER', 'UNDO'}

    selection: BoolVectorProperty(
        size=2,
        options={'SKIP_SAVE'}
    )

    def draw(self, context):
        layout = self.layout

        layout.prop(self, 'selection', index=0, text='Prop Name 1',toggle=True)
        layout.prop(self, 'selection', index=1, text='Prop Name 2',toggle=True)
        
        column = layout.column()
        r = column.split(factor=0.5)
        o1 = r.operator(&quot;object.test_op_a&quot;)
        r.operator(&quot;object.test_op_b&quot;)

    def invoke(self, context, event):
        wm = context.window_manager
        wm.invoke_popup(self)
        return {'RUNNING_MODAL'}
    
    def execute(self, context):
        return {'FINISHED'}


def register():
    bpy.utils.register_class(TestMainOp)
    bpy.utils.register_class(TestOpA)
    bpy.utils.register_class(TestOpB)

def unregister():
    bpy.utils.unregister_class(TestMainOp)
    bpy.utils.unregister_class(TestOpA)
    bpy.utils.unregister_class(TestOpB)

if __name__ == &quot;__main__&quot;:
    register()
One way to solve it would be by moving the cursor out of the panel temporarily, like so:
def close_panel(event):
    x, y = event.mouse_x, event.mouse_y
    bpy.context.window.cursor_warp(10, 10)

    move_back = lambda: bpy.context.window.cursor_warp(x, y)
    bpy.app.timers.register(move_back, first_interval=0.001)

How this works is: first, we grab the X and Y values of the current mouse position, because in the next line the event is updated, and we lose the original coordinates.
Next, we move the cursor way over to the bottom left corner of the screen (not 0, 0 though because that doesn't close the panel for some reason).
Then, we prepare a function which moves the cursor back to where it was originally.
And finally, we use bpy.app.timers to delay starting our function by 1 millisecond, to give Blender time to realize the cursor is no longer on the panel, and close it.