The perfect Open Source laptop
I'm a huge fan of FreeBSD. So much so that all my systems are running the latest version (8.1 as of this writing). Many of my blog posts are about FreeBSD or mention it in some way. So maybe that's why it bothers me to say this: FreeBSD just isn't well suited for a portable computer. I've fought it for some time and come to the conclusion that Linux just works better on laptops. A few of my gripes:
- Non-journaled filesystems suck. Using UFS + soft-updates helps but can be tedious on large drives. I think journaling + soft-updates is coming in 9.0 so maybe the level of suck will be less. Nonetheless, having to fsck a drive is an idea whose time has passed.
- ZFS kicks major butt but really needs a 64-bit CPU plus several gigs of memory, which leaves older laptops like mine out to dry. I can't get it to work as a root filesystem on any of my portable systems. I get a kernel panic on my i386 machines and the boot loader doesn't properly recognize my drives on my lone amd64 laptop.
- There's no good wireless manager for any of the BSDs. Linux has one called Wicd. It works with anything you throw at it, including WAPs that require an SSL certificate. You can do most of that in FreeBSD but it requires you to edit several config files. Try changing between locations that use different SSIDs or different encryption. Wicd continues to just work without needing to change any configs, even with the built in ncurses interface. Wicd is heavily tied to Linux (it makes use of the Linux proc filesystem) so porting it would basically require a rewrite.
- For some reason, Xorg seems to be hit or miss, driver-wise. It frequently hard locks on one of my systems with a Radeon but not another with a newer Radeon. I've never seen a lock up using the proprietary Nvidia drivers but the Nouveou drivers don't support 3D acceleration on all cards. I realize that most of the Xorg stuff is the same between BSD and Linux so that begs the question of why I see this on BSD but not Linux?
FreeBSD is rock solid on my desktop machines and ZFS on the root file system is a dream, so it's a bit disheartening that that experience didn't carry over to laptop-land. So, after dealing with the above annoyances I decided to throw my favorite Linux distribution on my laptops: Gentoo.
I wrote about Gentoo some time ago, ironically because I was critical of some things I needed in FreeBSD before I made the switch. Gentoo is unlike every Linux distribution out there (except the Linux From Scratch project) in that you have to build it in order to use it. This can be a serious turn off for folks that just want to install and get on with life, but I find it very intriguing and a great way to understand Linux at a much deeper level. The same idea holds when you want to install software; instead of prepackaged archives, you build it from source. This process is made easier with the Portage software management system, but you can tweak a near limitless amount of things to get exactly the kind of system you want. No bloat, no muss, no fuss.
With Gentoo installed, your next step to laptop bliss is to install Wicd to manage both your wired and your wireless interface (assuming you have one). Wicd is in the base Portage system, and assuming you chose the "desktop" Portage profile, installing Wicd should install a bunch of stuff. If you followed the Gentoo installation documentation, you probably added one or more of your Ethernet interfaces to your init scripts. Delete the net.eth scripts, but leave the net.lo script for the loopback interface. Add wicd to your init scripts by using 'rc-update add wicd default'. This ensures the wicd daemon starts so you can connect to networks. Since you don't have Xorg installed, you can use the ncurses interface by typing wicd-curses. Check out the man page for wicd for more details.
Next up is getting Xorg installed. This can take a while, but it basically involves specifying your video card type and input method (typically evdev on modern versions of the Linux kernel) in the /etc/make.conf file. Building Xorg will likely take quite a while so now might be a good time to catch up on your bash.org quotes. Make sure you get hald and dbus started and added to your init scripts when the build completes.
With the X server built, we're in the home stretch. The next thing to install is some sort of desktop environment like Gnome or KDE, or my preference, a simple window manager. You are, of course, free to install whatever tickles your fancy but for all my portable systems, nothing, and I mean NOTHING, beats StumpWM for a window manager. StumpWM is a rewrite of the Ratpoison window manager in Common Lisp. Ratpoison is heavily inspired by GNU Screen, so if you're an avid screen user, you'll feel right at home with both Ratpoison and StumpWM. Let me give you a few reasons why I think you should give one of these window managers a try before you go kicking and screaming back to Gnome or KDE.
- First and foremost, they're keyboard-driven. You're on a laptop, probably with an annoying touch pad or worse, the little pencil eraser pointer-thingy. Why would you inflict that kind of pain on yourself when you'll be far more productive if you could just keep your fingers on the keyboard?
- Ever fly commercial? Ever get stuck in coach next to someone that doesn't know the meaning of personal space? Good luck using an external mouse when you're crammed in like a sardine at 60,000 feet.
- If you write code for a living or even just as a hobby (you weirdo
), your brain will appreciate not having to break concentration to reach for a mouse when you need to switch between terminals or editors. - They automatically maximize windows for you. You can see everything without needing to get a window sized just right with the mouse. You can, of course resize windows and split them as needed.
- Pretty much anything you can do on a laptop would be enhanced by a window manager that is keyboard controlled.
With all the above in mind, you'll want to pick either Ratpoison or StumpWM to use. Ratpoison is written in C, uses minuscule amounts of memory, and is easily installed using the 'emerge' command. StumpWM is written in Common Lisp, so you'll need to install that first. If hearing the word Lisp sounds vaguely familiar, it should be. Lots of other open source software is written in Lisp or uses it, such as Emacs and The Gimp. Some closed source software uses Lisp as well.
To get a Lisp interpreter, you'll want to install either the CLISP interpreter or the SBCL interpreter. I highly recommend you install SBCL instead of CLISP. Add the following to your '/etc/portage/package.use' file (you may need to create the /etc/portage directory and the package.use file if they don't exist):
media-libs/gd fontconfig dev-lisp/sbcl doc
Next, add the following to your '/etc/portage/package.keywords' file:
x11-wm/stumpwm ~x86
Your USE flags in '/etc/make.conf' should look at minimum like the following:
USE="sbcl -qt4 -kde X dbus hal -cups"
This should get you a working install of StumpWM but the version in Portage is pretty old and looks like it hasn't been touched in some time. Plus it doesn't even compile a StumpWM binary for you! Instead, you should use the version in the Git repository. In addition to making the changes above, emerge the following ports like so:
sudo emerge -av cl-clx cl-ppcre autoconf
You may need to install Git in order to grab the StumpWM source. Grab the StumpWM source like so:
git clone git://git.savannah.nongnu.org/stumpwm.git
I generally just keep the StumpWM source in my home directory. It doesn't take much space at all and there are several goodies in there. Go into that directory now and type "autoconf". Once that completes, type "./configure" You should see a lot of messages whizz by. Make sure the output of the configure script shows you're using SBCL. Once that completes, type "make". That should actually compile the StumpWM and Stumpish (Stumpish is a "shell" to StumpWM) binaries for you. Once that completes, you should have a StumpWM binary in your ~/stumpwm folder and a Stumpish binary in your ~/stumpwm/contrib folder. Copy both to /usr/local/bin as root. I tried adding my ~/stumpwm folder to my PATH and running it that way but it just doesn't work right, so installing both to /usr/local/bin is the way to go.
With a fresh copy of StumpWM built, add it to your .xinitrc: "echo 'exec stumpwm' >> ~/.xinitrc" and fire up a startx! You should see a welcome message. If you do, congrats! If not, you may want to try the StumpWM wiki.
Below is my .stumpwmrc file for you to pick apart and customize for your own needs:
;; My key bindings
(in-package stumpwm)
(define-key stumpwm:*top-map* (stumpwm:kbd "F12") "mode-line")
;; switching window
(define-key stumpwm:*top-map* (stumpwm:kbd "M-Up") "pull-hidden-previous")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-Down") "pull-hidden-next")
;; switching frames
(define-key *top-map* (kbd "M-Page_Down") "fnext")
;; switching groups
(define-key stumpwm:*top-map* (stumpwm:kbd "M-Left") "gprev")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-Right") "gnext")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F1") "gselect 1")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F2") "gselect 2")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F3") "gselect 3")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F4") "gselect 4")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F5") "gselect 5")
;; splits
(define-key stumpwm:*top-map* (stumpwm:kbd "M-s") "vsplit")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-S") "hsplit")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-q") "only")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-r") "remove")
;; programs
(define-key stumpwm:*top-map* (stumpwm:kbd "M-c") "exec xfce4-terminal")
(define-key stumpwm:*top-map* (stumpwm:kbd "M-F") "exec firefox-2")
;; mouse
(setf *mouse-focus-policy* :sloppy)
;; prefix key
(set-prefix-key (kbd "Pause"))
;; wallpaper
;; (stumpwm:run-shell-command "display -window root '/home/<USER>/backgrounds/someimage.jpg'")
(stumpwm:run-shell-command "fbsetbg -l")
;; ff command
(define-stumpwm-command "firefox" ()
"Run or switch to firefox."
(run-or-raise "firefox" '(:class "Firefox")))
(define-key *root-map* (kbd "w") "firefox")
;; Multimedia Keys
(load "/home/<USER>/.stumpwm/multimedia-keys.lisp")
; Brightness Adjust (Fn + Up/Down)
(run-shell-command "xmodmap -e \'keycode 212 = XF86LaunchE'")
(run-shell-command "xmodmap -e \'keycode 101 = XF86LaunchD'")
(define-key stumpwm:*top-map* (stumpwm:kbd "XF86LaunchE") "exec brightness +")
(define-key stumpwm:*top-map* (stumpwm:kbd "XF86LaunchD") "exec brightness -")
;; Load Mode line
;; (load "/home/<USER>/.stumpwm/modeline-config.lisp")
(toggle-mode-line (current-screen) (current-head))
;; show the time in the mode-line
(setf *screen-mode-line-format*
(list '(:eval (run-shell-command "date '+%R, %F %a'|tr -d [:cntrl:]" t)) " | [^B%n^b] %W"))
;; Modeline Group Scrolling
(setf stumpwm:*mode-line-click-hook*
(list (lambda (&rest args)
(cond ((eq (second args) 5)
(run-commands "gnext"))
((eq (second args) 4)
(run-commands "gprev"))))))
;; Theming
;; (load "/home/<USER>/.stumpwm/effects.lisp")
;; Male's code for key sequence display
(defun key-press-hook (key key-seq cmd)
(declare (ignore key))
(unless (eq *top-map* *resize-map*)
(let ((*message-window-gravity* :bottom-right))
(message "Keys sequence: ~A" (print-key-seq (reverse key-seq))))
(when (stringp cmd)
;; Give 'em time to read it.
(sleep 0))))
(defmacro replace-hook (hook fn)
`(remove-hook ,hook ,fn)
`(add-hook ,hook ,fn))
(replace-hook *key-press-hook* 'key-press-hook)
Feel free to use what you can and look around for anything I missed. It'll take a bit of getting used to, but once you do, using a keyboard driven, tiling window manager on your laptop becomes second nature and you wonder how you went without it. For a great video introduction to StumpWM, go here. Enjoy!