15 Jan 2018

FreeBSD on a Laptop

A guide to a fully functional installation of FreeBSD on a ThinkPad T530.

As I stated my previous post, I recently dug up my old ThinkPad T530 after the embarrassing stream of OS X security bugs this month. Although this ThinkPad ran Gentoo faithfully during my time in school, these days I'd much rather spend time my family than fighting with emerge and USE flags. FreeBSD has always been my OS of choice, and laptop support seems to be much better than it was a few years ago. In this guide, I'll show you the tweaks I made to wrestle FreeBSD into a decent experience on a laptop.

Unlike my usual posts, this time I'm going to assume you're already pretty familiar with FreeBSD. If you're a layman looking for your first BSD-based desktop, I highly recommend checking out TrueOS (previously PC-BSD): they've basically taken FreeBSD and packaged it with all the latest drivers, along with a user-friendly installer and custom desktop environment out of the box. TrueOS is an awesome project–the only reason I don't use it is because I'm old, grumpy, and persnickety about having my operating system just so.

Anyway, if you'd still like to take the plunge, read on. Keep in mind, I'm using a ThinkPad T530, but other ThinkPads of the same generation should be similarly compatible. Here's what you'll get:

What I haven't tested yet:


  1. Installation
  2. Power Saving
  3. Tweaks for Desktop Use
  4. X11
  5. Fonts
  6. Login Manager: SLiM
  7. Desktop Environment: i3
  8. Applications

Installation

FreeBSD's installer is pretty much self-explanatory. Just dd the memstick image to a USB stick and reboot. I recommend encrypting your root partition, and the installer now supports automated configuration of an encrypted root-on-ZFS setup. However, I wanted a root-on-UFS configuration, and I wanted to boot via UEFI. I wrote a guide for that here if you're interested.

The biggest decision you'll need to make is whether to run the latest -RELEASE distribution, or try your luck with -CURRENT. As of this writing, 11.1 is the latest RELEASE version, but you can also download installer images for 12-CURRENT on the FreeBSD download page.

Release versions are the only ones guaranteed to work, and you'll have a hard time getting help on the forums if you're running a bleeding-edge development snapshot. In addition, you'll have to manually build the world and kernel to update the base system. However, running 12-CURRENT gets you all the latest hardware drivers. Graphics will probably be your biggest issue. You can check the support of your graphics card here. In my case, I run 12-CURRENT so I can take advantage of the latest Intel drivers in the graphics/drm-next-kmod port.

I have always run CURRENT without any issues. Just subscribe to the freebsd-current mailing list, and be sure to check recent threads for any issues before you update. If you want a more hands-off, low-maintenance experience, stick with RELEASE.

Notes on Running -CURRENT

If you do decide to run CURRENT, you should make some small configuration changes to make sure you get optimal battery life and performance—a lot of debugging options are turned on by default.

/etc/make.conf
CPUTYPE?=native CFLAGS=-O2 -pipe -fno-strict-aliasing COPTFLAGS=-O2 -pipe -fno-strict-aliasing MALLOC_PRODUCTION="YES"

/etc/src.conf
WITHOUT_ASSERT_DEBUG="ON"

These options only apply when rebuilding the base system and kernel. Make sure to compile your kernel using:

make buildkernel KERNCONF=GENERIC-NODEBUG

The NODEBUG configuration avoids all the performance-killing debugging features turned on by default in CURRENT.

Power Saving

From this point on I'm going to assume you successfully installed and booted FreeBSD. Log in as root as we can start configuring stuff!

The first order of business is to get some decent battery life. You can see the current battery status using:

acpiconf -i 0

Enabling CPU frequency scaling will give you the biggest power savings. Add the following to /etc/rc.conf:

/etc/rc.conf
powerd_enable="YES" powerd_flags="-a hiadaptive -b adaptive" performance_cx_lowest="Cmax" economy_cx_lowest="Cmax"

Depending on your wireless card, you might be able to enable WiFi power saving in this file as well. Try the following:

/etc/rc.conf
ifconfig_wlan0="WPA DHCP powersave"

There are plenty of power saving kernel tuneables, especially if you have an Intel card:

/boot/loader.conf
hw.pci.do_power_nodriver="3" hw.snd.latency="7" hint.p4tcc.0.disabled="1" hint.acpi_throttle.0.disabled="1" hint.ahcich.0.pm_level="5" hint.ahcich.1.pm_level="5" hint.ahcich.2.pm_level="5" hint.ahcich.3.pm_level="5" hint.ahcich.4.pm_level="5" hint.ahcich.5.pm_level="5" # for intel cards only drm.i915.enable_rc6="7" drm.i915.semaphores="1" drm.i915.intel_iommu_enabled="1"

Finally, you can set power savings on your USB devices. However, not all of them will support power saving mode. The following shell one-liner will generate a list of commands to enable power saving on all your supported USB devices.

for ugen in $(usbconfig | awk -F: '{print $1}' | sort) ; do cmd="/usr/sbin/usbconfig -d $ugen power_save"; $($cmd 2> /dev/null) && echo $cmd ; done

You can put these commands in /etc/rc.local so they'll run on every boot. Here's what it looks like on my ThinkPad:

/etc/rc.local
/usr/sbin/usbconfig -d ugen1.2 power_save /usr/sbin/usbconfig -d ugen1.3 power_save /usr/sbin/usbconfig -d ugen1.4 power_save /usr/sbin/usbconfig -d ugen1.5 power_save /usr/sbin/usbconfig -d ugen2.2 power_save

After all that configuration, I get about 8-9 hours of battery life on my ThinkPad, depending on the backlight's brightness.

Tweaks for Desktop Use

Let's set some kernel and sysctl values to make FreeBSD a bit more pleasant to use as a desktop system. First, open up /boot/loader.conf:

/boot/loader.conf
autoboot_delay="2" # these values need to be bumped up a bit for desktop usage kern.maxproc="100000" kern.ipc.shmseg="1024" kern.ipc.shmmni="1024" # enable the nub and the touchpad hw.psm.trackpoint_support="1" hw.psm.synaptics_support="1" # Enables a faster but possibly buggy implementation of soreceive net.inet.tcp.soreceive_stream="1" # increase the network interface queue link - the default (50) is way # too low net.link.ifqmaxlen="2048" # enable hardware accelerated AES (can speed up TLS) aesni_load="YES" # Load the H-TCP algorithm. It has a more aggressive ramp-up to max # bandwidth, and is optimized for high-speed, high-latency connections. cc_htcp_load="YES" # enable CPU firmware updates cpuctl_load="YES" # enable CPU temperature monitoring coretemp_load="YES" # enable LCD backlight control, ThinkPad buttons, etc acpi_ibm_load="YES" # load firmware for wireless card - I have Intel 6300-N iwn6000fw_load="YES" # desktop-ish filesystems, webcam driver, etc cuse4bsd_load="YES" libiconv_load="YES" fuse_load="YES" libiconv_load="YES" libmchain_load="YES" cd9660_iconv_load="YES" msdosfs_iconv_load="YES" tmpfs_load="YES"

And in /etc/rc.conf:

/etc/rc.conf
hostname="thinkpad.c0ffee.net" # wireless config - DHCP, powersaving, and IPv6 enabled by default wlans_iwn0="wlan0" ifconfig_wlan0="WPA DHCP powersave" ifconfig_wlan0_ipv6="inet6 accept_rtadv" create_args_wlan0="country US regdomain FCC" ipv6_activate_all_interfaces="YES" ip6addrctl_policy="ipv6_prefer" # enable IPv6 autoconfiguration rtsold_enable="YES" rtsold_flags="-aF" # don't hang the boot process while waiting on DHCP background_dhclient="YES" # I still use moused. Supposedly you can evdev/synaptics working natively # in X11 now - but it was too much trouble for me to get working. I don't # use the trackpad (just the nub) and moused works great for that. The -VH # flags enable vertical and horizontal scrolling while holding down the # center button. moused_enable="YES" moused_flags="-VH" # clear /tmp on reboot clear_tmp_enable="YES" # don't let syslog open network sockets syslogd_flags="-ss" # disable the sendmail daemon - I don't use it on laptop sendmail_enable="NONE" # disable kernel crash dumps dumpdev="NO" # sync clock on boot ntpd_enable="YES" ntpd_flags="-g" # dbus is required for basically everything in a graphical system dbus_enable="YES" # enable bluetooth (haven't tried this yet) hcsecd_enable="YES" sdpd_enable="YES" # I compile my ports with sndio - it's like the BSD-equivalent of # pulseaudio (except actually good) sndiod_enable="YES" # enable printing cupsd_enable="YES" # enable use of the webcam (haven't tested yet) webcamd_enable="YES"

You'll need to install the packages for some of those daemons. Install the following:

print/cups
audio/sndio
multimedia/webcamd

Set UTF-8 as the default encoding. Edit the default login class in /etc/login.conf:

/etc/login.conf
default:\ :passwd_format=sha512:\ :copyright=/etc/COPYRIGHT:\ :welcome=/etc/motd:\ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\ :path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ~/bin:\ :nologin=/var/run/nologin:\ :cputime=unlimited:\ :datasize=unlimited:\ :stacksize=unlimited:\ :memorylocked=64K:\ :memoryuse=unlimited:\ :filesize=unlimited:\ :coredumpsize=unlimited:\ :openfiles=unlimited:\ :maxproc=unlimited:\ :sbsize=unlimited:\ :vmemoryuse=unlimited:\ :swapuse=unlimited:\ :pseudoterminals=unlimited:\ :kqueues=unlimited:\ :umtxp=unlimited:\ :priority=0:\ :ignoretime@:\ :umask=022:\ :charset=UTF-8:\ :lang=en_US.UTF-8:

Remember to rebuild the login database after editing this file:

cap_mkdb /etc/login.conf

And finally, some more sysctls. Most taken from Cooltrainer's awesome desktop guide and my FreeBSD server guide.

/etc/sysctl.conf
# increase UFS readahead vfs.read_max=128 # allow users to mount disks without root permissions vfs.usermount=1 # make desktop more responsive under high CPU load kern.sched.preempt_thresh=224 # disable annoying system beep hw.syscons.bell=0 kern.vt.enable_bell=0 # needed for chromium to work kern.ipc.shm_allow_removed=1 # enable IPv6 autoconfiguration net.inet6.ip6.accept_rtadv=1 # suspend on lid close hw.acpi.lid_switch_state=S3 # increase the nub's tracking sensitivity - tweak to your liking hw.psm.trackpoint.sensitivity=255 hw.psm.trackpoint.upper_plateau=125 # uncomment this to disable the touchpad - I never use it # hw.psm.synaptics.touchpad_off=1 # some tweaks to boost network performance over long, fat pipes - see the # networking section of my server guide for details. net.inet.tcp.cc.algorithm=htcp net.inet.tcp.cc.htcp.adaptive_backoff=1 net.inet.tcp.cc.htcp.rtt_scaling=1 net.inet.tcp.rfc6675_pipe=1 net.inet.tcp.syncookies=0 net.inet.tcp.nolocaltimewait=1 kern.ipc.soacceptqueue=1024 kern.ipc.maxsockbuf=8388608 kern.ipc.maxsockbuf=2097152 net.inet.tcp.sendspace=262144 net.inet.tcp.recvspace=262144 net.inet.tcp.sendbuf_max=16777216 net.inet.tcp.recvbuf_max=16777216 net.inet.tcp.sendbuf_inc=32768 net.inet.tcp.recvbuf_inc=65536 net.local.stream.sendspace=16384 net.local.stream.recvspace=16384 net.inet.raw.maxdgram=16384 net.inet.raw.recvspace=16384 net.inet.tcp.abc_l_var=44 net.inet.tcp.initcwnd_segments=44 net.inet.tcp.mssdflt=1448 net.inet.tcp.minmss=524 net.inet.ip.intr_queue_maxlen=2048 net.route.netisr_maxqlen=2048

