Skip to content

Instantly share code, notes, and snippets.

@tbnorth
Last active December 25, 2015 07:19
Show Gist options
  • Save tbnorth/6938960 to your computer and use it in GitHub Desktop.
Save tbnorth/6938960 to your computer and use it in GitHub Desktop.
pywarp.py, warp / teleport / relocate / move mouse / pointer / cursor when it's moved over / enters an invisible window / region of the screen / display.
"""
pywarp.py, Terry Brown, terry_n_brown@yahoo.com, Fri Oct 11 12:07:50 2013
Warp / teleport / relocate / move mouse / pointer / cursor when it's
moved over / enters an invisible window / region of the screen / display.
Can be used to override physical monitor layout. I have three
monitors, 2 x 1680x1050, and one 1920x1080. I'd like them laid out
out left to right 1680x1050 1920x1080 1680x1050 but the graphics
cards I'm using can't render across that total width, so instead
I tell the graphics cards they're laid out out like this::
+------------+
|1680x1050 |
| |
+------------+------------+--+
|1680x1050 |1920x1080 |
| | |
+------------+---------------+
whereas the actual layout is::
A B C
+------------+---------------+------------+
|1680x1050 |1920x1080 |1680x1050 |
| | | |
+------------+---------------+------------+
This program makes the mouse wrap between B and C as expected on their
right / left borders, rather than having to remember to go up from B
or down from C to move between them. It's run like this::
python pywarp.py 3599 1050 1 1080 -1915 -1050 \
1680 0 1 1050 1915 1050 &
and each set of 6 values creates an invisible window at
x, y, w, h, dx, dy::
x, y top left corner of invisible window in screen coords
w, h width and height of invisible window in pixels
dx, dy values added to mouse coords in pixels when mouse
enters invisible window - the pointer is moved by dx, dy
Make sure one window doesn't warp the mouse into the other, my example
above puts the mouse 5 pixels into the receiving monitor, not right on
the edge, so there's no ping pong between the warp windows.
"""
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self, x, y, w, h, dx, dy):
self.args = x, y, w, h, dx, dy
QtGui.QWidget.__init__(self)
self.setMouseTracking(True)
self.setGeometry(x, y, w, h)
# in case the window manager moves the window when it's opened
QtCore.QTimer.singleShot(10000, lambda: self.setGeometry(x, y, w, h))
self.setWindowFlags(
QtCore.Qt.CustomizeWindowHint | # hides border
QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.SplashScreen # supress task list entry
)
self.setStyleSheet("background:transparent;")
def mouseMoveEvent(self, event):
x, y, w, h, dx, dy = self.args
cx, cy = event.globalX(), event.globalY()
nx, ny = cx+dx, cy+dy
if x <= cx < x+w and y <= cy < y+h: # ignore out of range events
self.cursor().setPos(nx, ny)
# print("%s,%s -> %s,%s moved" % (cx, cy, nx, ny))
else:
# print("%s,%s -> %s,%s ignored" % (cx, cy, nx, ny))
pass
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
windows = []
while len(sys.argv) > 1:
x, y, w, h, dx, dy = [int(i) for i in sys.argv[1:7]]
del sys.argv[1:7]
window = Window(x, y, w, h, dx, dy)
window.show()
windows.append(window)
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment