Created
November 3, 2013 23:01
-
-
Save dcolascione/7295864 to your computer and use it in GitHub Desktop.
The beauty of desktop Linux is that I can write shell scripts like this. The horror is realizing I shouldn't have to.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script runs on login and on device hotplug and configures | |
# various bits of my Lenovo laptop. It automatically detects whether | |
# the machine is docked. | |
# Profiles: | |
# -1 = None | |
# 0 = legacy behavior: if thresh is 0, polynomial, | |
# otherwise, simple. | |
# 1 = device-dependent | |
# 2 = polynomial: velocity serves as the coefficient, | |
# acceleration being the exponent. Very useable, | |
# the recommended profile. | |
# dancol: Reading the code, thresh is ignored. | |
# 3 = smooth linear: scales mostly linear, but with a | |
# smooth (non-linear) start. | |
# 4 = simple: transitions between accelerated/unaccelerated, | |
# but with a smooth transition range. | |
# This has the fundamental problem of accelerating on | |
# two niveaus, on which acceleration stays independent | |
# of velocity. Traditionally the default however. | |
# 5 = power: transitions between accelerated/unaccelerated, | |
# but with a smooth transition range. | |
# This has the fundamental problem of accelerating on two | |
# niveaus, on which acceleration stays independent of velocity. | |
# Traditionally the default however. | |
# 6 = linear: just linear to velocity and acceleration. | |
# Simple and clean. | |
# dancol: identical to polynomial with exp=1? | |
# 7 = limited: smoothly ascends to acceleration, | |
# maxing out at threshold, where it becomes flat | |
# (is limited). | |
# dancol: Appears not actually implemented. | |
mouse_profile=2 | |
mouse_accel_num=2 | |
mouse_accel_den=1 | |
mouse_thresh=1 | |
mouse_buttons='3 2 1 4 5 8 9 6 7' | |
mouse_buttons_msft='3 2 1 4 5 6 7 8 9' | |
mouse_constant_deceleration=3 | |
mouse_constant_deceleration_msft=1.7 | |
mouse_adaptive_deceleration=3 | |
lock_timeout=10 # seconds | |
reconfigure-input() { | |
# Reset X defaults --- override specific pointers with X input. | |
xset m default | |
for dev_id in $(xinput list --id-only); do | |
dev_name=$(xinput list --name-only $dev_id) | |
echo "Found device $dev_id: $dev_name" | |
if [[ $dev_name = 'Logitech USB Laser Mouse' ]] || | |
[[ $dev_name = Microsoft*'5-Button Mouse'* ]]; | |
then | |
if [[ $dev_name = Microsoft* ]]; then | |
decel=$mouse_constant_deceleration_msft | |
buttons=$mouse_buttons_msft | |
else | |
decel=$mouse_constant_deceleration | |
buttons=$mouse_buttons | |
fi | |
xinput set-button-map $dev_id $buttons | |
xinput set-prop $dev_id 'Device Accel Profile' $mouse_profile | |
# Fudge factor that accounts for device control | |
xinput set-prop $dev_id 'Device Accel Velocity Scaling' 10 | |
# Decelerate pointer before reaching accel engine | |
xinput set-prop $dev_id 'Device Accel Constant Deceleration' \ | |
$decel | |
# Somehow slow for precision? | |
xinput set-prop $dev_id 'Device Accel Adaptive Deceleration' \ | |
$mouse_adaptive_deceleration | |
xinput set-ptr-feedback $dev_id \ | |
$mouse_thresh $mouse_accel_num $mouse_accel_den | |
fi | |
if [[ $dev_name = 'SynPS/2 Synaptics TouchPad' ]]; then | |
# Train myself not to use the bottom-right corner for right | |
# clicking. This technique doesn't actually work becaues of | |
# problems in the synaptics driver, and we can uwe a two-finger | |
# OS-X-like click instead. | |
synclient RightButtonAreaLeft=0 RightButtonAreaTop=0 | |
# Make corners dead so palms don't interfere | |
synclient CornerTopLeft=1000 | |
synclient CornerTopRight=1000 | |
fi | |
# Reconfigure USB-attached model M. Make sure to | |
# not reconfigure any mouse also called USBPS2. | |
if [[ $dev_name = 'USBPS2' ]]; then | |
if ! xinput get-button-map $dev_id >/dev/null 2>&1; then | |
~/conf/tools/remap-xkb -s $dev_id <<EOF | |
key <SCLK> { [ Super_R ] }; | |
EOF | |
fi | |
fi | |
done | |
} | |
reconfigure-display() { | |
# When lid becomes closed, without suspend-resume cycle, | |
# X doesn't realize other display is gone. Help it along. | |
local status= | |
local bigmon= | |
if read -r status < /sys/class/drm/card0-HDMI-A-1/status; | |
[[ $status = 'connected' ]]; | |
then | |
bigmon=HDMI1 | |
elif read -r status < /sys/class/drm/card0-DP-1/status; | |
[[ $status = 'connected' ]]; | |
then | |
bigmon=DP1 | |
fi | |
local closed | |
read -r _ closed < /proc/acpi/button/lid/LID/state | |
# If we have no external display connected, never turn off LVDS1 | |
# --- doing so results in windows being resized to 0x0! We turn | |
# off the display when we close the lid via the suspension | |
# mechanism, not through this code. | |
if [[ -z $bigmon ]]; then | |
xrandr --output LVDS1 --auto | |
elif [[ $closed != 'closed' ]]; then | |
xrandr --output LVDS1 --auto --right-of $bigmon | |
else | |
xrandr --output LVDS1 --off | |
fi | |
} | |
reconfigure-unfuck-keybindings() { | |
# Unity fucking resets keybindings on reboot sometimes. Fix them | |
# here. | |
dconf load / < ~/conf/unfucked-bindings.conf | |
gsettings set org.gnome.settings-daemon.plugins.media-keys \ | |
terminal '' | |
} | |
reconfigure() { | |
reconfigure-display | |
reconfigure-input | |
reconfigure-unfuck-keybindings | |
} | |
# Actually do the reconfiguration with a lockfile held. | |
( | |
if flock -w $lock_timeout $lockfd; then | |
reconfigure | |
echo "Reconfigured!" | |
else | |
echo >&2 "lenovo-input-conf: lock failed: $?" | |
exit 1 | |
fi | |
) {lockfd}>"/tmp/$USER-lenovo-input-conf.lock" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment