Skip to content

Instantly share code, notes, and snippets.

@jmoiron
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmoiron/37685539549b42600c52 to your computer and use it in GitHub Desktop.
Save jmoiron/37685539549b42600c52 to your computer and use it in GitHub Desktop.
synpad
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Simple synaptics client save/restore."""
import argparse
import sys
import os.path
from collections import OrderedDict
from subprocess import *
CFGPATH = os.path.expanduser("~/.config/synpadrc")
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-s", "--save", action="store_true", help="save config")
parser.add_argument("-r", "--restore", action="store_true", help="restore config")
parser.add_argument("-d", "--diff", action="store_true", help="show diff between saved and live config")
parser.add_argument("-l", "--list", action="store_true", help="show current config (same as synclient -l)")
def synclient(*options):
"""Run synclient with options and return the (code, output)."""
args = ["synclient"] + list(options)
cmd = Popen(args, stdout=PIPE, stderr=PIPE)
cmd.wait()
out = cmd.stdout.read()
if cmd.returncode != 0:
print "Error running %s:\n%s" % (' '.join(args), out)
sys.exit(-1)
return out
def parse(options):
"""Return an OrderedDict of options from an options file."""
optd = OrderedDict()
for line in options:
if "=" in line:
sp = [l.strip() for l in line.split("=")]
optd[sp[0]] = sp[1]
return optd
def dolist():
out = synclient("-l").strip()
print out
def save():
out = synclient("-l")
open(CFGPATH, "w+").write(out)
broken = ('FingerLow', 'FingerHigh')
def restore():
try:
options = open(CFGPATH).readlines()
except IOError:
print "Could not load configuration from %s." % CFGPATH
sys.exit(-1)
if not options:
print "No options saved in configuration."
sys.exit(0)
optd = parse(options)
for k,v in optd.iteritems():
# there is some kind of bug setting this option
if k in broken:
continue
synclient("%s=%s" % (k,v))
def diff():
current = synclient("-l")
coptd = parse(current)
saved = open(CFGPATH).read()
soptd = parse(saved)
diffs = False
for k,v in coptd.iteritems():
if k not in soptd:
print "%s = %s (cfg: missing)" % (k, v)
diffs = True
if v != soptd[k]:
print "%s = %s (cfg: %s)" % (k, v, soptd[k])
diffs = True
for k,v in soptd.iteritems():
if k not in coptd:
print "%s = %s (current: missing)" % (k, v)
diffs = True
sys.exit(1 if diffs else 0)
if __name__ == '__main__':
args = parser.parse_args()
if args.list:
dolist()
if args.save:
save()
if args.restore:
restore()
if args.diff:
diff()
Parameter settings:
LeftEdge = -3791
RightEdge = 4311
TopEdge = 423
BottomEdge = 6027
FingerLow = 70
FingerHigh = 50
MaxTapTime = 180
MaxTapMove = 522
MaxDoubleTapTime = 180
SingleTapTimeout = 180
ClickTime = 100
EmulateMidButtonTime = 0
EmulateTwoFingerMinZ = 283
EmulateTwoFingerMinW = 7
VertScrollDelta = 237
HorizScrollDelta = 237
VertEdgeScroll = 0
HorizEdgeScroll = 0
CornerCoasting = 0
# use 2-finger scroll instead of edge scroll
VertTwoFingerScroll = 1
HorizTwoFingerScroll = 1
# still figuring these, might reduce the minspeed a smidge
MinSpeed = 0.8
MaxSpeed = 2.5
AccelFactor = 0.01
TouchpadOff = 0
LockedDrags = 0
LockedDragTimeout = 5000
RTCornerButton = 0
RBCornerButton = 0
LTCornerButton = 0
LBCornerButton = 0
TapButton1 = 1
# disable 2 & 3 button taps as these get in the way of some gestures and i don't use them often
TapButton2 = 0
TapButton3 = 0
ClickFinger1 = 1
ClickFinger2 = 3
# disable 3-finger click
ClickFinger3 = 0
CircularScrolling = 0
CircScrollDelta = 0.1
CircScrollTrigger = 0
CircularPad = 0
# enable palm detection but set everything as high as possible
# lower values were triggering occasionally with my fingers
PalmDetect = 1
PalmMinWidth = 15
PalmMinZ = 255
CoastingSpeed = 20
CoastingFriction = 50
PressureMotionMinZ = 30
PressureMotionMaxZ = 160
PressureMotionMinFactor = 1
PressureMotionMaxFactor = 1
ResolutionDetect = 1
GrabEventDevice = 0
TapAndDragGesture = 0
AreaLeftEdge = 0
AreaRightEdge = 0
AreaTopEdge = 0
AreaBottomEdge = 0
HorizHysteresis = 39
VertHysteresis = 27
ClickPad = 1
RightButtonAreaLeft = 0
RightButtonAreaRight = 0
RightButtonAreaTop = 0
RightButtonAreaBottom = 0
MiddleButtonAreaLeft = 0
MiddleButtonAreaRight = 0
MiddleButtonAreaTop = 0
MiddleButtonAreaBottom = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment