Link to home
Start Free TrialLog in
Avatar of gelonida
gelonidaFlag for France

asked on

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







SOLUTION
Avatar of Superdave
Superdave
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gelonida

ASKER

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

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

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

Having now two solutions which work nicely on Linux / Windows
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