View all entries in Miscellaneous

Trying out StumpWM

Updated 2008-08-16: Newer and complete ~/.stumpwmrc

StumpWM is a tiling window manager written in Common Lisp with access to an interactive console.

I've been meaning to try it out for some time. Download and install according to the documentation. I use SBCL-1.0.18. bzexe/gzexe helps getting down the binary size (stumpwm is an executable SBCL image dump). If you, like me, use Ubuntu, you'll want to add this to your ~/.gnomerc:

export WINDOW_MANAGER=$HOME/local/bin/stumpwm

replacing the path with wherever you've installed it. This will give you gnome-panel and default theme settings (such as fonts), but with stumpwm instead of metacity.

Full ~/.stumpwmrc:

;; vim:filetype=lisp
;;
;; .stumpwmrc for mail@mikael.jansson.be

(in-package :stumpwm)

;; change the prefix key to something else
(set-prefix-key (kbd "F20")) ; F20 = Hyper here

;; prompt the user for an interactive command. The first arg is an
;; optional initial contents.
(defcommand colon1 (&optional (initial "")) (:rest)
  (let ((cmd (read-one-line (current-screen) ": " initial)))
    (when cmd
      (eval-command cmd t))))

(defcommand pull-window-from-list (&optional (fmt *window-format*)) (:rest)
"Allow the user to Select a window from the list of windows and pull
the selected window into the current frame. For information of menu bindings
@xref{Menus}. The optional argument @var{fmt} can be specified to
override the default window formatting."
  (if (null (group-windows (current-group)))
      (message "No Managed Windows")
      (let* ((group (current-group))
             (window (second (select-from-menu
                              (current-screen)
                              (mapcar (lambda (w)
                                        (list (format-expand *window-formatters* fmt w) w))
                                      (sort-windows group))))))

        (if window
            (pull-window window)
            (throw 'error :abort)))))

(defcommand paste-x-selection () (:rest)
  "Universal rat-less X paste."
  (let ((cmd (concatenate 'string "insert " (get-x-selection))))
     (eval-command cmd)))

(define-key *top-map* (kbd "M-TAB") "fother")
(define-key *top-map* (kbd "s-ESC") "exec xfce4-terminal")

;; meta-hjkl
(define-key *top-map* (kbd "M-k") "move-focus up")
(define-key *top-map* (kbd "M-j") "move-focus down")
(define-key *top-map* (kbd "M-l") "move-focus right")
(define-key *top-map* (kbd "M-h") "move-focus left")
;; control-meta-hjkl
(define-key *top-map* (kbd "C-M-k") "move-window up")
(define-key *top-map* (kbd "C-M-j") "move-window down")
(define-key *top-map* (kbd "C-M-l") "move-window right")
(define-key *top-map* (kbd "C-M-h") "move-window left")

;; (shift-)meta-space
(define-key *top-map* (kbd "S-M-SPC") "prev-in-frame")
(define-key *top-map* (kbd "M-SPC") "next-in-frame")

(define-key *top-map* (kbd "s-1") "gselect 1")
(define-key *top-map* (kbd "s-2") "gselect 2")
(define-key *top-map* (kbd "s-1") "gselect 1")
(define-key *top-map* (kbd "s-2") "gselect 2")
(define-key *top-map* (kbd "s-3") "gselect 3")
(define-key *top-map* (kbd "s-4") "gselect 4")
(define-key *top-map* (kbd "s-5") "gselect 5")
(define-key *top-map* (kbd "s-6") "gselect 6")
(define-key *top-map* (kbd "s-7") "gselect 7")
(define-key *top-map* (kbd "s-8") "gselect 8")
(define-key *top-map* (kbd "s-9") "gselect 9")

;; Jump to the previous group ("workspace")
(define-key *top-map* (kbd "s-^") "gother")

(defvar *query-map* nil
  "The keymap with net queries (e.g. IMDB)")

(setf *query-map*
  (let ((m (make-sparse-keymap)))
     (define-key m (kbd "i") "imdb")
     (define-key m (kbd "g") "google")
     (define-key m (kbd "w") "wikipedia")
     m))

(defmacro make-web-jump (name url-prefix)
  `(defcommand ,name (search) ((:rest ,(string-capitalize (string-downcase (concatenate 'string (symbol-name name) ": ")))))
     (run-shell-command (format nil "opera -remote 'openURL(~A=~A)'"
                             ,url-prefix (substitute #\+ #\Space search)))))

(make-web-jump imdb "http://www.imdb.com/find?q")
(make-web-jump google "http://www.google.com/search?q")
(make-web-jump wikipedia "http://en.wikipedia.org/wiki/Special:Search?fulltext=Search&search")

(setf *root-map*
  (let ((m (stumpwm:make-sparse-keymap)))
    (define-key m (kbd "g") '*groups-map*)
    (define-key m (kbd "G") "vgroups")

    ; (define-key m (kbd "C-g") "abort")
    (define-key m (kbd "C-h") "help")
    ;; XXX: doesn't work yet if typed with altgr-å...
    (define-key m (kbd "?") "help")
    (define-key m (kbd ";") "eval")
    (define-key m (kbd ",") "colon")

    (define-key m (kbd "#") "mark")

    ;; delete pushes the X button of a window, kill is like /bin/kill
    (define-key m (kbd "C-w") "delete")
    (define-key m (kbd "C-q") "kill")

    ; (define-key m (kbd "h") "banish") ; hide the mouse

    (define-key m (kbd "w") "windowlist")
    (define-key m (kbd "W") "pull-window-from-list")

    ;; stuff contents of X11 selection into current window
    (define-key m (kbd "p") "paste-x-selection")

    ;; works like screen, and quoteright is the regular quote mark (')
    (define-key m (kbd "t") "title")
    (define-key m (kbd "quoteright") "select")
    (define-key m (kbd "f") "only") ; sort-of like fullscreen
    (define-key m (kbd "F11") "fullscreen") ; for apps that otherwise refuse to go fullscreen, e.g. vlc

    (define-key m (kbd "d") "remove") ; delete current frame

    (define-key m (kbd "r") "iresize")
    ;; Reverse of the default: s to make a vertical stripe, S to cut in half
    (define-key m (kbd "s") "hsplit")
    (define-key m (kbd "S") "vsplit")

    ;; Run
    (define-key m (kbd "!") "exec ")
    ;; Open
    (define-key m (kbd "o") "colon1 exec gnome-open ")
    ;; Browse
    (define-key m (kbd "b") "colon1 exec opera http://www.")
    ;; Connect
    (define-key m (kbd "c") "colon1 exec xfce4-terminal -x ssh -l ")
    ;; Edit
    (define-key m (kbd "e") "colon1 exec gvim ")

    ;; web queries
    (define-key m (kbd "q") '*query-map*)
    m))

;; Message window font ("The Bar")
(set-font "-microsoft-comic sans ms-medium-*-*-*-17-*-*-*-*-*-iso8859-15")
(set-bg-color "Yellow")
(set-fg-color "Black")
(set-border-color "Red")
(set-msg-border-width 5)

(setf *message-window-padding* 20)

(setf *maxsize-border-width* 3)
(setf *normal-border-width* 3)
(setf *window-border-style* :thick)
(setf *transient-border-width* 5) ; popups
(setf *mouse-focus-policy* :sloppy)
(set-focus-color "Blue")

The gother mapping is taken directly from BeOS. For metacity, you can use my workspace_switcher script (start the Python app in the background, map the shell script to a key combo) at https://svn.jansson.be/public/workspace_switcher/.

I haven't toyed with frame/window placement rules yet. Looks promising, though. The documentation has a list of commands, which you can try out interactively by <prefix> ;. A useful command is loadrc (reloads ~/.stumpwmrc.) There's an issue with AltGr (Mode_switch according to xev) and the interactive console, so if you are on a Swedish keyboard and would like to type in @ in e.g. the ssh command you'll have to fix StumpWM or nag the helpful people in #stumpwm until they fix the issue.

Enjoy!


Responses

You can follow any responses to this entry through the RSS 2.0 feed.

  1. Joe said on August 14th, 2008 at 17:12 (link)

    You should try out xmonad, its similar, but has a much bigger and more helpful userbase and pile of contributed configs/extensions.

  2. Mikael Jansson said on August 14th, 2008 at 17:42 (link)

    I’ve read about xmonad, and that there are people using it.

  3. dranorter said on December 23rd, 2008 at 21:56 (link)

    Can we see a screenshot?

If this is the first time you comment on my site, your post might get held up in the moderation queue. Don't panic, I'll approve it as soon as possible!

Code (i.e. literal) blocks should be wrapped inside <PRE>.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Close
Powered by ShareThis