Now you can reboot for your kernel tunables to take effect. While you have the chance, open up your BIOS and make sure your TPM is disabled—it breaks resume from suspend in FreeBSD in some cases.

Notes on WiFi

I haven't bothered with installing any network managers. To me, they just feel like bloat. FreeBSD's ifconfig stack is so well documented that I've had no issues just adding my networks to /etc/wpa_supplicant.conf. Here is a configuration snippet:

/etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant eapol_version=2 ap_scan=1 fast_reauth=1 network={ ssid="PrettyFlyForAWiFi" psk="secret!!1" priority=5 } # uncomment to enable connecting to any open wifi network. # network={ # priority=0 # key_mgmt=NONE # }

Just do a service netif restart wlan0 when you make any changes.

X11

At this point, you should have decent battery life, suspend/resume on lid close, and display brightness controls working. A much better state than the last time I tried this in the 9.0 days! You're free to just cruise around with tmux in the framebuffer, if that's your thing. But read on if you'd like the details on my X11 and i3 configuration.

To install X11, just navigate to /usr/ports/x11/xorg and run make install clean. Or, just pkg install xorg if you're using binary packages.

When building from source, unless you have some poorly-maintained package that requires HAL, I'd leave it disabled in favor of FreeBSD's native devd. Almost all devices are autodetected out of the box these days, so you no longer need to fiddle with xorg.conf.

If you're running -CURRENT, be sure to install graphics/drm-next-kmod to get the latest graphics drivers ported over from the Linux source. My ThinkPad uses Intel graphics, so I add the following to /etc/rc.conf to enable KMS:

/etc/rc.conf
# for drm-next-kmod: kld_list="/boot/modules/i915kms.ko" # for the stock -RELEASE kernel: # kld_list="i915kms"

Also, be sure to add yourself to the video group!

pw groupmod video -m joe

Drivers

These days, you no longer need to install xf86-video-intel for native graphics support. If you leave it uninstalled, X11 should use the new Glamor 2-D acceleration driver by default. I wouldn't install any graphics drivers unless you have problems with the default configuration.

On FreeBSD, you still need to install xf86-input-keyboard and xf86-input-mouse.

Fonts

Unlike polished distros like Ubuntu, the stock fontconfig installation needs a bit of tweaking to get decent looking fonts. The biggest change these days is that fonts are now good enough that hinting can be disabled entirely. To my surpise, I found that almost all fonts looked much better with all hinting turned off.

