Command-line solutions to laptop functions

Trying to make the jump to exwm, which is a similar experience (though considerably less documented) than switching to i3wm, there are a number of core laptop functionalities that the heavier-weight window managers take care of for you. I’m using this on a laptop that is often used that way – traveling, connecting to multiple different WiFi networks daily, connecting to docking stations and extra monitors and devices, toggling touch pad, etc. In my quest to get this figured out, here are some of the major things I’ve dealt with.

Controlling the power key

The power button isn’t handled by the window manager, it’s handled by systemd

For example this is in my /etc/systemd/logind.conf

[Login]
HandlePowerKey=hibernate
HandleLidSwitch=ignore
IdleAction=suspend
IdleActionSec=20min

Toggling the touch pad

This was solved by implementing the following shell script:

#!/bin/bash

declare -i ID
ID=`xinput list | grep -Eo 'Touchpad\s*id\=[0-9]{1,2}' | grep -Eo '[0-9]{1,2}'`
declare -i STATE
STATE=`xinput list-props $ID|grep 'Device Enabled'|awk '{print $4}'`
if [ $STATE -eq 1 ]
then
    xinput disable $ID
    echo "Touchpad disabled."
    # notify-send -a 'Touchpad' 'Disabled' -i /usr/share/icons/Adwaita/48x48/devices/input-touchpad.png
else
    xinput enable $ID
    echo "Touchpad enabled."
    # notify-send -a 'Touchpad' 'Enabled' -i /usr/share/icons/Adwaita/48x48/devices/input-touchpad.png
fi

I then bound this to my desired key (since I’m using exwm, I bound it in my emacs.el, with touchpad_toggle being the name of the script I created above):

(exwm-input-set-key (kbd "s-<f7>")
                (lambda () (interactive)    
                  (shell-command (executable-find "touchpad_toggle"))))

Lock Screen

xscreensaver took care of this. Once I’d installed xscreensaver from my repos – including the extras to get the gl-slideshow that I wanted as my lock screen – I ran xscreensaver-demo to set it up to my desires. Then I created a one-liner that I named lockscreen, and bound it in my emacs file:

#!/bin/bash

xscreensaver-command -lock

(exwm-input-set-key (kbd "s-l") (lambda () (interactive) (shell-command (executable-find "lockscreen"))))

Then it was a matter of also locking on screen shutdown: https://unix.stackexchange.com/questions/81692/suspend-and-lock-screen-on-closing-lid-in-arch-systemd

Battery Status

Simple with fancy-battery mode (it says it is un-maintained, but it works for me from melpa)

(use-package fancy-battery
  :ensure t
  (fancy-battery-mode))

Simple Wifi management

nmtui is the simplest, a good text-interface to NetworkManager. The trick was in the fact that it isn’t usable in any of the Emacs terminals, wich have been my shell solution for a long while.

The trouble I had was finding a way to remeber passwords, since NMTUI was having me type them in each time.

Simple Quick Transitions to Multiple Monitors

When I plug in an external monitor, under KDE it simply connects (though I might have to do some resolution tweaking). In my exwm setup, nothing happens. However, exwm has solutions for this, which go into my emacs.el file:

(require 'exwm-randr)
(setq exwm-randr-workspace-output-plist '(0 "DP-1")) ;; DP-1 being the name of my new monitor as shown by `randr'
(add-hook 'exwm-randr-screen-change-hook
      (lambda ()
        (start-process-shell-command
         "xrandr" nil "xrandr --output DP-1 --left-of eDP-1 --auto"))) ;; eDP-1 being the name of my original (laptop) monitor
(exwm-enable)
(exwm-randr-enable)

Audio Volume

I was lucky enough that I was already using Alsa for my sound, so didn’t even have to install anything. In previous attempts on different devices sound was much harder to deal with. Here I could get it going with nothing but my exwm config.

(exwm-input-set-key (kbd "<XF86AudioLowerVolume>")
                (lambda () (interactive) (shell-command "amixer set Master 5%-")))
(exwm-input-set-key (kbd "<XF86AudioRaiseVolume>")
                (lambda () (interactive) (shell-command "amixer set Master 5%+")))
(exwm-input-set-key (kbd "<XF86AudioMute>")
                (lambda () (interactive) (shell-command "amixer set Master 1+ toggle")))

Screen Brightness

I have hardware keys that worked wonderfully under kde to dim and brighten my screen. How can I regain this functionality? The answer is in the light package (which works far more easily than xbacklight, which always told me ‘No outputs have backlight property’.

https://github.com/haikarainen/light

Following the instructions to install, I then set my keys appropriately:

(exwm-input-set-key (kbd "<XF86MonBrightnessDown>") (lambda () (interactive) (shell-command "light -U 5; light")))
(exwm-input-set-key (kbd "<XF86MonBrightnessUp>") (lambda () (interactive) (shell-command "light -A 5; light")))

Screenshot

The last thing I realized I needed when writing this post was the ability to make a screenshot. My favorite screenshot tool is that which ships with KDE, Spectacle. Since it is already installed for me, I just bound it to my Printscreen key:

(exwm-input-set-key (kbd "<print>") (lambda () (interactive) (start-process-shell-command "spectacle" nil "spectacle")))

USB Drive Mounting

Use udiskie to auto-mount devices plugged in to your machine, such as flash drives. I found that trying to install it from my OpenSUSE packagemanager didn’t work, although it was listed, but I already had pip installed and that led to simple process. After installation, the following worked beautifully:

~/.local/bin/udiskie --no-notify --tray &

notifications did not play nice with exwm, but the tray works great. Then I just put the above into my .xinitrc.

Tory Anderson avatar
Tory Anderson
Digital Humanist, Web App Engineer, PhD Candidate, Computer Psychologist
comments powered by Disqus