=====Laptop Hacks===== Ho boy, this got difficult really quickly - in 2011 I had everything working on my laptop (Dell XPS-15 L502X) with the LXDE spin of fedora plus fluxbox. After a quick spurt of travel using all the laptoppy things like conserving battery life, suspend/resume and lid up and down I left it alone, using it like a desktop on AC power but updating through various fedora's. Quite unbeknownst to me, ''systemd'' came in and the laptoppy stuff got broken - I had to re-discover how to do everything again. Now I know and understand some of it and hopefully recording it here will help me next time. Maybe it'll help you too - but you will almost certainly need to some make tweaks for your particular setup. Why go through all this? Why not just use a full DE like KDE or gnome to take care of it? With KDE the best I could get was about 4 hours of battery life. By doing the hard work and understanding what's going on I can get up to 6.5 hours! Not bad. ====Who's doing the work?==== Several players: * acpid: for suspend * DBus: for power connect/disconnect * acpi: to get battery status * systemctl: but, of course! * ???: DBus? lid opening & closing - just seems to work ====Suspend==== Install ''acpid'' and ''acpi'' and then: systemctl enable acpid systemctl start acpid Put this into ''/etc/acpi/events/sleepconf'': event=button/sleep action=systemctl suspend ====Tweaking touchpad==== Seems the synaptics driver is deprecated in favour of libinput - put tweaks in /etc/X11/xorg.conf.d/30-touchpad.conf: Section "InputClass" Identifier "touchpad" Driver "libinput" MatchIsTouchpad "on" Option "Tapping" "on" Option "TappingButtonMap" "lmr" Option "ScrollMethod" "edge" EndSection ====Power Disconnect/Connect events==== These events come through DBus, so I run this in my ''.xsession''. # if there's a battery then listen on dbus for a/c connect/disconnect: upower -e |grep -q battery && { power-monitor & xfce4-power-manager & } Where, ''power-monitor'' is this bit of python which keeps an eye on remaining battery life (and hibernate as it gets low) but also runs the ''low-power'' script when the power/battery status changes: #!/bin/env python # needs to run as normal user under X (so that battery-alarm can popup) # requires dbus-python import gobject, os, sys gobject.threads_init() from dbus import glib glib.init_threads() import dbus bus = dbus.SystemBus() sys.dont_write_bytecode = True def backtick(command): """ Equivalent of Bourne shell's backtick See http://www.python.org/doc/2.5.1/lib/node534.html """ from subprocess import Popen, PIPE #print "backtick: command='%s'\n" % command value = Popen(["sh", "-c", command], stdout=PIPE).communicate()[0].rstrip() #print "returning '%s'\n" % value return(value) # power connection events def ac(*args, **kwargs): print("[" + backtick("date '+%Y%m%d:%H%M%S'") + "] power-monitor: ac: args = ") print args try: if args[1]['Online'] == 0: print("power-monitor: ac: unplugged - calling low-power true") os.system("low-power true") else: print("power-monitor: ac: plugged in - calling low-power false") os.system("low-power false") except: pass # warn user or suspend def check_battery(*args, **kwargs): battery_status = backtick("acpi -b") print("[" + backtick("date '+%Y%m%d:%H%M%S'") + "] power-monitor: " + battery_status) if "Discharging" in battery_status: percent = int( backtick("acpi -b | awk '{print $4}' | tr -d '%,'")) if percent < 5: print("power-monitor: check-battery: systemctl hibernate") os.system("pkill battery-alarm; sudo systemctl hibernate") if percent < 10: print("power-monitor: check-battery: battery-alarm") os.system("battery-alarm&") gobject.timeout_add(60 * 1000, check_battery) # get path from 'upower -e': bus.add_signal_receiver(ac, signal_name="PropertiesChanged", dbus_interface="org.freedesktop.DBus.Properties", path="/org/freedesktop/UPower/devices/line_power_ADP0") check_battery() l = gobject.MainLoop() l.run() Put this in ''$HOME/bin/low-power'': #!/usr/bin/env bash POWER="OFF" [[ "${1:-}" && "$1" == "false" ]] && POWER="ON" echo "$0: POWER=$POWER" case "$POWER" in OFF) battery-status #sudo $( which 01-pm-power-display) true sudo $( which brightness ) 20 sudo $( which 02-pm-power-tweaks) true sudo $( which 03-pm-power-hda) true sudo powertop --auto-tune sleep 3 battery-status ;; ON) #sudo $( which 01-pm-power-display) false sudo $( which brightness ) 100 sudo $( which 02-pm-power-tweaks) false sudo $( which 03-pm-power-hda) false ;; esac pkill -0 i3blocks && pkill -RTMIN+9 i3blocks Put this in ''$HOME/bin/03-pm-power-hda'' to maximise battery or performance on the hard disc: #!/bin/sh logger -t $0 "$0 $@" case "$1" in true) # called by pm-powersave on power disconnect logger -t $0 "power disconnect: hdparm -B1 -S5 /dev/sda" hdparm -B1 -S5 /dev/sda ;; false) # called by pm-powersave on power connect logger -t $0 "power connect: hdparm -B128 -S60 /dev/sda" hdparm -B128 -S60 /dev/sda ;; esac exit 0 Put this in ''$HOME/bin/02-pm-power-tweaks'' for general tweaking - most of this originates from ''powertop'': #!/usr/bin/env bash # BH logger -t $0 "$0 $@" case "$1" in true) logger -t $0 "power disconnect" systemctl stop bluetooth.target rfkill block bluetooth BT_PID=$(ps -ef |grep '[/]usr/libexec/bluetooth/bluetoothd' | awk '{print $2}') [[ "$BT_PID" ]] && kill -9 $BT_PID echo 5 > /proc/sys/vm/laptop_mode echo 0 > /proc/sys/kernel/nmi_watchdog # echo 1 > /sys/devices/system/cpu/sched_smt_power_savings echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo 1500 > /proc/sys/vm/dirty_writeback_centisecs for i in /sys/bus/usb/devices/*/power/autosuspend; do echo 1 > $i; done for i in /sys/bus/usb/devices/*/power/level; do echo auto > $i; done echo min_power > /sys/class/scsi_host/host0/link_power_management_policy echo min_power > /sys/class/scsi_host/host1/link_power_management_policy echo Y > /sys/module/snd_hda_intel/parameters/power_save_controller echo 1 > /sys/module/snd_hda_intel/parameters/power_save for i in /sys/bus/pci/devices/*/power/control; do echo auto > $i; done iw dev wlp3s0 set power_save on ;; false) logger -t $0 "power connect" echo 0 > /proc/sys/vm/laptop_mode echo 1 > /proc/sys/kernel/nmi_watchdog # echo 0 > /sys/devices/system/cpu/sched_smt_power_savings echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo 500 > /proc/sys/vm/dirty_writeback_centisecs for i in /sys/bus/usb/devices/*/power/autosuspend; do echo 2 > $i; done # for i in /sys/bus/usb/devices/*/power/level; do echo auto > $i; done echo max_performance > /sys/class/scsi_host/host0/link_power_management_policy echo max_performance > /sys/class/scsi_host/host1/link_power_management_policy #echo Y > /sys/module/snd_hda_intel/parameters/power_save_controller #echo 1 > /sys/module/snd_hda_intel/parameters/power_save #for i in /sys/bus/pci/devices/*/power/control; do echo auto > $i; done modprobe bluetooth rfkill unblock bluetooth systemctl start bluetooth.target modprobe uvcvideo r8169 mii iw dev wlp3s0 set power_save off ;; esac exit 0 To run stuff on 'resume', put this in ''/etc/systemd/system/bhepple-resume.service'': [Unit] Description=Run on 'resume' After=suspend.target [Service] User=root Type=oneshot ExecStart=/sbin/hdparm -y /dev/sda # puts aux disc into standby - should test that it's not '/' !! [Install] WantedBy=suspend.target and run ''systemctl enable bhepple-resume.service'' brightness is this: #!/bin/bash # since xbacklight isn't working (nouveau?) # https://bbs.archlinux.org/viewtopic.php?id=134972 and modified: # needs to be run as root NEW_VALUE=${1:-0} # base dir for backlight class basedir="/sys/class/backlight/" # get the backlight handler handler=$basedir$(ls $basedir |head -n 1)"/" # get current brightness old_brightness=$(cat $handler"brightness") # get max brightness max_brightness=$(cat $handler"max_brightness") # get current brightness % old_brightness_p=$(( 100 * $old_brightness / $max_brightness )) # calculate new brightness % if [[ $NEW_VALUE == [+-]* ]]; then new_brightness_p=$(($old_brightness_p + $NEW_VALUE)) else new_brightness_p=$NEW_VALUE fi # calculate new brightness value new_brightness=$(( $max_brightness * $new_brightness_p / 100 )) (( new_brightness <= max_brightness && new_brightness >= 0 )) && { # set the new brightness value echo $new_brightness > $handler"brightness" } ====Disable nouveau==== I find it slow & buggy so ''/etc/modprobe.d/blacklist.conf'' gets: blacklist nouveau and ''/etc/default/grub'' gets: rdblacklist=nouveau Run this to get grub updated: grub2-mkconfig >/boot/grub2/grub.cfg