automating mouse movementson Linux X (or via VNC)

From a python script I'd like to be able to move the mouse to certain
absolute coordinates on the screen.


There's no problems calling an external program with subprocess.popen,
as I do not want to perform many movements.

The mouse can jump it doesn't have to visibly move to the target coordinate.



What would you suggest to achieve this on Linux Ubuntu 10.4?

Lateron it would be intersting to acheive the same on a Windows PC


One idea, that I had (for a cross platform solution) would be to start a
VNC server on localhost and the current display and run a small custom
VNC client, which will only control the mouse.

However I have no idea how easy it would be to use a custom VNC client
for moving the mouse.


I read about python-vnc-viewer but don't know how complex it would be to
use it as a base for 'just moving the mouse'



Thanks for any suggestions and ideas







LVL 19
gelonidaAsked:
Who is Participating?
 
-Richard-Commented:
The best solution by far in the Windows environment is Mark Hammond's "PyWin32", which essentially offers a complete Python interface to the Windows SDK.   Anything you could do by programming directly to the Windows system APIs in C or C++ is easily available directly from any Python program, with cursor movement being the least of its capabilities.   It can be downloaded from here:  http://sourceforge.net/projects/pywin32/  and once installed, the following code should get you started.  

import win32api, win32con
def click(x,y):
    win32api.SetCursorPos((x,y))
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
click(10,10)

Unfortunately, this option only works under Windows.  I'm not aware off the top of my head of a good cross-platform solution,
0
 
SuperdaveCommented:
Probably the best way from Python would be to install the Xlib library for Python, create a display, and call its warp_pointer(x,y) method.  Looks like it should be simple except I tried it and it didn't work, so it might require some more research or experimenting (or maybe my version is just too old).  If there is a way to do it with Tkinter it would be better and more portable, but I can't find a way.  If there were it would be cross-platform though.
0
 
gelonidaAuthor Commented:
Hi Superdave,

I'm not sure, that Tkinter can click/move the mouse outside of its own scope.

Meanwhile somebody else pointed me to a Linux only solution, which works quite well for slow mouse
moves / clicks  etc.

The tool is xte ( "xte - Generates fake input using the XTest extension" )

the command is
to move the mouse cursor to 100,200 one would call
xte 'mousemove 200 200'


What would be interesting now would be either
- solutions without subprocess.Popen
or
soultions working on windows AND Linux

0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
gelonidaAuthor Commented:
Hi Richard,

Thanks. This works perfectly for Windows.

So now I have a:
- a solution with a library for windows
- a solution with subprocess.Popen for Linux

There's potentially also Superdave's solution for X-Windows, but if I understood him correctly not working as expected.

I'll wait a little more to see if anybody knows a tiny Linux code snippet for Linux (without subprocess).
Then I'll close this issue

0
 
-Richard-Commented:
I have done some more research and have concluded, sadly, that there is truly no canned "out of the box" cross platform solution to this problem.   The best solution in the Linux environment is the X solution suggested by Superdave.  X is a *nux-only solution and only if your *nix is running X-Windows - I supect that Superdave tried running it under Windows and that's why he had no success.
0
 
gelonidaAuthor Commented:
Thanks

Having now two solutions which work nicely on Linux / Windows
0
 
gelonidaAuthor Commented:
Hmm, Somehow I failed attaching a working code snippet for X.


So here it is again.

I thought it might interesting for the ones searching for this question.


#!/usr/bin/env python
import os
import Xlib
import Xlib.X
import Xlib.display
import time

import Xlib.display
import Xlib.ext.xtest

class MouseControl(object):
    def __init__(self):
        DISPLAY=os.environ.get('DISPLAY')
        self.display = Xlib.display.Display(DISPLAY)
        self.screen = self.display.screen()
        self.root = self.screen.root

    def mouse_click(self, button):
        self.mouse_down(button)
        self.mouse_up(button)

    def mouse_down(self, button): #button= 1 left, 2 middle, 3 right
        Xlib.ext.xtest.fake_input(self.display,Xlib.X.ButtonPress, button)
        self.display.sync()

    def mouse_up(self, button):
        Xlib.ext.xtest.fake_input(self.display,Xlib.X.ButtonRelease, button)
        self.display.sync()

    def mouse_warp(self, x,y):
        self.root.warp_pointer(x,y)
        self.display.sync()

    def get_screen_resolution(self):
        return self.screen['width_in_pixels'], self.screen['height_in_pixels']

def main():
    mc = MouseControl()
    for i in range(4):
        time.sleep(0.5)
        mc.mouse_warp(i*100,i*100)
    mc.mouse_click(3)
    

if __name__ == "__main__":
    main()

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.