mouseless scripts

This commit is contained in:
gotbletu 2016-08-26 00:45:33 -07:00
parent 4b5fc5e1bd
commit 7b4f66eecf
4 changed files with 330 additions and 0 deletions

181
mouseless.py Executable file
View File

@ -0,0 +1,181 @@
#!/usr/bin/python2
# author: hruskam
# source: https://hruskam.wordpress.com/2015/11/14/mouseless/
# http://phoebe.inf.upol.cz/~hruskam/temporary/mouseless.py
# description:
# mouseless is a small python script, which enables fast movement of
# mouse cursor by successive division of screen. In effect, one can reach
# every pixel in small number of steps (logarithmic in size of screen)
# by using adequate keys on numeric keypad.
# An example of process of division is shown on the following video.
# https://www.youtube.com/watch?v=OsefVqkWpgs
# requirements: python2 python2-qt4 xdotool
# run mouseless: (bind script to hotkeys examples)
# Left Hand: Ctrl+Shift+A or Hyper_L + A (Capslock + A)
# Right Hand: Alt_R + Semicolon
# Numpad: Pause/Break key
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 28 14:03:06 2013
@author: hruskam
"""
verbose = True
# import libraries
from PyQt4 import QtGui, Qt, QtCore
import sys
import itertools as it
import subprocess as sp
import re
# configuration
xdotool_bin = '/usr/bin/xdotool'
# graphics
pen_width = 1
# pen used for the innermost grid
final_pen = QtGui.QPen(QtGui.QColor(255, 0, 0, 255), pen_width, QtCore.Qt.DashLine)
# pen used for the rest of grids
nonfinal_pen = QtGui.QPen(QtGui.QColor( 0, 0, 0, 255), pen_width, QtCore.Qt.SolidLine)
# opacity of the main window
win_opacity = 0.25
# keys used for exiting the application
exit_keys = [QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Escape, QtCore.Qt.Key_Semicolon, QtCore.Qt.Key_Plus]
# keys used for going to previous grid
back_keys = [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Space, QtCore.Qt.Key_0]
# mapping keypad to selection tuples
qk = QtCore.Qt
keyd = {qk.Key_7: (-1, -1), qk.Key_8: ( 0, -1), qk.Key_9: ( 1, -1),
qk.Key_4: (-1, 0), qk.Key_5: ( 0, 0), qk.Key_6: ( 1, 0),
qk.Key_1: (-1, 1), qk.Key_2: ( 0, 1), qk.Key_3: ( 1, 1),
qk.Key_Q: (-1, -1), qk.Key_W: ( 0, -1), qk.Key_E: ( 1, -1),
qk.Key_A: (-1, 0), qk.Key_S: ( 0, 0), qk.Key_D: ( 1, 0),
qk.Key_Z: (-1, 1), qk.Key_X: ( 0, 1), qk.Key_C: ( 1, 1),
qk.Key_U: (-1, -1), qk.Key_I: ( 0, -1), qk.Key_O: ( 1, -1),
qk.Key_J: (-1, 0), qk.Key_K: ( 0, 0), qk.Key_L: ( 1, 0),
qk.Key_M: (-1, 1), qk.Key_Comma: ( 0, 1), qk.Key_Period: ( 1, 1)}
# mouse moving using xdotool
def mouse_move(x, y):
sp.check_call([xdotool_bin, 'mousemove', "%d" % x, "%d" % y])
# perform mouse move to center of an QRect
def mouse_move_center(qr):
mouse_move(qr.center().x(), qr.center().y())
# auxiliary functions from fplib (not yet on pypi)
# performs flattening of the list
def unlist1(value):
return list(it.chain(*value))
# retrieves the list without its last element
def nolast(l):
return l[:-1]
# retrievies set of lists, which start
def prefixes(l):
return map(lambda i: l[:(i + 1)], range(len(l)))
# centered scale of rectangle
def qt_centered_scale(qr, scale):
qc = Qt.QRect(qr)
t = Qt.QTransform().fromScale(scale, scale)
qr = t.mapRect(qr)
qr.translate(qc.center() - qr.center())
return qr
# obtain final rectangle, based on user selections
# e.g. if selections are [(-1, -1), (0, 0)]
# that means the user selected 7 (upper left) and 5 (center)
# in each step, the rectangle is scaled (three times smaller), preserving
# its center; and shifted accordingly
def get_selections_final_rect(selections):
qr = QtGui.QDesktopWidget().screenGeometry()
for d_x, d_y in selections:
qr = qt_centered_scale(qr, 1.0 / 3)
qr.translate(d_x * qr.width(), d_y * qr.height())
return qr
class GridScene(QtGui.QGraphicsScene):
def __init__(self, parent=None):
QtGui.QGraphicsScene.__init__(self, parent)
qr = QtGui.QDesktopWidget().screenGeometry()
self.draw_grid(qr, nonfinal_pen)
def draw_grid(self, qr, pen, n=3):
for y in range(qr.top(), qr.bottom(), qr.height() / n):
self.addLine(qr.left(), y, qr.right(), y, pen=pen)
for x in range(qr.left(), qr.right(), qr.width() / n):
self.addLine(x, qr.top(), x, qr.bottom(), pen=pen)
class GridWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
# initialize user selections to empty
self.selections = []
#
QtGui.QMainWindow.__init__(self, parent)
self.scene = GridScene()
view = QtGui.QGraphicsView(self.scene)
# hide scrollbars
view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# simple layout
hbox = QtGui.QHBoxLayout()
hbox.setSpacing(0)
hbox.setMargin(0)
hbox.addWidget(view)
# window properties
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.setWindowState(self.windowState() | QtCore.Qt.WindowActive)
self.setWindowOpacity(win_opacity)
#
mainWidget = QtGui.QWidget()
mainWidget.setLayout(hbox)
def widgetKeypress(event):
key = event.key()
def update_to_user_selections():
self.scene.clear()
for sels in [[]] + prefixes(self.selections):
qr = get_selections_final_rect(sels)
pen = final_pen if len(sels) == len(self.selections) else nonfinal_pen
self.scene.draw_grid(qr, pen)
mouse_move_center(qr)
# if key is in numeric keypad, then add selection
if key in keyd.keys():
self.selections.append(keyd[key])
# if key is in backspace keys, then remove last selection
elif key in back_keys:
self.selections = nolast(self.selections)
# exit if key is in exit keys
elif key in exit_keys:
sys.exit()
update_to_user_selections()
mainWidget.keyPressEvent = widgetKeypress
self.setCentralWidget(mainWidget)
# mouse_move(screen_width() / 2, screen_height() / 2)
app = QtGui.QApplication(['mouseless'])
screen = QtGui.QDesktopWidget().screenGeometry()
# create main window maximized
window = GridWindow()
window.showMaximized()
#
sys.exit(app.exec_())

View File

@ -0,0 +1,49 @@
# Mouseless Keyboard Ninja
Emulate moving the mouse around using just our keyboard. All part of becoming a keyboard ninja lols. We have two modes, mousless grid mode then mousemove mode, with these two together we can hop around and do basic task quickly without reaching for the mouse. Saves time depending on task.
* tutorial video: [Link](https://www.youtube.com/playlist?list=PLqv94xWU9zZ1cXfg3ED24G6RSt4NbFBfO)
* offical website: [Link](https://www.youtube.com/user/gotbletu)
### install requirements
python2 python2-qt4 xdotool xterm wmctrl
### download scripts
note: put it all in the same folder and make sure to chmod +x the scripts to give it permission to run
wget https://raw.githubusercontent.com/gotbletu/shownotes/master/mouseless_mousemove_mode.sh
wget https://raw.githubusercontent.com/gotbletu/shownotes/master/mouseless.py
wget https://raw.githubusercontent.com/gotbletu/shownotes/master/mousemove_mode.sh
### activate
bind (mouseless_mousemove_mode.sh) script to a hotkey
Example:
Left Hand: Ctrl+Shift+A or Hyper_L + A (Capslock + A)
Right Hand: Alt_R + Semicolon
Numpad: Pause/Break key
### references
- https://hruskam.wordpress.com/2015/11/14/mouseless/
- http://phoebe.inf.upol.cz/~hruskam/temporary/mouseless.py
- https://bbs.archlinux.org/viewtopic.php?pid=1106808#p1106808
- http://stackoverflow.com/a/10680015
- http://stackoverflow.com/a/11759139
- http://www.bbc.co.uk/accessibility/guides/keyboard_mouse/computer/linux/gnome/
### contact
_ _ _ _
__ _ ___ | |_| |__ | | ___| |_ _ _
/ _` |/ _ \| __| '_ \| |/ _ \ __| | | |
| (_| | (_) | |_| |_) | | __/ |_| |_| |
\__, |\___/ \__|_.__/|_|\___|\__|\__,_|
|___/
- http://www.youtube.com/user/gotbletu
- https://twitter.com/gotbletu
- https://plus.google.com/+gotbletu
- https://github.com/gotbletu
- gotbletu@gmail.com

32
mouseless_mousemove_mode.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# _ _ _ _
# __ _ ___ | |_| |__ | | ___| |_ _ _
# / _` |/ _ \| __| '_ \| |/ _ \ __| | | |
#| (_| | (_) | |_| |_) | | __/ |_| |_| |
# \__, |\___/ \__|_.__/|_|\___|\__|\__,_|
# |___/
# https://www.youtube.com/user/gotbletu
# https://twitter.com/gotbletu
# https://plus.google.com/+gotbletu
# https://github.com/gotbletu
# gotbleu@gmail.com
# tutorial video playlist: https://www.youtube.com/playlist?list=PLqv94xWU9zZ1cXfg3ED24G6RSt4NbFBfO
# description: start mouseless (Grid) then wait for it to exit to start mousemove mode
# requires: mouselesss.py, mousemove_mode.sh and this script (mouseless_mousemove_mode.sh) to be in the same folder
# bind this script (mouseless_mousemove_mode.sh) to hotkeys examples
# Left Hand: Ctrl+Shift+A or Hyper_L + A (Capslock + A)
# Right Hand: Alt_R + Semicolon
# Numpad: Pause/Break key
# kill existing script
wmctrl -F -c "mouseless"
sleep 0.1
wmctrl -F -c "mousemove_mode.sh"
# start script
DIR=$(dirname "$0")
"$DIR"/mouseless.py && xterm -geometry 0x0+0+0 -e "$DIR"/mousemove_mode.sh

68
mousemove_mode.sh Executable file
View File

@ -0,0 +1,68 @@
#!/bin/bash
# _ _ _ _
# __ _ ___ | |_| |__ | | ___| |_ _ _
# / _` |/ _ \| __| '_ \| |/ _ \ __| | | |
#| (_| | (_) | |_| |_) | | __/ |_| |_| |
# \__, |\___/ \__|_.__/|_|\___|\__|\__,_|
# |___/
# https://www.youtube.com/user/gotbletu
# https://twitter.com/gotbletu
# https://plus.google.com/+gotbletu
# https://github.com/gotbletu
# gotbleu@gmail.com
# tutorial video playlist: https://www.youtube.com/playlist?list=PLqv94xWU9zZ1cXfg3ED24G6RSt4NbFBfO
# description: move mouse cursor around, mouse clicks and drag using just the keyboard (vim style, wasd, numpad, or arrow keys)
# requirements: xdotool xterm wmctrl
# note: if you want to use this script by itself then bind commmand to a hotkey:
# xterm -geometry 0x0+0+0 -e /path/to/mousemove_mode.sh
# references:
# https://bbs.archlinux.org/viewtopic.php?pid=1106808#p1106808
# http://stackoverflow.com/a/10680015
# http://stackoverflow.com/a/11759139
# http://www.bbc.co.uk/accessibility/guides/keyboard_mouse/computer/linux/gnome/
# use to set always on top and refocusing
title="mousemove_mode.sh"
# Always on top: check if terminal script window is focus or not, if not then refocus it
refocus_window() {
while :
do
detect_focus_window=$(xdotool getwindowfocus getwindowname)
if [[ "$detect_focus_window" != "$title" ]]; then
wmctrl -a "$title"
fi
done
}
# background the process
refocus_window &
# movemouse/mouse clicks using xdotools (using vim, wasd, numpad or arrow keys)
while read -rsn1 key # 1 char (not delimiter), silent, dont need to hit enter key
do
# catch multi-char special key sequences
# allows special arrow keys to work
read -sN1 -t 0.0001 k1
read -sN1 -t 0.0001 k2
read -sN1 -t 0.0001 k3
key+=${k1}${k2}${k3}
case "$key" in
h|a|4|$'\e[D') xdotool mousemove_relative -- -15 0 ;; # move left
j|s|5|$'\e[B') xdotool mousemove_relative 0 15 ;; # move down
k|w|8|$'\e[A') xdotool mousemove_relative -- 0 -15 ;; # move up
l|d|6|$'\e[C') xdotool mousemove_relative 15 0 ;; # move right
u|e|7|'/') xdotool click 1 ;; # primary click
o|q|9|'-') sleep 0.2 && xdotool click 3 ;; # secondary click (menu click)
i|r|'*'|',') xdotool click 2 ;; # middle click
n|z|0) xdotool mousedown 1 ;; # highlight | drag&drop mode (begin)
m|x|'.') xdotool mouseup 1 ;; # highlight | drag&drop mode (end)
$'\e'|';'|'+') break ;; # quit
esac
done