First things first though, we should enable the terminus font (since it's the best). You can install it with the terminus-font package (or terminus-ttf for the non-bitmap version). Enable it with the following xorg.conf snippet:

/usr/local/etc/X11/xorg.conf.d/90-fonts.conf
Section "Files" FontPath "/usr/local/share/fonts/terminus-font/" EndSection

You'll need to install some non-monospaced fonts as well. I have the following packages on my system, and it seems enough to cover most websites. You can install your favorites, too.

x11-fonts/bitstream-vera
x11-fonts/cantarell-font
x11-fonts/croscorefonts
x11-fonts/crosextrafonts-caladea
x11-fonts/crosextrafonts-carlito
x11-fonts/droid-fonts-ttf
x11-fonts/emojione-color-font-ttf
x11-fonts/inconsolata-ttf
x11-fonts/liberation-fonts-ttf
x11-fonts/ubuntu-font
x11-fonts/webfonts
x11-fonts/terminus-font
x11-fonts/terminus-ttf

Next, we'll make some fontconfig tweaks. Of course, fonts are a very subjective topic, and all this stuff is just what I think looks best.

cd /usr/local/etc/fonts/conf.d
# disable hinting
ln -s ../conf.avail/10-hinting-none.conf
ln -s ../conf.avail/10-unhinted.conf
# use RGB subpixel rendering - change as a appropriate if you have a
# (rare) non-RGB display
ln -s ../conf.avail/10-sub-pixel-rgb.conf
# use the LCD filter
ln -s ../conf.avail/11-lcdfilter-default.conf
# don't use bitmapped fonts
ln -s ../conf.avail/70-no-bitmaps.conf

I much prefer the slim look of the Liberation fonts over the default choice, DejaVu. To use Liberation fonts for Sans, Sans-Serif, and Monospace, add the following to a new file at 99-liberation.conf:

/usr/local/etc/fonts/conf.d/99-liberation.conf
<?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <alias> <family>serif</family> <prefer><family>Liberation Serif</family></prefer> </alias> <alias> <family>sans-serif</family> <prefer><family>Liberation Sans</family></prefer> </alias> <alias> <family>sans</family> <prefer><family>Liberation Sans</family></prefer> </alias> <alias> <family>monospace</family> <prefer><family>Liberation Mono</family></prefer> </alias> </fontconfig>

You'll also need to remove the following files to fully purge DejaVu from being selected by default:

cd /usr/local/etc/fonts/conf.d
rm 45-latin.conf
57-dejavu-*
rm 60-latin.conf

One last font tweak. To keep terminus-ttf from looking ugly, I had to disable antialiasing for that specific font. Create 99-unantialias-terminus.conf:

/usr/local/etc/fonts/conf.d/99-unantialias-terminus.conf
<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <match target="font"> <test name="family" compare="eq" ignore-blanks="true"> <string>Terminus (TTF)</string> </test> <edit name="hinting"> <bool>false</bool> </edit> <edit name="antialias"> <bool>false</bool> </edit> </match> </fontconfig>

You should now have some decent looking fonts!

Login Manager: SLiM

SLiM is my favorite login manager. It does one thing, and one thing well: it presents me with a username and password prompt, and executes my .xinitrc file. Best of all, it doesn't bring in extra bloat like consolekit and friends. You can install SLiM from the x11/slim port.

To start SLiM on boot, just make a one-line change to /etc/ttys and reboot:

/etc/ttys
#ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure ttyv8 "/usr/local/bin/slim" xterm on secure

I make two changes to the SLiM configuration file: first, I comment out the sessiondir line. This allows me to exec the desktop environment of my choice at the end of my xinitrc file. Second, I enable the cool FreeBSD theme :-)

/usr/local/etc/slim.conf
#sessiondir /usr/local/share/xsessions # ... current_theme fbsd

Desktop Environment: i3

I have used the i3 tiling window manager for years. In my opinion, it strikes the perfect balance between simplicity and ease of configuration. I just don't want to recompile a binary or learn Haskell just to change a font.

If you use i3, be sure to install all the following packages:

x11-wm/i3
x11/i3lock
x11/i3status

xinitrc

There's plenty online to read about i3, so I'll just give you a brief overview of my setup on FreeBSD. .xinitrc is run every time you log in. This file is where you autostart programs, do initial configuration, and start your window manager.

~/.xinitrc
# install misc/qt5ct to configure qt5 themes export QT_QPA_PLATFORMTHEME="qt5ct" # load .Xresources configuration xrdb -merge .Xresources # set the background image (requires graphics/feh) feh --bg-fill /usr/local/share/wallpaper/wallpaper.png & # I use x11/rxvt-unicode for my terminal emulator - you can run a server # process to conserve resources. urxvtd -q -f -o # install sysutils/dunst for lightweight OSD notifications dunst & # I use security/keychain for persistent ssh/gpg agent between logins export SSH_ASKPASS=/usr/local/bin/ssh-askpass eval `keychain --quiet --eval --agents ssh,gpg id_ed25519 id_rsa me@example.com` # start your window manager here exec i3

Xresources

Most crusty old X11 software stores their configuration in Xresources. I split mine up into separate files for easy organization. Standard stuff, urxvt as my terminal, solarized theme, and rofi, an awesome dmenu replacement. You can install it from x11/rofi.

~/.Xresources
Xft.autohint : 0 Xft.lcdfilter : lcddefault Xft.hintstyle : hintnone Xft.hinting : 0 Xft.antialias : 1 Xft.rgba : rgb Xcursor.size : 16 #include ".Xresources.d/solarized" #include ".Xresources.d/urxvt" #include ".Xresources.d/rofi"

