StumpWM
Я уже рассматривал простой тайловый оконный менеджер, который очень удобен в работе - RatPoison. Проблема заключается только в том, что данный оконный менеджер можно настраивать только в рамках, предусмотренных программистами. И ничего более… К примеру, строку информации необходимо уже реализовывать с помощью внешних программ. Что порой бывает не удобно и порой не обладает достаточным функционалом.
Я уже несколько раз до сего момента обращал внимание на тайловый менеджер StumpWM, который написан на языке Lisp и который, судя по описанию, можно настраивать полностью, фактически переписывая код самого оконного менеджера. Но столкнулся с проблемами в установке, а потому довольно надолго оставлял эту затею.
Один раз мне удалось установить stumpwm непосредственно из AUR. Я об этом описывал в статье Установка StumpWM. Но чуть позже, после того, как пакет был обновлен, сборка стала невозможна. Каждый раз прерывалась ошибками, то компиляции, то ошибками сборки самого пакета.
В конце концов Павел Вязовой подсказал мне, что не нужно собирать пакет. Достаточно только откомпилировать пакет и использовать при запуске указание полного пути до папки сбинарником. Что я, естественно, и сделал. Все оказалось много проще, чем я думал.
Подготавливаем систему к установке, для этого ставим пакетыsbcl, cl-ppcre и git, если они еще не были установлены до этого. И создаем файл ~/.sbclrc со следующим содержимым:
(require 'asdf)
(pushnew #p"/usr/share/common-lisp/systems/" asdf:*central-registry* :test #'equal)
(asdf:operate 'asdf:load-op 'cl-ppcre)
Теперь выполняем следующие действия для установки stumpwm:
$ git clone git://git.savannah.nongnu.org/stumpwm.git
$ cd stumpwm
$ autoconf && ./configure && make
Теперь прописываем в ~/.xinitrc строку запуска данного оконного менеджера:
exec /PATH/TO/stumpwm
Теперь можно запускать иксы, или перезапускать их для входа в новое окружение.
Если вы ничего не увидите, не пугайтесь, все нормально. По умолчанию stumpwm не запускает никаких программ и не задает внешний вид своего окружения. Все, что необходимо, можно будет запускать из файла конфигурации stumpwm или из файла ~/.xinitrc, который используется для запуска самого оконного менеджера. У меня данный файл выглядит так:
#!/bin/bash
#
# .xsession/.xinitrc
export G_FILENAME_ENCODING=@locale
export G_BROKEN_FILENAMES=1
export OOO_FORCE_DESKTOP=gnome
export GDK_USE_XFT=1
export EDITOR=emacsclient
#переключение раскладки
#export LC_CTYPE=ru_RU.utf8
export XMODIFIERS="@im=SCIM"
export GTK_IM_MODULE="scim"
export QT_IM_MODULE="scim"
scim -d &
#загрузка коинфига клавиш и внешнего вида
xmodmap ~/.Xmodmap
xrdb ~/.Xdefaults
# D-bus
if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; then
eval `dbus-launch --sh-syntax --exit-with-session`
fi
#установка параметров клавы, энергосбережения, шрифтов и скорости мыши
xset r rate 350 30
xset -dpms &
xset s off &
xset fp+ /usr/share/fonts/local/
xset fp+ /usr/share/fonts/artwiz-fonts/
xset fp+ ~/.fonts/snap-11/
xset fp rehach
xset m 3
#установка рисунка рабочего стола
eval `cat ~/.fehbg` &
#синхронизация буферов обмена
autocutsel -f
#управление мышью логитех
lomoco -g &
#скрываем курсор мыши через определенное время
unclutter -idle 20 &
# run daemon scripts
/etc/X11/Xsession
#запуск демона автомонтирования
pgrep halevt >> /dev/null || halevt &
#установка темы курсоров
xsetroot -cursor_name left_ptr &
#включение композита
xcompmgr -a &
exec /home/git/stumpwm/stumpwm
По умолчанию в качестве префикса клавиш используется сочетание клавиш C-t, точно так же как и в крысином яде. Преимущества данного подхода очевидны, и были разобраны в ряде моих статей, поэтому не буду на нем останавливаться подробно.
Для того, чтобы изменить конфигурацию, внешний вид оконного менеджера, необходимо создать в домашней папке файл ~/.stumpwmrc, который в дальнейшем редактируем. Текст файла представляет собой обычную программу на языке программирования lisp.
Для задания внешнего вида фреймов используется следующий код:
(set-font "-*-terminus-medium-r-normal-*-12-*-*-*-*-*-iso10646-1")
(setf *normal-border-width* 0
*maxsize-border-width* 0
*transient-border-width* 1
*window-border-style* :thick) ; :thick :thin :tight :none
(setf *startup-message* "Never Stop Hacking!"
*mouse-focus-policy* :sloppy ;; :click, :ignore, :sloppy
;;Set the message and input box to the bottom right. This way it overlaps with mode-line.
*message-window-gravity* :bottom-left
*input-window-gravity* :bottom-left
*frame-number-map* "123qwe"
*window-number-map* "123qwe")
Для определения префикса клавиш используется строка:
(set-prefix-key (kbd "s-s"))
В данном случае назначена комбинация Win-S.
Для определения основных клавиатурных комбинаций лучше всего определить пару функций:
;; define keys
(defmacro defkey-top (key cmd)
`(define-key *top-map* (kbd ,key) ,cmd))
(defmacro defkeys-top (&rest keys)
(let ((ks (mapcar #'(lambda (k) (cons 'defkey-top k)) keys)))
`(progn ,@ks)))
(defmacro defkey-root (key cmd)
`(define-key *root-map* (kbd ,key) ,cmd))
(defmacro defkeys-root (&rest keys)
(let ((ks (mapcar #'(lambda (k) (cons 'defkey-root k)) keys)))
`(progn ,@ks)))
После чего определение клавиатурных комбинаций записывается очень просто:
(defkeys-top
("s-RET" "exec sakura")
("s-p" "dmenu")
("s-R" "reinit")
("s-Q" "quit")
("s-b" "mode-line"))
Запускать программы через клавиатурные комбинации можно двумя способами:
-
Используя в качестве команды exec command
-
Определить функцию через RunOnRaise. Данная функция позволяет, если программа не была запущена до сих пор, запустить ее, а если была запущена, то переключиться на нее. Очень удобно! Сначала прописываем саму функцию, а затем прописываем сочетание клавиш:
(defcommand firefox () () “Run or switch to firefox.” (run-or-raise “firefox” ‘(:class “Firefox”)))
(defkeys-root (“f” “firefox”))
Для того, чтобы получить информацию о группах и окнах, которые расположены в этих группах или для вывода дополнительной информации, типа температуры процессора, не нужно использовать сторонних программ, достаточно прописать в конфигурации использование modeline… Для этого прописываем в конфигурации следующие строки, которые задают внешний вид строки и описывают ее содержимое.
;;;; The Mode Line
(setf *mode-line-background-color* "DarkRed"
*mode-line-foreground-color* "White"
*mode-line-border-color* "White"
*mode-line-timeout* 1
*mode-line-screen-position* :top
*window-format* "^B^8*%n%s%m%30t :: ^7*"
*group-format* "%t"
*screen-mode-line-format* (list "^B" `(:eval (stumpwm:run-shell-command "printf \"`date +'%a, %d %B %H:%M'`\"" t))
" ^ B|| "
`(:eval (stumpwm:run-shell-command "printf \"`sensors| grep temp3| awk '{print ($2)}'`\"" t))
" || ^b^7*%g^B || %w ^1*%N" ; Current group and frames
))
;; turn on/off the mode line for the current screen only.
(if (not (head-mode-line (current-head)))
(toggle-mode-line (current-screen) (current-head)))
При использовании внешних программ для получения информации следует обратить внимание на то, что вывод обычно заканчивается символом перевода строки. И если в modeline вывести данный вывод, то modeline получиться высотой в две строки, причем вторая строка будет пустовать. Для избежание данной ситуации существует два пути:
- Использование потока вывода с преобразованием последовательности символов.
(run-shell-command "date +'%a %d %b %H:%M:%S' | tr -d [:cntrl:]" t)
- Использование для вывода функции printf (как это показано выше в конфигурации modeline)
Я использую второй вариант, просто потому, что он мне больше нравиться. Как уже стало понятным, modeline можно разбивать на несколько строк, для получения более информативного вывода.
Необходимо так же помнить, что в modeline до сих пор не реализована возможность выравнивания текста по правому краю.
Для автоматического запуска программ при старте оконного менеджера необходимо использовать следующий код:
(run-shell-command "xmodmap ~/.Xmodmap")
(run-shell-command "xrdb ~/.Xdefaults")
Конфигурирование stumpwm возможно осуществлять несколькими способами:
- Правкой файла конфигурации, с последующей его повторной загрузкой
(defcommand reinit () ()
(run-commands "reload" "loadrc"))
(defkeys-top
("s-R" "reinit"))
- Использование сочетаний клавиш для ввода нужного кода lisp. Для этого жмем C-t : и вводим нужные нам функции или команды. В примере используется префикс по умолчанию, если он был изменен в конфиге, то нужно использовать именно его.
В stumpwm так же, как и во многих тайловых оконных менеджерах можно определять правила расположения окон по определенным группам. Сначала нужно описать сами группы:
;; Create groups
(defvar group-names "123qwe")
(dotimes (i 6)
(define-key *top-map* (kbd (format nil "s-~a" (char group-names i)))
(format nil "gselect ~a" (1+ i)))
(define-key *top-map* (kbd (format nil "s-C-~a" (char group-names i)))
(format nil "gmove ~a" (1+ i))))
(defmacro make-groups (&rest names)
(let ((ns (mapcar #'(lambda (n) (cat "gnew " n)) names)))
`(run-commands ,@ns)))
(make-groups "2" "3" "q" "w" "e")
(run-commands "gselect 1" "grename 1")
Теперь остается только задать правила расположения окон по группам:
;; Clear rules
(clear-window-placement-rules)
(define-frame-preference "1"
;; frame raise lock (lock AND raise == jumpto)
(0 t t :title "emacs")
(0 t t :class "XTerm"))
(define-frame-preference "2"
;; frame raise lock (lock AND raise == jumpto)
(0 t t :class "Firefox"))
(define-frame-preference "3"
;; frame raise lock (lock AND raise == jumpto)
(0 t t :instance "aumix")
(0 t t :class "MPlayer")
(0 t t :class "Avidemux"))
Можно еще долго перечислять возможности данного оконного менеджера. Но тут я думаю уже остановиться.
Мой файл конфигурации stumpwm можно найти по адресу github.com/Juev/stumpwm-config
И напоследок внешний вид:
