Locking the mouse cursor within the area in Blender

Sometimes it may be necessary to prevent the mouse cursor from going beyond the boundaries of a particular Blender area. For example, when grabbing and dragging a mesh with the mouse, the captured mesh should not leave the 3D Viewport area, not to be above another type of area, for example, above the Node Editor or Text Editor areas.

The easiest way to achieve the desired behavior of the mouse pointer is to add the “GRAB_CURSOR” and “BLOCKING” values ​​to the bl_options parameter of the operator:

Now, if we make the operator modal, when it is executed, the cursor will be limited to only the work area from which the operator was called.

Let’s define a modal operator with a mouse pointer lock through the operator’s parameters:

Now, when we execute this operator:

The mouse cursor cannot be moved outside the current area.

To return the cursor to the ability to move freely, we need just to interrupt the execution of the modal operator by clicking the right mouse button or pressing the ESC key.

This method of locking the cursor is simple and convenient, but it enables the “continuous grab” – at the moment when the mouse pointer goes beyond the work area on one side, it immediately returns to this area, but from the opposite side.

This is useful, for example, when dragging or scaling objects. However, sometimes we just need to freeze the cursor on the border of the area, without moving it anywhere else.

We can implement such mouse pointer behavior by controlling over the cursor coordinates, so that when the value of these coordinates approaches the borders of the area, “freeze” them.

Let’s change the code of our modal operator as follows:

Here we removed the previously set “bl_options” parameter of the operator and start to control the MOUSEMOVE event – control over the movement of the mouse cursor in the “modal” function of the operator.

Handling the MOUSEMOVE event allows us to get the coordinates of the mouse cursor inside the current work area through the variables event.mouse_region_x – the X coordinate of the cursor, and event.mouse_region_y – the Y coordinate of the mouse cursor.

The dimensions of the current area are changed from 0 to context.region.width horizontally, and from 0 to context.region.height vertically.

So, at any time we can compare the cursor coordinates with the dimensions of the current area to check if the mouse cursor has gone beyond them.

The cursor coordinates can be compared to zero and to the exact width and height of the area, or, as in our example, leaving a padding of 10 pixels from the area border.

If the cursor coordinates go beyond the dimensions of the area, we can return the cursor back by force moving it to the desired position ​​using the cursor_warp function.

For example, calling the cursor_warp function with parameters (0, 0):

will set the mouse cursor to a point on the current area with the x = 0 and y = 0 coordinates.

In our case, we set the coordinates for the cursor on the border of the area, to which it approaches less than 10.

When we execute this operator:

the cursor, when approaching the boundaries of the area, will always remain inside and, unlike our first version of the operator, will not jump to the opposite side.

To return the cursor to its standard behavior, still click the right mouse button or press the ESC key on the keyboard.

0 0 votes
Article Rating
Notify of
0 Comment
Inline Feedbacks
View all comments