Different output in mouse suppression pynput.mouse

432 Views Asked by At

I am trying to lock the mouse pointer but still receive mouse movements. I almost achieved this goal by adding suppress=True in the pynput.mouse.Listener Here:

def on_move(x, y):
    print(x, y)


with pynput.mouse.Listener(on_move=on_move, suppress=True) as listener:
    listener.join()

The problem is I get an output like this when I start moving the mouse: (x on left, y on right)

681 551
681 550
681 550
682 550
681 551
681 550
682 550
682 551

But want to receive the movement of the mouse like this:

1 0 (mouse moved one pixel right)
0 -1 (mouse moved one pixel up)
-1 1 (mouse moved one left and one pixel down)
1 1 (mouse moved one right and one pixel down)
...

When moving the mouse continuously right the output is this:

524 364
525 364
524 364
525 364
524 364
525 364
524 364
525 364

Which means using the previous x as a variable like this x - prev_x will not be affective and will print this:

1 0
-1 0
1 0
-1 0
1 0
-1 0

Not this: (The output I would like)

1 0
1 0
1 0
1 0
1 0
1 0
2

There are 2 best solutions below

1
On

After looking at the edited question and seeing that your issue is that you are suppressing mouse movement, the output is logical.

1 0    > you are moving the mouse 1 pixel to the right
-1 0   > because the mouse is supressed it is moved back 1 pixel to it's original position

This output is entirely expected, when you supress the mouse.

I don't think there is a good way of supressing the mouse, that will allow for your desired output.

If you really need the user mouse input and absolutely don't want the mouse to actually move on screen, but to have it do something in your program, you might want to look for a different library to use.

3
On

It seems like the program is doing as you want it to already,

but instead of stating the mouse position as a relative position (something like: "1, -1"), it is being output as an absolute position (something like: "681, 550").

In the case, that this is really your issue, the fix is simple:

lastx = 0
lasty = 0

def on_move(x, y):
    global lastx, lasty
    print(x - lastx, y - lasty)
    lastx = x
    lasty = y

that way on_move() will print how much your mouse moved since the last call of the function.

The vertical movement will however be "inverted", meaning a change in the y-value of -1 is not moving 1 pixel down, but 1 pixel up.

To make the y decrease instead of increasing when moving down this should work:

lastx = 0
lasty = 0

def on_move(x, y):
    global lastx, lasty
    print(x - lastx, lasty - y)
    lastx = x
    lasty = y

Note that lasty and y are swapped here, resulting in the printed vertical movement being (-1) times whatever it would be otherwise.