~/.Xresources.d/solarized
#define S_base03 #002b36 #define S_base02 #073642 #define S_base01 #586e75 #define S_base00 #657b83 #define S_base0 #839496 #define S_base1 #93a1a1 #define S_base2 #eee8d5 #define S_base3 #fdf6e3 *background: S_base03 *foreground: S_base0 *fadeColor: S_base03 *cursorColor: S_base1 *pointerColorBackground:S_base01 *pointerColorForeground:S_base1 #define S_yellow #b58900 #define S_orange #cb4b16 #define S_red #dc322f #define S_magenta #d33682 #define S_violet #6c71c4 #define S_blue #268bd2 #define S_cyan #2aa198 #define S_green #859900 !! black dark/light *color0: S_base02 *color8: S_base03 !! red dark/light *color1: S_red *color9: S_orange !! green dark/light *color2: S_green *color10: S_base01 !! yellow dark/light *color3: S_yellow *color11: S_base00 !! blue dark/light *color4: S_blue *color12: S_base0 !! magenta dark/light *color5: S_magenta *color13: S_violet !! cyan dark/light *color6: S_cyan *color14: S_base1 !! white dark/light *color7: S_base2 *color15: S_base3

~/.Xresources.d/urxvt
URxvt.font : -*-terminus-medium-r-normal-*-12-*-*-*-*-*-iso8859-1 URxvt.boldFont : -*-terminus-medium-r-normal-*-12-*-*-*-*-*-iso8859-1 URxvt.italicFont : -*-terminus-medium-r-normal-*-12-*-*-*-*-*-iso8859-1 URxvt.boldItalicfont : -*-terminus-medium-r-normal-*-12-*-*-*-*-*-iso8859-1 URxvt.cursorBlink : 1 URxvt.scrollBar : false URxvt.termName : rxvt-unicode-256color URxvt.internalBorder : 2 URxvt.externalBorder : 0 URxvt.urgentOnBell : true URxvt.intensityStyles : true URxvt*scrollTtyOutput : false URxvt*scrollWithBuffer : true URxvt*scrollTtyKeypress : true URxvt*saveLines : 10000 !! install x11/urxvt-perls to get the extensions URxvt.perl-ext-common : default,keyboard-select,clipboard,url-select URxvt.keysym.C-C : perl:clipboard:copy URxvt.keysym.C-V : perl:clipboard:paste URxvt.keysym.M-u : perl:url-select:select_next URxvt.url-select.underline : true !! replace with path to your preferred browser URxvt.url-select.launcher : ~/bin/browser !! keep X selection buffer and clipboard separate URxvt.clipboard.autocopy : false !! disable the ctrl+shift functionality - I always press it on accident URxvt.iso14755 : false

~/.Xresources.d/rofi
rofi.separator-style : solid rofi.font : Terminus (TTF) 9 rofi.lines : 10 rofi.width : 800

Dunst

dunst is a lightweight daemon that provides onscreen notifications. You can install it from sysutils/dunst. Here is my basic configuration with colors to match my i3 theme:

~/.config/dunst/dunstrc
[global] font = "Terminus (TTF) 9" markup = yes format = "%a: %s\n%b" sort = yes indicate_hidden = yes alignment = center show_age_threshold = 60 word_wrap = yes ignore_newline = no geometry = "400x5-30-50" transparency = 6 idle_threshold = 120 follow = mouse sticky_history = yes line_height = 0 separator_height = 2 padding = 10 horizontal_padding = 10 frame_color = "#676E7D" separator_color = frame startup_notification = false frame_width = 2 [shortcuts] close_all = mod4+backslash history = mod4+grave [urgency_low] background = "#2f343f" foreground = "#676E7D" timeout = 5 [urgency_normal] background = "#2f343f" foreground = "#f3f4f5" timeout = 5 [urgency_critical] background = "#2f343f" foreground = "#E53935" timeout = 10

i3

The following is my i3 configuration file. Most of it is taken from the defaults, but I remapped the movement hotkey to use HJKL (instead of the idiotic default with the semicolon) and added some ThinkPad-specific media keybindings and other BSD tweaks.

