Search code examples
pythonmacoseventsmousesteam

CGEventPost does not always move the mouse macOS


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.


Solution

  • 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.