FVWM
FVWM (также F(?)VWM, значение буквы F утеряно) - второй в истории оконный менеджер для иксов (первым был twm), до сих пор актуальный и поддерживаемый (хоть и не так активно, но в официальном списке рассылок проскакивают новые патчи), насчитывающий свыше 250 000 строчек исходного кода.
FVWM
Обладает большим набором функций, и, если так будет понятнее, FVWM -- это как конструктор или фреймворк, в котором уже реализованы все необходимые возможности современных оконных менеджеров, а вам лишь остается написать конфигурационный файл для своих задач. FVWM позволяет создавать внешний вид (декорации) для каждого окна в отдельности, или отключить декорации совсем, задавать поведение каждого окна в отдельности и так далее... Помимо настраиваемых окон, из коробки имеет 4 294 967 295 виртуальных рабочих столов, столь же настраиваемое меню и возможность выполнять скрипты (на любом языке)... И, к примеру, для настройки того же поведения окон, с помощью своих скриптов можно реализовать тайлинг в FVWM. FVWM дает вам полную свободу действий, и вы можете сделать свой оконный менеджер, с нескучными декорациями и панелями, совсем не похожий на другие. FVWM -- полноценный оконный менеджер, в котором реализованы все существующие стандарты (EWMH, ICCCM-2 и GNOME Hints). С FVWM возможен любой "высший пилотаж" в управлении окружением.
Для кого предназначен FVWM? Если вы не ленитесь узнать что-то новое, готовы потратить время на чтение документации, чтобы однажды, но навсегда настроить что-либо для себя, и чтобы затем это просто стабильно работало -- FVWM для вас. Потратить день на изучение, чтобы потом за 5 минут "долететь". Собственно, не ради ли этого вы используете Linux? Либо, даже если вам просто нужен полноценный оконный менеджер, следующий стандартам.
Кому FVWM противопоказан? Если вы любите нескучные 3D эффекты и пошлый глянец (хотя и это настраиваемо, опять же), или предпочитаете, чтобы за вас уже подумали другие, и предоставили рабочее решение "под ключ", или вам жаль потратить пару вечеров на чтение документации и настройку софта. Вам надоел "линукс ради линукса", и надоело всё вечно настраивать и допиливать -- FVWM не для вас.
Установка и запуск
FVWM (пакет fvwm) доступен в официальных репозиториях множества дистрибутивов, в некоторых может быть установлен уже даже из коробки. Если нет, можно скачать с официального сайта и, распаковав архив с исходниками, собрать их самостоятельно.
user@linux:~$ wget ftp://ftp.fvwm.org/pub/fvwm/version-2/fvwm-2.6.5.tar.bz2 user@linux:~$ tar xf fvwm-2.6.5.tar.bz2 user@linux:~$ cd fvwm-2.6.5 user@linux:~$ ./configure && make user@linux:~$ su -c "make install"
После чего запустить еще одни иксы по соседству, но уже с FVWM.
xinit fvwm -- :1
Для запуска FVWM как оконного менеджера по умолчанию вам уже необходимо подправить ваш ~/.xinitrc или какой другой Экранный менеджер, но в этом вы и сами разберетесь, раз уж осилили взяться за изучение FVWM и собрали его...
Конфигурационный файл расположен в файле ~/.fvwm/config, но по умолчанию сам он не создается, поэтому:
user@linux:~$ mkdir .fvwm user@linux:~$ touch .fvwm/config
Первое впечатление
Вы получаете чистый экран с малофункциональной менюшкой по клику в любом месте на рабочем столе. С нуля, если вы не используете Debian и стандартный эмулятор терминала xterm -- вы вообще вряд ли чего сможете запустить в fvwm. Чтобы такого не произошло, запишем первую строку в конфигурационный файл, чтобы по нажатию определенных клавиш запускался терминал, откуда затем мы уже сможем запустить что угодно.
Добавим в ~/.fvwm/config:
Key Return A CM Exec urxvt
В данном случае: (Key) по нажатию клавиши (Return) Enter (A) в любом контексте, будь то рабочий стол или активное окно (CM) с зажатыми клавишами Ctrl и Meta (Alt) следует запустить программу (urxvt).
То есть, перезапускаем FVWM с одной такой строкой в конфиге, и теперь по нажатию Ctrl + Alt + Enter мы запустим нужный нам эмулятор терминала.
Глядя на декорации окон, кто-то пустит скупую слезу по былым временам и предастся ностальгии, а кто-то в ужасе закроет FVWM и больше никогда его не запустит. На время нашего первого знакомства с FVWM предлагаю отключить декорации окон совсем, чтобы они вас не отвлекали.
Добавим в ~/.fvwm/config:
Style * !Title, !Handles, !Borders
В данном случае: (Style) командой по управлению внешним видом и поведением (*) всем окнам (!) отключим (Title) заголовок, (Handles) элементы управления по бокам окна (Borders) и однопиксельную рамку.
Получилось минималистично, но хотя бы не так ужасно. И просто для того, чтобы данным оконным менеджером можно было пользоваться, соберем минимально необходимую, но удобную для того конфигурацию.
Добавим в ~/.fvwm/config:
DesktopSize 3x1 EdgeThickness 0 OpaqueMoveSize 0 MoveThreshold 0 DestroyFunc FuncFvwmRaiseLowerX AddToFunc FuncFvwmRaiseLowerX + I Raise + M $0 + D Lower Key Return A CM Exec urxvt Key Delete W CM Close Key Insert W CM RaiseLower Key BackSpace A CM Restart Key 1 A CM GotoPage 0 0 Key 2 A CM GotoPage 1 0 Key 3 A CM GotoPage 2 0 Key x W CM Maximize Mouse 1 R A Menu MenuFvwmWindowOps Mouse 2 R A WindowList NoDeskSort Mouse 3 R A Menu MenuFvwmRoot Mouse 1 T A FuncFvwmRaiseLowerX "Move" Mouse 1 FS A FuncFvwmRaiseLowerX "Resize" Mouse 1 W M FuncFvwmRaiseLowerX "Move" Mouse 2 W M Lower Mouse 2 FST A Lower Mouse 3 WFS M FuncFvwmRaiseLowerX "Resize" Style * !Title, !Handles, !Borders Style URxvt PositionPlacement UnderMouse
Горячие клавиши:
- Ctrl + Alt + Enter -- запустит терминал urxvt (измените название терминала, если необходимо);
- Ctrl + Alt + Delete -- закроет активное окно;
- Ctrl + Alt + Insert -- переключает фокус между окнами и выводит следующее окно на передний план;
- Ctrl + Alt + BackSpace -- перезапустит FVWM (необходимо при редактировании конфигурационного файла);
- Ctrl + Alt + X -- развернет окно на весь экран, при повторном нажатии восстановит его обратно;
- Ctrl + Alt + 1, 2, 3 -- переключает рабочие столы (1, 2, или 3 соответственно);
- (Shift +) Alt + Tab -- встроенные клавиши для переключения между окнами.
В случае, если вы решили не отключать декорации окон -- мышкой вы можете управлять окнами, таская их за декорации, иначе, зажав клавишу Meta (Alt), левой кнопкой мышки вы перемещаете окно, средней (колесиком, либо двойным кликом левой) переключаете фокус между окнами, а правой изменяете размер окна.
И таким образом, на первых порах, мы получили классический оконный менеджер, который предоставляет весь необходимый минимум в управлении окнами.
Правила оформления кода
При оформлении конфигурационного файла вовсе не обязательно следовать данным правилам, но так уже сложилось...
- Названия функций следует начинать с FuncFvwm. Например, FuncFvwmMaximize, если вы желаете переопределить функцию Maximize, и затем поменять везде название данной функции на вызов вашей новой FuncFvwmMaximize. Исключение составляют стандартные встроенные функции -- как раз потому, что они встроенные, и чтобы ваши функции с ними не пересекались, добавляйте вышеуказанный префикс.
- Названия меню следует начинать с MenuFvwm. MenuFvwmRoot -- самое главное (корневое) меню, которое вызывается в FVWM по клику на рабочем столе, MenuFvwmWindowOps -- меню со списком действий над окнами, StartMenu используется в модуле FvwmTaskBar для вызова меню кнопки "Пуск". Так или иначе, названия меню не критичны, ведь вы сами определяете, какие и где меню вам вызывать.
Особенности поведения
У каждого оконного менеджера имеются свои особенности поведения (как задумали их авторы), и в большинстве они вшиты в исходный код. Меняя оконные менеджеры, вам приходится привыкать к новому поведению окон и прочим мелочам, которые могут казаться непривычными или даже раздражать, но в FVWM все настраиваемо. FVWM не стал исключением и по умолчанию имеет свой ряд особенностей.
Инициализация
Имеется ряд встроенных функций для последующего автовыполнения команд, таких, как InitFunction, SessionInitFunction, StartFunction, SessionStartFunction, RestartFunction, SessionRestartFunction и ExitFunction.
Однако двух функций с последующей проверкой условий вполне достаточно.
DestroyFunc StartFunction AddToFunc StartFunction + I Test (Init) PipeRead 'test -d "/tmp/fvwm-$[UID]" || mkdir "/tmp/fvwm-$[UID]"; echo Nop' + I Test (Init) PipeRead 'xsetroot -solid "#400040"; echo Nop' DestroyFunc ExitFunction AddToFunc ExitFunction + I Test (Quit) PipeRead 'rm --force --recursive "/tmp/fvwm-$[UID]"; echo Nop'
Здесь командой Test мы проверяем, что сейчас конкретно происходит, и при запуске, в зависимости от выполненного условия, создадим временную директорию для FVWM (необязательно, просто она нам еще пригодится), установим обои (фон) на рабочий стол. При закрытии FVWM удалим временную директорию со всем содержимым.
Alt + Tab, Alt + Shift + Tab
Как и во многих других оконных менеджерах, данные горячие клавиши переключают окна, по умолчанию вызывая меню со списком окон. Не всех может устраивать такое поведение, поэтому для "тихого" переключения между окнами предлагаю переопределить их на свои функции.
DestroyFunc FuncFvwmNextWindow AddToFunc FuncFvwmNextWindow + I Next (CurrentPage, !Iconic, AcceptsFocus) FlipFocus NoWarp + I Current Raise DestroyFunc FuncFvwmPrevWindow AddToFunc FuncFvwmPrevWindow + I Prev (CurrentPage, !Iconic, AcceptsFocus) Focus NoWarp + I Current Raise Key Tab A M FuncFvwmNextWindow Key Tab A SM FuncFvwmPrevWindow
Таким образом, курсор мышки не будет скакать от окна к окну, а фокус между окнами переключается без всяких меню.
Автофокус окна
Представим, что вы используете все виртуальные рабочие столы в количестве 4 294 967 295 штук, на каждом из которых крутятся какие-то приложения, и вот одно из них "позвало вас к себе" -- когда, например, вас хайлайтнули (обратились к вашему нику) в чате. Среди такого зоопарка окон трудно найти нужное, а если это был просто "бип" спикером? Сиди, гадай, что за окно может бибикать и по какой причине.
В FVWM было решено мгновенно переключаться на такое окно, и это удобно, но может раздражать, если вы в это время писали код, а какое-то надоедливое окно вас отвлекает автофокусом на него.
Так вот, когда такое окно "звенит", вызывается встроенная функция UrgencyFunc, и когда оно перестает "звенеть", вызывается UrgencyDoneFunc. По умолчанию функции выглядят следующим образом:
AddToFunc UrgencyFunc + I Iconify off + I FlipFocus NoWarp + I Raise AddToFunc UrgencyDoneFunc + I Nop
И понятное дело, вы можете их переопределить. К примеру, наделать всплывающих уведомлений где-либо с наименованием окна, которое вас "позвало"... Все же удобнее и проще будет просто их удалить, и более "хайлайт в чатах" вас не будет отвлекать (в прямом смысле).
DestroyFunc UrgencyFunc DestroyFunc UrgencyDoneFunc
Еще один момент, когда, помимо звенящих окон, стандарт EWMH требует активации окна, и схож он с предыдущей функцией, но называется EWMHActivateWindowFunc:
AddToFunc EWMHActivateWindowFunc + I Iconify off + I Focus NoWarp + I Raise
Ее мы также удаляем, если вам совсем-совсем не хочется отвлекаться на требующие к себе внимания окна.
DestroyFunc EWMHActivateWindowFunc
Меню
Есть два вида меню -- обычное (скажем, для запуска программ или выполнения каких-то действий) по умолчанию называется MenuFvwmRoot, и меню со списком всех окон, которое вызывается функцией WindowList.
Если по заголовку меню кликнуть средней кнопкой мыши (колесиком), то меню превратится в обычное окно fvwm_menu, и для него также можно установить отдельные стили:
Style fvwm_menu Title, Handles, Borders Style fvwm_menu UsePPosition
WindowList
WindowList вызывается по клику мышкой на рабочем столе, либо встроенными горячими клавишами Alt + Tab (чтобы переключить следующее окно) и/или Alt + Shift + Tab (для переключения на предыдущее окно).
Когда вы выбираете пункт в этом меню, вызывается функция WindowListFunc, по умолчанию выполняющая следующее:
AddToFunc WindowListFunc + I Iconify off + I FlipFocus NoWarp + I Raise
Можете переопределить ее по своему усмотрению.
Иконки приложений
Обычно графические приложения уже имеют свои иконки, установленные в /usr/share/icons/hicolor, но в большинстве случаев вам придется задавать иконки приложениям вручную, если вы хотите использовать какие-то "темы" иконок.
Для удобства задаем ImagePath, где FVWM будет искать картинки.
ImagePath /usr/share/icons/Tango:+
И теперь к каждому приложению задаем иконки.
Style * Icon "48x48/mimetypes/application-x-executable.png", MiniIcon "22x22/mimetypes/application-x-executable.png" Style URxvt Icon "48x48/apps/utilities-terminal.png", MiniIcon "22x22/apps/utilities-terminal.png" Style Firefox Icon "48x48/apps/internet-web-browser.png", MiniIcon "22x22/apps/internet-web-browser.png", IconOverride, EWMHMiniIconOverride Style MPlayer Icon "48x48/apps/mplayer.png", MiniIcon "22x22/apps/mplayer.png" Style Thunar Icon "48x48/apps/system-file-manager.png", MiniIcon "22x22/apps/system-file-manager.png" Style Leafpad Icon "48x48/apps/accessories-text-editor.png", MiniIcon "22x22/apps/accessories-text-editor.png", IconOverride, EWMHMiniIconOverride Style Deadbeef Icon "48x48/apps/audioplayer.png", MiniIcon "22x22/apps/audioplayer.png", IconOverride, EWMHMiniIconOverride
Обратите внимание, что некоторые графические приложения требуют дополнительные параметры IconOverride и EWMHMiniIconOverride, чтобы установить иконки.
Свернутые окна
Сворачиваемые окна становятся иконками на рабочем столе, по клику на которые разворачиваются обратно в окно. Если вы хотите отключить такие иконки, то тогда установите следующий параметр:
Style * NoIcon
При этом прежде у окон не должны быть заданы какие-либо иконки (Icon, MiniIcon), и теперь свернутые окна не будут видны на рабочем столе, а доступны лишь через какой-либо список окон (всевозможные TaskBar'ы, либо меню WindowList).
Советы и трюки
Выполнить...
Если у вас установлен эмулятор терминала rxvt-unicode (urxvt), то мы можем использовать его отдельно для запуска приложений.
DestroyFunc FuncFvwmRun AddToFunc FuncFvwmRun + I PipeRead 'test -a "/tmp/fvwm-$[UID]/!PS1" || echo "PS1=" > /tmp/fvwm-$[UID]/!PS1; urxvtc -geometry 50x1+30-30 \ -name fvwm_run --keysym.0xFF0D " &\\nexit\\n" -fn "9x15bold" +sb -e bash --init-file "/tmp/fvwm-$[UID]/!PS1"' Key r A CM FuncFvwmRun Style fvwm_run !Title, !Handles, Borders Style fvwm_run !Iconifiable, !Maximizable, FixedPosition, FixedSize Style fvwm_run GrabFocus
По нажатию Ctrl + Alt + R в левом нижнем углу у вас появится urxvt, если что-нибудь ввести и нажать Enter -- оно запустится, а urxvt закроется.
Фокус окна в зависимости от положения курсора
FocusFollowsMouse -- фокус переключается на окно, над которым расположен указатель мыши.
MouseFocusClickRaises -- Click на любой части окна поднимает его наверх.
Style * FocusFollowsMouse, MouseFocusClickRaises
Автоматическое всплытие окна через 1 секунду, при наведении указателя.
Module FvwmAuto 1000 Raise Nop
Alt-tab, unix way
Стандартное переключение окон через список -- это, конечно, удобно, но порой хочется чего-то необычного и юниксового. Пример ниже работает так: сначала показываем предыдущее окно, после -- переключаемся между окнами по кругу. Звучит удобно, не так ли?
InfoStoreAdd DIR Next DestroyFunc FuncSwitchWindow AddToFunc FuncSwitchWindow + I $[infostore.DIR] (CurrentDesk, !Iconic, !Sticky) SelectWindow + I Deschedule 134000 + I PipeRead `[ "$[infostore.DIR]" == "Prev" ] && \ echo 'InfoStoreAdd NDIR Next' || \ echo 'InfoStoreAdd NDIR Prev'` + I Schedule 700 134000 InfoStoreAdd DIR $[infostore.NDIR] DestroyFunc SelectWindow AddToFunc SelectWindow + I Iconify false + I Focus + I Raise + I WarpToWindow 50 50 Key Tab A 4 FuncSwitchWindow
Обратите внимание на строчку "+ I WarpToWindow 50 50" -- она перемещает курсор в центр окна. Если у вас фокус окна выделяется кликом по нему, то строчку можно убрать.
Я не стал портить картину Alt + Tab и прописал сочетание Win + Tab для переключения вышеописанным способом.
Операции над окном (или окнами)
Полноэкранный режим
Может быть удобным при развертывании окна на весь экран отключать его декорации и фиксировать (ни свернуть, ни развернуть, ни поменять размер или положение окна), и тем же методом восстанавливать окно в обычное состояние.
DestroyFunc FuncFvwmMaximize AddToFunc FuncFvwmMaximize + I ThisWindow (Maximized) DestroyWindowStyle + I TestRc (NoMatch) ThisWindow (!Maximized) WindowStyle !Title, !Handles, !Borders + I UpdateStyles + I ThisWindow (Maximized) Maximize + I TestRc (NoMatch) Maximize ewmhiwa 100 100 + I TestRc (NoMatch) WindowStyle !Iconifiable, !Maximizable, FixedPosition, FixedSize + I TestRc (NoMatch) UpdateStyles Key x A CM FuncFvwmMaximize
Делаем это клавишами Ctrl + Alt + X.
Свернуть/развернуть все окна
Свернуть/развернуть все окна
Можно свернуть все окна на рабочем столе, как это сделано в windows.
DestroyFunc FuncSHDesktop AddToFunc FuncSHDesktop + I All (CurrentPage, Iconifiable, !Iconic, !WindowListSkip, !Shaded) Iconify on + I TestRc (Match) Break + I All (CurrentPage, Iconic, !WindowListSkip) Iconify off Key D A 4 FuncSHDesktop Mouse 1 R M FuncSHDesktop
Таким образом, всё, что у вас на текущем экране, будет свернуто в иконки (сочетание Win + D), при повторном нажатии -- развернуто. А сочетание Alt + клик_левой_кнопкой по рабочему столу выполняет ту же функцию.
Свернуть/развернуть все окна, но не разворачивать свернутые ранее
Бывает полезно свернуть то, что у вас открыто, но не разворачивать то, что скрыли до этого. В трюке ниже мы будем использовать параметр State.
DestroyFunc ShowDesktop AddToFunc ShowDesktop + I All (CurrentPage, Iconic, State 31) RestoreDesktop + I TestRc (Match) Break + I All (CurrentPage, !Iconic, !State 31) ThisWindow State 31 True + I All (CurrentPage, !Iconic) Iconify DestroyFunc RestoreDesktop AddToFunc RestoreDesktop + I All (CurrentPage, Iconic, State 31) Iconify off + I All (CurrentPage, State 31) ThisWindow State 31 False Key H A 4 ShowDesktop
Таким образом, всё, что у вас на текущем экране, будет свернуто в иконки (сочетание Win + H), при повторном нажатии -- развернуто, кроме тех окон, что ранее были свернуты.
AutoShade или свернуть в заголовок
Набор функций, реализующих autoshade, подсмотренный в kwin и стащенный у Hoodoo. Окно сворачивается в заголовок. Как только курсор оказывается в заголовке, окно разворачивается. Как только курсор покидает окно, оно снова сворачивается. Используется команда State, позволяющая задать для любого окна один или несколько статусов, которые впоследствии можно проверить, и на основании проверки выполнить ту или иную команду. Модуль FvwmAuto следит за курсором и реагирует, когда тот входит в окно или покидает его. Всего можно задать 32 статуса (0-31). Вообще этот модуль следовало бы поместить в автостарт.
Module FvwmAuto 0 -menter "Silent AutoUnshade" "Silent AutoShade" DestroyFunc ToggleAutoshaded AddToFunc ToggleAutoshaded + I State 0 + I ThisWindow (!State 0) WindowShade false DestroyFunc AutoShade AddToFunc AutoShade + I ThisWindow (State 0) WindowShade True DestroyFunc AutoUnshade AddToFunc AutoUnshade + I ThisWindow (State 0) WindowShade False DestroyFunc FuncWindowShade AddToFunc FuncWindowShade + I ThisWindow WindowShade toggle + I ThisWindow (State 0) State 0 + I ThisWindow WarpToWindow 50 50 Mouse 3 T N ToggleAutoshaded
Функция в данном примере активируется по щелчку средней кнопкой мыши по заголовку окна.
Группировка окон
DestroyFunc AddToGroup AddToFunc AddToGroup + I ThisWindow State $0 DestroyFunc GroupSwitch AddToFunc GroupSwitch + I Next (State $0) SelectWindow DestroyFunc SelectWindow AddToFunc SelectWindow + I Iconify false + I Focus + I Raise + I WarpToWindow 50 50
Key 1 WTSF C4 AddToGroup 1 Key 2 WTSF C4 AddToGroup 2 Key 3 WTSF C4 AddToGroup 3 Key 4 WTSF C4 AddToGroup 4 Key 5 WTSF C4 AddToGroup 5 Key 6 WTSF C4 AddToGroup 6 Key 7 WTSF C4 AddToGroup 7 Key 8 WTSF C4 AddToGroup 8 Key 9 WTSF C4 AddToGroup 9 Key 1 A 4 GroupSwitch 1 Key 2 A 4 GroupSwitch 2 Key 3 A 4 GroupSwitch 3 Key 4 A 4 GroupSwitch 4 Key 5 A 4 GroupSwitch 5 Key 6 A 4 GroupSwitch 6 Key 7 A 4 GroupSwitch 7 Key 8 A 4 GroupSwitch 8 Key 9 A 4 GroupSwitch 9
При нажатии Ctrl + {цифра от 1 до 9} -- окно добавляется в группу, при нажатии Win + {цифра от 1 до 9} можно переключаться между окнами данной группы. Повторное нажатие Ctrl + {цифра от 1 до 9} исключает окно из группы.
Окно поверх других окон
DestroyFunc WinOnTop AddToFunc WinOnTop + I ThisWindow (Layer 6) Layer + I TestRc (NoMatch) Layer 0 6 + I Raise Key T WFST 4 WinOnTop
По сочетанию клавиш Win + T окно будет поднято над другими окнами, по повторному нажатию -- окно примет прежние параметры.
Прижатие окна к углам/сторонам экрана
# Для прижатия окна к углам/сторонам страницы и перемещения в центр нажимаем win+ # +---------+ # ! q w e ! # ! ! # ! a s d ! # ! ! # ! z x c ! # +---------+
DestroyFunc NWWindow AddToFunc NWWindow + I ThisWindow AnimatedMove 0 0 + I WarpToWindow 50 50 DestroyFunc NEWindow AddToFunc NEWindow + I ThisWindow AnimatedMove -0 0 + I WarpToWindow 50 50 DestroyFunc SWWindow AddToFunc SWWindow + I ThisWindow AnimatedMove 0 -0 + I WarpToWindow 50 50 DestroyFunc SEWindow AddToFunc SEWindow + I ThisWindow AnimatedMove -0 -0 + I WarpToWindow 50 50 DestroyFunc CWindow AddToFunc CWindow + I ThisWindow Piperead "echo AnimatedMove $(( $[vp.width]/2-$[w.width]/2 ))p $(( $[vp.height]/2-$[w.height]/2 ))p" + I WarpToWindow 50 50 # Прижатие окна к середине верхней границы страницы DestroyFunc CNWindow AddToFunc CNWindow + I ThisWindow Piperead "echo AnimatedMove $(( $[vp.width]/2-$[w.width]/2 ))p 0" + I WarpToWindow 50 50 # Прижатие окна к середине нижней границы страницы DestroyFunc SCWindow AddToFunc SCWindow + I ThisWindow Piperead "echo AnimatedMove $(( $[vp.width]/2-$[w.width]/2 ))p -0" + I WarpToWindow 50 50 # Прижатие окна к середине левой границы страницы DestroyFunc CWWindow AddToFunc CWWindow + I ThisWindow Piperead "echo AnimatedMove 0 $(( $[vp.height]/2-$[w.height]/2 ))p" + I WarpToWindow 50 50 # Прижатие окна к середине правой границы страницы DestroyFunc CEWindow AddToFunc CEWindow + I ThisWindow Piperead "echo AnimatedMove -0 $(( $[vp.height]/2-$[w.height]/2 ))p" + I WarpToWindow 50 50 Key Q WTSF 4 NWWindow Key W WTSF 4 CNWindow Key E WTSF 4 NEWindow Key A WTSF 4 CWWindow Key S WTSF 4 CWindow Key D WTSF 4 CEWindow Key Z WTSF 4 SWWindow Key C WTSF 4 SEWindow Key X WTSF 4 SCWindow
Вместо AnimatedMove вы можете использовать просто Move. В каждой функции используется "+ I WarpToWindow 50 50", это перемещает указатель мышки в центр окна. Если вам это не нужно -- можно смело убрать.
Миниатюры окон
Миниатюры окон(простой вариант)
По умолчанию окна сворачиваются в небольшие иконки приложений на рабочем столе. С помощью пакетов imagemagick и xorg-xwd возможно сделать так, чтобы предварительно делался скриншот сворачиваемого окна, а затем задавался как иконка.
DestroyFunc FuncFvwmThumbnail AddToFunc FuncFvwmThumbnail + I Raise + I InfostoreAdd Icon-$[w.id] $[w.iconfile] + I PipeRead 'xwd -silent -id $[w.id] | convert -scale 128 -quality 0 xwd:- png:- | composite -gravity SouthEast $[w.iconfile] - /tmp/fvwm-$[UID]/Icon-$[w.id].png && echo WindowStyle Icon "/tmp/fvwm-$[UID]/Icon-$[w.id].png" || echo Nop' DestroyFunc FuncFvwmDeThumbnail AddToFunc FuncFvwmDeThumbnail + I PipeRead 'echo WindowStyle Icon \\$\\[Icon-$[w.id]\\]' + I InfostoreRemove Icon-$[w.id] + I PipeRead 'rm --force "/tmp/fvwm-$[UID]/Icon-$[w.id].png"' DestroyFunc FuncFvwmIconify AddToFunc FuncFvwmIconify + I ThisWindow (!Shaded, Iconifiable, !Iconic) FuncFvwmThumbnail + I ThisWindow (Iconic) FuncFvwmDeThumbnail + I Iconify + I All (CurrentPage, Iconic) PlaceAgain Icon Key z W CM FuncFvwmIconify Mouse 1 I M FuncFvwmRaiseLowerX "Move" Mouse 1 I A FuncFvwmIconify Mouse 2 I M Lower Mouse 3 I A Menu MenuFvwmWindowOps Style * IconFont "Shadow=0 0 BottomRight:StringEncoding=UTF-8:xft:Sans:Medium:Roman:size=8:minspace=False;fixed" Style * IconBox screen w 0 0 -0 -0, IconFill left bottom
По нажатию Ctrl + Alt + Z окно свернется в небольшую миниатюру в левом нижнем углу, а по клику по ней развернется обратно.
Миниатюры окон(расширенный режим)
Мы делаем миниатюру окна и накладываем на неё иконку приложения (если она прописана в стилях). Задействовал параметр State 28, чтобы не давать слишком часто сворачивать окна, иначе иконка стиля замещается миниатюрой окна (в таком случае помогает только DestroyWindowStyle). Сделана соместимость с функцией ShowDesktop (которая использует State 31).
InfoStoreAdd fvwm_icon_size 160 InfoStoreAdd fvwm_tmp "/tmp" DestroyFunc Thumbnail AddToFunc Thumbnail + I ThisWindow (State 28) Break + I State 28 True + I Raise + I InfostoreAdd Icon-$[w.id] $[w.iconfile] + I ThisWindow (!Shaded, Iconifiable, !Iconic) PipeRead "xwd -silent -id $[w.id] | \ convert -scale $[infostore.fvwm_icon_size] -frame 1x1 \ -mattecolor black -quality 0 xwd:- png:$[infostore.fvwm_tmp]/window-$[w.id].png && echo Nop" + I TestRc (Match) Test (f $[w.iconfile], f $[infostore.fvwm_tmp]/window-$[w.id].png) PipeRead \ "composite -gravity SouthEast -geometry +4+6 \ $[w.iconfile] $[infostore.fvwm_tmp]/window-$[w.id].png $[infostore.fvwm_tmp]/window-$[w.id].png || echo Nop" + I TestRc (Match) Test (f $[infostore.fvwm_tmp]/window-$[w.id].png) \ Piperead "echo WindowStyle IconOverride, Icon $[infostore.fvwm_tmp]/window-$[w.id].png || echo Nop" + I Schedule 150 Iconify on + I Schedule 1500 State 28 False DestroyFunc DeThumbnail AddToFunc DeThumbnail + I Exec rm -f $[infostore.fvwm_tmp]/window-$[w.id].png + I PipeRead "echo Test \\(i \\$\\[infostore.Icon-$[w.id]\\]\\) WindowStyle Icon \\$\\[infostore.Icon-$[w.id]\\]" + I TestRc (NoMatch) WindowStyle NoIconOverride, Icon + I Schedule 100 InfostoreRemove Icon-$[w.id] + I ThisWindow (State 31) State 31 False # FvwmEvent DestroyModuleConfig FvwmEvent: * *FvwmEvent: deiconify DeThumbnail Module FvwmEvent Key z W CM Thumbnail
Сворачиваем окно так же, как и в предыдущем варианте, по Ctrl + Alt + z.
Обратите внимание на модуль FvwmEvent, в данном случае все окна, которые будут разворачиваться из иконки, почувствуют на себе эффект DeThumbnail. :)
Прозрачность окна
У вас должен быть запущен композитный менеджер, например xcompmgr.
AddToFunc InitFunction + I Exec exec $(sleep 3 && xcompmgr -cC &> /dev/null)&
В примерах используется программа transset-df, которая, в отличие от transset, считается более стабильной.
Устанавливаем прозрачность для текущего окна
А дальше установим сочетания для управления прозрачностью с помощью transset-df:
Key Prior WTSF 4 Exec exec transset-df --min 0.3 --inc 0.1 -i $[w.id] &> /dev/null Key Next WTSF 4 Exec exec transset-df --min 0.3 --dec 0.1 -i $[w.id] &> /dev/null Key Home WTSF 4 Exec exec transset-df --min 0.3 -i $[w.id] 1 &> /dev/null Key End WTSF 4 Exec exec transset-df --min 0.3 -i $[w.id] 0 &> /dev/null
Минимальная прозрачность задана как 0.3.
Итак, сочетания клавиш:
- Win + PageUp -- уменьшить прозрачность с шагом 0.1;
- Win + PageDown -- увеличить прозрачность с шагом 0.1;
- Win + Home -- сделать окно полностью непрозрачным;
- Win + End -- сделать окно полностью прозрачным(с оговоркой, что полная прозрачность 0.3).
Прозрачное окно при перемещении или изменении размера
Легко реализовать прозрачные окна, когда мы их перемещаем, либо изменяем им размер. Никакой пользы данный эффект не несет, просто рюшечка. :)
OpaqueMoveSize unlimited Style * ResizeOpaque DestroyFunc FuncFvwmRaiseLowerX AddToFunc FuncFvwmRaiseLowerX + I Raise + M PipeRead 'transset-df --min 0.3 -i $[w.id] 0 > /dev/null; echo Nop' + M $0 + M PipeRead 'transset-df --min 0.3 -i $[w.id] 1 > /dev/null; echo Nop' + D Lower Mouse 1 T A FuncFvwmRaiseLowerX "Move" Mouse 1 FS A FuncFvwmRaiseLowerX "Resize" Mouse 1 W M FuncFvwmRaiseLowerX "Move" Mouse 2 W M Lower Mouse 2 FST A Lower Mouse 3 WFS M FuncFvwmRaiseLowerX "Resize"
Перво-наперво мы установили отображение содержимого окон при их перемещении, а также при изменении размера (по умолчанию рисовалась рамка в стиле FVWM). Затем к функции FuncFvwmRaiseLowerX добавили две команды -- одна выполняется до перемещения/ресайза, а вторая после. Теперь попробуйте перемещать окна или изменять их размер -- в этот момент они будут прозрачными!
Прозрачность для окна по событию
К разделу рюшечек. Пусть главное окно имеет прозрачность 1, а все второстепенные 0.92. Тогда:
Module FvwmEvent DestroyModuleConfig FvwmEvent: * *FvwmEvent: add_window SetFocusTrans *FvwmEvent: leave_window SetUnfocusTrans *FvwmEvent: enter_window SetFocusTrans DestroyFunc SetFocusTrans AddToFunc SetFocusTrans + I Exec exec transset-df --inc .5 -x 1 -i $[w.id] DestroyFunc SetUnfocusTrans AddToFunc SetUnfocusTrans + I Exec exec transset-df --dec .5 -m .92 -i $[w.id]
Немного поясню по событиям:
- add_window -- окно создано
- leave_window -- c окна сняли фокус
- enter_window -- окно получило фокус
Управление плеером
Простой способ управления одним из плееров: MPD + mpc, cmus, xmms, audacious и другими.
MPD + mpc
MPD сервер должен быть запущен.
Key XF86AudioNext A A Exec exec $(mpc next &> /dev/null) Key XF86AudioPrev A A Exec exec $(mpc prev &> /dev/null) Key XF86AudioPlay A A Exec exec $(mpc toggle &> /dev/null) Key XF86AudioStop A A Exec exec $(mpc stop &> /dev/null)
cmus
# запуск cmus или проигрывание/пауза Key XF86AudioPlay A N Exec exec sh -c "if ( grep playing ~/np.txt >/dev/null ); then cmus-remote -u; else cmus-remote -p; fi" # следующий трек Key XF86AudioNext A N Exec exec cmus-remote -n # предыдущий трек Key XF86AudioPrev A N Exec exec cmus-remote -r # останов Key XF86AudioStop A N Exec exec cmus-remote -s
xmms
Управление xmms
Key XF86AudioStop A N Exec exec xmms -s Key XF86AudioPlay A N Exec exec xmms -t Key XF86AudioNext A N Exec exec xmms -f Key XF86AudioPrev A N Exec exec xmms -r
audacious
Key XF86AudioPrev A N Exec exec audacious --rew Key XF86AudioStop A N Exec exec audacious --stop Key XF86AudioPlay A N Exec exec audacious --play-pause Key XF86AudioNext A N Exec exec audacious --fwd
Quod Libet
Key XF86AudioPrev A N Exec exec quodlibet --previous Key XF86AudioStop A N Exec exec quodlibet --stop Key XF86AudioPlay A N Exec exec quodlibet --play-pause Key XF86AudioNext A N Exec exec quodlibet --next
banshee
Key XF86AudioPrev A N Exec exec banshee --previous Key XF86AudioStop A N Exec exec banshee --stop Key XF86AudioPlay A N Exec exec banshee --play-pause Key XF86AudioNext A N Exec exec banshee --next
Goggles Music Manager
Key XF86AudioPrev A N Exec exec gmm --previous Key XF86AudioStop A N Exec exec gmm --stop Key XF86AudioPlay A N Exec exec gmm --play-pause Key XF86AudioNext A N Exec exec gmm --next
Rhythmbox
Rhythmbox dbus
Key XF86AudioNext A N Exec exec dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.rhythmbox /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next Key XF86AudioPrev A N Exec exec dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.rhythmbox /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous Key XF86AudioPlay A N Exec exec dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.rhythmbox /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause Key XF86AudioStop A N Exec exec dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.rhythmbox /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Stop
rhythmbox-client
Key XF86AudioNext A N rhythmbox-client --next Key XF86AudioPrev A N rhythmbox-client --previous Key XF86AudioPlay A N rhythmbox-client --play-pause Key XF86AudioStop A N rhythmbox-client --stop
Управление громкостью (amixer)
Ниже пример с PCM:
Key XF86AudioRaiseVolume A N Exec exec amixer sset PCM 2+ Key XF86AudioLowerVolume A N Exec exec amixer sset PCM 2- Key XF86AudioMute A N Exec exec amixer sset PCM toggle
В варианте с PCM может отсутствовать возможность toggle. Ошибок в stdout не выводится, но и не работает переключение mute/unmute.
Или в варианте с Master:
Key XF86AudioRaiseVolume A N Exec exec amixer sset Master 2+ Key XF86AudioLowerVolume A N Exec exec amixer sset Master 2- Key XF86AudioMute A N Exec exec amixer sset Master toggle
Ссылки на сайты, связанные с fvwm
FVWM(англ.) -- основной сайт.
Форум FVWM(англ.) -- основной форум.
zensites guide FVWM(англ.) -- гайд по заточке системы, с некоторыми интересными функциями.
CookBook(англ.) -- рецепты. К сожалению, сайт больше не пополняется. Надеемся, что это временно.
box-look или примеры настройки(англ.) -- давольно ценный сайт, можно посмотреть и скачать темы оформления пользователей.
советы по настройке fvwm -- старые советы, но ещё актуальные.
Описание оконного менеджера FVWM -- описываются модули, анатомия окон и прочее. Увы, всё старо, но не бесполезно.
топик: Строим свой wm (с преферансом и куртизанками) -- убунту-форум. Для многих из современности знакомство с fvwm началось c просмотра этой темы.
Комментарии этой статьи содержат множество полезных идей и каких-либо решений по вопросам FVWM, если вам интересно почитать неформальные обсуждения про FVWM.