0

I have been encountering issues when trying to move the mouse programmatically in macOS Sierra using Quartz Event Services in a Python environment.

For Example:

When I run this script:

from Quartz.CoreGraphics import CGEventCreateMouseEvent
from Quartz.CoreGraphics import CGEventPost
from Quartz.CoreGraphics import kCGMouseButtonLeft
from Quartz.CoreGraphics import kCGEventMouseMoved
from Quartz.CoreGraphics import kCGHIDEventTap


def MouseMove(x, y):
        event = CGEventCreateMouseEvent(None, kCGEventMouseMoved, (x, y), kCGMouseButtonLeft)
        CGEventPost(kCGHIDEventTap, event)

MouseMove(100, 100)

Everything works great and the mouse gets moved to (x: 100, y: 100).

HOWEVER, for some reason this procedure does not manage to move the mouse in certain applications. Specifically in my case my MacBook is running Call of Duty: Modern Warfare 2 on Steam and moving the mouse in this manner does not register in this application but interestingly enough I am still able to generate mouse clicks in the application using CGEventPost just not mouse movements.

So I've done some research to try to figure out why this is happening and the closest thing I could find online relating to my problem is this question on SO and the reason I mention this is because I'm wondering if like in the linked question I need to call a method similar to something like CGEventSetIntegerValueField only instead of updating the kCGMouseEventClickState update a mouse event pertaining to the movement of the mouse so that the application will know that the mouse has indeed moved. However I have not found such a method in the CGEventField documentation and I just feel like I'm missing something or maybe this isn't even involved with problem but this is the only lead I could find.

Please help. I would appreciate any suggestions anyone might have.

Garret Kaye
  • 2,412
  • 4
  • 21
  • 45

1 Answers1

1

I found the answer.

I changed this line:

event = CGEventCreateMouseEvent(None, type, (x, y), kCGMouseButtonLeft)
CGEventPost(kCGHIDEventTap, event)

To this:

CGPostMouseEvent((x, y), True, 0, False)

And of course imported: CGPostMouseEvent

As a result, moving the mouse works everywhere and in all applications. The reason why it works is because it turns out CGPostMouseEvent occurs on a deeper level of the local machine than CGEventPost.

Garret Kaye
  • 2,412
  • 4
  • 21
  • 45
  • Thank you for posting the reply. I encountered the same issue using Unity. This issue reproduces with all the following modules: pynput, pyautogui and autopy. In the source of these modules they all rely on CGEventCreateMouseEvent which prevents navigation in 3D Viewports. As of today CGPostMouseEvent is flagged as deprecated. Is there another method to update the mouse position within a 3D Viewport that is not deprecated ? – Diego Trazzi Aug 11 '20 at 19:54