I'm making a simple script that will move some vertices by using modal operator. I'm using mouse position value as a variable but I noticed when the cursor is outside of blender's window it stops incrementing the value. For example, blender's normal scaling operator keeps gettign the mouse position even if the mouse is outside of the window.

How to get the mouse position even if it's outside of the window? or is there better way to do it? Below is a script that I'm testing on.

Thank you.

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

# Init
def __init__(self):

# invoke
def invoke(self, context, event):
    self.init_loc_x = context.object.location.x
    self.init_loc_x = context.object.location.y
    self.mouse_initial_x = event.mouse_x
    self.mouse_initial_y = event.mouse_y
    self.value = 0
    #self.value = event.mouse_xa
    return {'RUNNING_MODAL'}

# Actual content
def execute(self, context):
    context.object.location.x = self.init_loc_x + self.value / 100.0
    return {'FINISHED'}

# While loop
def modal(self, context, event):
    if event.type == 'MOUSEMOVE':  # Apply
        # Use UP / DOWN
        self.value = event.mouse_y - self.mouse_initial_y
    elif event.type == 'LEFTMOUSE':  # Confirm
        return {'FINISHED'}
    elif event.type in {'RIGHTMOUSE', 'ESC'}:  # Cancel
        context.object.location.x = self.init_loc_x
        return {'CANCELLED'}

    return {'RUNNING_MODAL'}

# End
def __del__(self):
  • $\begingroup$ Does the scaling operator ("S") keep getting the event outside the window, or does it reset the mouse location to the opposite of where it exits the region? Eg if it exits right, it reappears left. I wonder if could mouse_x and mouse_prev_x to do something similar. $\endgroup$
    – batFINGER
    Nov 7, 2017 at 13:10
  • $\begingroup$ I think that's the way scaling or moving operator are using internally.Forcefully Reset the mouse position if it went out side of the window. $\endgroup$
    – Miumiu
    Nov 8, 2017 at 21:08

1 Answer 1


The following script will check if the mouse is outside the 3d_view window, not Blender's window. It's not exactly what you asked for, but I hope it'll help:

def click_outside_3d_view(event):
    area, viewport = get_3d_area_region()
    return not (0 < event.mouse_region_x < viewport.width and 0 < event.mouse_region_y < viewport.height)

def get_3d_area_region():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        return area, region

***** Edit *****

I'm not completely sure, but it seems that the mouse_region_x/y are relative to the original region that the operator was running in. The following code is more foolproof:

def click_inside_3d_view(event):
    for area in get_3d_areas():
        if 0 < event.mouse_x-area.x < area.width and 0 < event.mouse_y-area.y < area.height:
            return True
    return False

def get_3d_areas():
    for screen in bpy.data.screens:
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                yield area
  • $\begingroup$ Thank you for the answer! It might help. I think one idea is to reset the mouse position if mouse left the VIEW_3D window. $\endgroup$
    – Miumiu
    Nov 8, 2017 at 21:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .