stumpwmを常用に。

日頃ratpoisonを使ってましたが、以前チャレンジして挫折したstumpwmに再度挑戦してみました。

以前は何が悪かったのかわかりませんでしたが、普通のインストール方法で問題無くいけました。
切り替えてみると、実に使いやすいです。ratpoisonの作者が作っているだけあり、通常使用ではratpoisonと全く使用感は変わりません。

ですが、仮想デスクトップについては、ratpoisonの時にお世話になったrpwsではなく、stumpwmのgroupというのを使う点が最初気付きませんでした。

C-t g c
グループを新規作成
C-t g g
グループ一覧を表示
C-t g k
指定したグループを削除

のような感じで、グループを作成したり消したりできます。グループと言ってますが、概念的には仮想デスクトップで問題は特に無いと思います。

また、ウィンドウのタイリングもratpoisonよりずっとよくなり、ratpoisonでは時折見えていた隙間も、ほとんど見えなくなりました。

・・・とまぁ、いいことばかりかと思いきや、常用していたratpoison.elとか、ratpoisonに依存していた設定を移行しなけりゃなりません。
で、emacsではspecial frame(かな?)というのを使って、特定のフレームを常にratpoison上の特定フレームに設定していました。
最近gentooではソースからコンパイルしたEmacsCVS Headを利用してるんですが、これがなぜかframe-visible-pを常にtを返してくれていたため、現在の設定が使えなくなってしまいました。

frmae-visible-pが使えないと、emacs上からではフレームの表示云々とかをチェックすることができないため、どうしようかと思案し、結局stumpwmにやってもらうことにしました。

(defun my-global-window-number (name &optional equal?)
  "returns a number of the name of all the window"
  (let ((groups (sort-groups (current-screen)))
        (windows nil))
    (dolist (group groups)
      (dolist (window (group-windows group))
        ;; Don't include the current window in the list
        (let ((end (min (length (window-name window)) (length name))))
          (when (and (string-equal (window-name window) name :end1 end
                                   :end2 end)
                     ;; オプションが指定されている場合、同一ウィンドウである場合は無視される。
                     (if equal?
                         (not (eq window (current-window)))
                       t))
            (return-from my-global-window-number (window-number window)))))))
  )

(defun my-global-window (name &optional equal?)
  "returns a number of the name of all the window"
  (let ((groups (sort-groups (current-screen)))
        (windows nil))
    (dolist (group groups)
      (dolist (window (group-windows group))
        ;; Don't include the current window in the list
        (let ((end (min (length (window-name window)) (length name))))
          (when (and (string-equal (window-name window) name :end1 end
                                   :end2 end)
                     ;; オプションが指定されている場合、同一ウィンドウである場合は無視される。
                     (if equal?
                         (not (eq window (current-window)))
                       t))
            (return-from my-global-window window))))))
  )

(defun my-global-window-names ()
  "Returns a list of the names of all the windows in the current screen."
  (let ((groups (sort-groups (current-screen)))
        (windows nil))
    (dolist (group groups)
      (dolist (window (group-windows group))
        ;; Don't include the current window in the list
        (when (not (eq window (current-window)))
          (setq windows (cons (window-name window) windows)))))
    windows))

;; インタラクティブに実行される際に、補完ができるようにする。
(define-stumpwm-type :my-global-window-names (input prompt)
  (or (argument-pop input)
      (completing-read (current-screen) prompt (my-global-window-names))))

(define-stumpwm-command "pull-window-from-title" ((arg :my-global-window-names "Select: "))
  "pull window what in args to current frame"
      ;; 表示されていない場合のみpullする。
  (pull-window-by-number (my-global-window-number arg t)))

;; emacsのspecial-display-frame用のコマンド。
;; 実際には、指定した名前のウィンドウを指定したフレームに入れる。
(defcommand my-special-frame-display (name number) ((:string) (:number))
  (save-frame-recursion
   (let ((win (my-global-window name t)))
     (if (not (eq win (frame-window (frame-by-number (window-group win) number))))
         (pull-window win (frame-by-number (window-group win) number)))))
  )

みたいな感じで.stumprcに記述し、emacsでは

(call-process "stumpish" nil nil nil "my-special-frame-display emacs-special 1")

とでも記述しておけば、指定した名前を持つウィンドウが、frame1に表示されていない場合には表示されるようになります。
問題となったのはこの程度で、他は特に問題無く満足できます。

この他、モードラインがデフォルトで付いてくるようになっています。

ratpoisonをお使いの方、lisp好きな方はいかがでしょうか?