~/.config/i3/config
# use windows key as modifier set $mod Mod4 font -*terminus-medium-r-normal-*-12-*-*-*-*-*-iso8859-1 floating_modifier $mod # disable titlebars new_window pixel 1 new_float pixel 1 # kill focused window bindsym $mod+Shift+q kill # change focus bindsym $mod+h focus left bindsym $mod+j focus down bindsym $mod+k focus up bindsym $mod+l focus right # alternatively, you can use the cursor keys: bindsym $mod+Left focus left bindsym $mod+Down focus down bindsym $mod+Up focus up bindsym $mod+Right focus right # move focused window bindsym $mod+Shift+h move left bindsym $mod+Shift+j move down bindsym $mod+Shift+k move up bindsym $mod+Shift+l move right # alternatively, you can use the cursor keys: bindsym $mod+Shift+Left move left bindsym $mod+Shift+Down move down bindsym $mod+Shift+Up move up bindsym $mod+Shift+Right move right # split in horizontal orientation bindsym $mod+c split h # split in vertical orientation bindsym $mod+v split v # enter fullscreen mode for the focused container bindsym $mod+f fullscreen toggle # change container layout (stacked, tabbed, toggle split) bindsym $mod+s layout stacking bindsym $mod+w layout tabbed bindsym $mod+e layout toggle split # toggle tiling / floating bindsym $mod+Shift+space floating toggle # change focus between tiling / floating windows bindsym $mod+space focus mode_toggle # focus the parent container bindsym $mod+a focus parent # focus the child container #bindsym $mod+d focus child # switch to workspace bindsym $mod+1 workspace 1 bindsym $mod+2 workspace 2 bindsym $mod+3 workspace 3 bindsym $mod+4 workspace 4 bindsym $mod+5 workspace 5 bindsym $mod+6 workspace 6 bindsym $mod+7 workspace 7 bindsym $mod+8 workspace 8 bindsym $mod+9 workspace 9 bindsym $mod+0 workspace 10 # move focused container to workspace bindsym $mod+Shift+1 move container to workspace 1 bindsym $mod+Shift+2 move container to workspace 2 bindsym $mod+Shift+3 move container to workspace 3 bindsym $mod+Shift+4 move container to workspace 4 bindsym $mod+Shift+5 move container to workspace 5 bindsym $mod+Shift+6 move container to workspace 6 bindsym $mod+Shift+7 move container to workspace 7 bindsym $mod+Shift+8 move container to workspace 8 bindsym $mod+Shift+9 move container to workspace 9 bindsym $mod+Shift+0 move container to workspace 10 # reload the configuration file bindsym $mod+Shift+c reload # restart i3 inplace bindsym $mod+Shift+r restart # exit i3 bindsym $mod+Shift+e exec --no-startup-id "i3-nagbar -t warning -m 'Exit i3?' -b 'yes' 'i3-msg exit'" # resize window (you can also use the mouse for that) mode "resize" { # These bindings trigger as soon as you enter the resize mode # Pressing left will shrink the window’s width. # Pressing right will grow the window’s width. # Pressing up will shrink the window’s height. # Pressing down will grow the window’s height. bindsym h resize shrink width 10 px or 10 ppt bindsym j resize grow height 10 px or 10 ppt bindsym k resize shrink height 10 px or 10 ppt bindsym l resize grow width 10 px or 10 ppt # same bindings, but for the arrow keys bindsym Left resize shrink width 10 px or 10 ppt bindsym Down resize grow height 10 px or 10 ppt bindsym Up resize shrink height 10 px or 10 ppt bindsym Right resize grow width 10 px or 10 ppt # back to normal: Enter or Escape bindsym Return mode "default" bindsym Escape mode "default" } bindsym $mod+r mode "resize" set $bg-color #2f343f set $inactive-bg-color #2f343f set $text-color #f3f4f5 set $inactive-text-color #676E7D set $urgent-bg-color #E53935 # window colors # border background text indicator client.focused $bg-color $inactive-text-color $text-color #4084d6 client.unfocused $inactive-bg-color $inactive-bg-color $inactive-text-color $inactive-bg-color client.focused_inactive $inactive-bg-color $inactive-bg-color $inactive-text-color $inactive-bg-color client.urgent $urgent-bg-colo $urgent-bg-color $text-color $inactive-bg-color bar { status_command i3status tray_output primary colors { background $bg-color separator #757575 # border background text focused_workspace $bg-color $bg-color $text-color inactive_workspace $inactive-bg-color $inactive-bg-color $inactive-text-color urgent_workspace $urgent-bg-color $urgent-bg-color $text-color } } # # Application keybindings # start a terminal bindsym $mod+Return exec urxvtc # ctrl+alt+L to lock the screen bindsym Control+mod1+l exec --no-startup-id i3lock -i /usr/local/share/wallpaper/wallpaper.png -t # raise/lower volume with the ThinkPads volume keys. The mute key appears # to be a hardware-level mute. It works, but it doesn't register any # change in the OSS mixer. bindsym XF86AudioRaiseVolume exec --no-startup-id "mixer vol +5 && pkill -SIGUSR1 i3status" bindsym XF86AudioLowerVolume exec --no-startup-id "mixer vol -5 && pkill -SIGUSR1 i3status" # start rofi (program launcher) bindsym $mod+d exec rofi -show drun # start rofi (window switcher) bindsym $mod+Tab exec rofi -show window # start rofi (ssh host autocomplete) bindsym $mod+x exec rofi -show ssh # some windows should float by default for_window [class="feh"] floating enable for_window [class="Lxappearance"] floating enable for_window [class="pinentry-gtk-2"] floating enable for_window [class="Arandr"] floating enable for_window [title="Preferences"] floating enable for_window [title="Download Manager"] floating enable

i3status

I use i3status to display the clock and system stats on the bottom of the screen. My configuration shows network connectivity (wired, wireless, tethered, IPv6), disk/CPU usage, system load, CPU temperature, volume, battery status, and (of course) the current time.

~/.config/i3status/config
general { colors = true interval = 2 output_format = "i3bar" } ethernet em0 { format_up = "E: %ip" format_down = "" } ethernet ue0 { format_up = "iPhone: %ip" format_down = "" } wireless wlan0 { format_up = "%essid %ip" format_down = "no WiFi" } tztime local { format = "%Y-%m-%d %H:%M" } load { format = "%1min" } disk "/" { format = "%free" } cpu_usage { format = "CPU %usage" } cpu_temperature 0 { format = "%degrees°C" } volume master { format = "VOL %volume" format_muted = "MUTE" } battery 0 { format = "%status %percentage" } ipv6 { format_up = "IPv6" format_down = "" } path_exists VPN { path = "/dev/tun0" format_down = "" format = "VPN" } order += "path_exists VPN" order += "ipv6" order += "ethernet ue0" order += "wireless wlan0" order += "ethernet em0" order += "disk /" order += "cpu_usage" order += "load" order += "cpu_temperature 0" order += "volume master" order += "battery 0" order += "tztime local"

Screen Lock on Lid Close

As much as I hate to say it, one thing systemd makes really easy is the ability to lock the screen on ACPI events. On FreeBSD, making this work is a total hack. But, it is possible!

Edit /etc/rc.suspend and add in the following bolded line (replacing yourusername with your user name):

/etc/rc.suspend
# If a device driver has problems suspending, try unloading it before # suspend and reloading it on resume. Example: # kldunload usb /usr/bin/su yourusername -c 'DISPLAY=:0.0 /usr/local/bin/i3lock -i /usr/local/share/wallpaper/wallpaper.png' /usr/bin/logger -t $subsystem suspend at `/bin/date +'%Y%m%d %H:%M:%S'` /bin/sync && /bin/sync && /bin/sync /bin/sleep 3

Of course, if you use something else (like xscreensaver) just patch in the appropriate command here instead. It's probably possible to do this more cleanly with devd, but I haven't had a chance to look into it yet.

Applications

In case you are interested, the following is a list of applications I use with this setup. They work well with a terminal/tiling workflow and are fully compatible with FreeBSD. I won't dive into my configs for all these here.