Управление прозрачностью неактивных окон в Xmonad

Преимущества тайлового оконного менеджера, коим является Xmonad, могут обернуться недостатками, а точнее, одним недостатком, который весьма меня раздражал. Если открыто , например, несколько консолей, то очень тяжело определить, в какой из них находится фокус. За счет того, что рамка окна очень тонкая, она очень хорошо маскируется краями экрана, да и не всегда бросается в глаза.

Но сегодня в недрах XMonadContrib’а натолкнулся на модуль  XMonad.Hooks.FadeInactive, который, согласно документации, изменяет у неактивных окон значение атома  _NET_WM_WINDOW_OPACITY, а проще говоря, делает неактивные окна полупрозрачными в степени, задаваемой пользователем.

Однако для этого нужно, чтобы в Xorg’е было включено расширение Composite. Проверить это можно, запустив в консоли следующую команду:

loquens@home:~$ xdpyinfo | grep -q Composite && echo ok
ok

Если увидели «ok», значит все хорошо. Если нет, то необходимо изменить настройки X-сервера в зависимости от используемой видеокарты. Инструкция есть, например,  здесь.

Чтобы изменение прозрачности выражалось не только в именении какого-то непонятного параметра, но и визуально, необходимо, чтобы была запущена программа xcompmgr.

В Debian, которым я пользуюсь, она устанавливаетя из одноименного пакета:

loquens@home:~$ sudo apt-get install xcompmgr

Далее запускаем ее в фоне:

loquens@home:~$ xcompmgr -c &

Параметр «-c» включает Composite на стороне клиента с поддержкой мягких теней и полупрозрачности. Для того, чтобы xcompmgr стартовал каждый раз при логине, я добавил его в файл ~/.xsession, посредством которого у меня запускается и сам Xmonad, и куча других приложений.

После этого осталось слегка именить конфиг Xmonad’а согласно документации на XMonad.Hooks.FadeInactive:

Добавим в начало файла, к директивам импорта следующие строки:

import XMonad
import XMonad.Hooks.FadeInactive

Далее, модифицируем поле logHook конфига Xmonad’а по умолчанию, а также уберем границы окна (мне так больше нравится):

main = do
    ...
    xmonad $ defaultConfig
        { manageHook = myManageHook
        , borderWidth = 0
        , logHook = fadeInactiveLogHook 0.8
        ...
        }

Но у меня logHook уже использовался для обновления панели dzen’a, поэтому пришлось несколько усложнить конструкцию:

        , logHook = do
            dynamicLogWithPP $ myDzenPP xmproc
            fadeInactiveLogHook 0.8

Параметр хука fadeInactiveLogHook  (у меня он равен 0.8) указывает степень непрозрачности неактивного окна (1 — непрозрачное окно, 0 — полностью прозрачное).

Сохраняем конфигурационный файл, перезапускаем xmonad (Mod-q)  и все работает! 🙂

  • (в стандартном xmonad.hs от 0.9 xmonad понадобилось также закомментировать ненужный myLogHook)

  • loquens

    @bakava
    Если хук один, то можно было не комментировать, а добавить fadeInactiveLogHook туда (в документации на этот хук как раз такой пример приводится). На мой взгляд, это более правильный способ, но я так не стал делать, так как не хватило знаний вынести наружу dynamicLogWithPP $ myDzenPP xmproc.

  • Спасибо огромное, даже у такого тугово и ленивого на .hs пользователя xmonad, как я, всё получилось без проблем)

    Теперь бы ещё как в Компизе сделать разную степень прозрачности и анимацию последней. Ну это уже видимо не для меня сейчас)

    Ещё раз Спасибо)

    • Аноним

      Я сам в хаскеле не очень силен ). С компизом посоветовать ничего не могу, т.к. у меня его нет. А с тенями — это, похоже, особенность реализации.

      • Ну и так хорошо. И от рамки полноэкранной в mplayer’е не надо заковыристыми способами избавляться.

  • И ещё
    xcompmgr как-то странно работает, тени залезают на соседние окна(

  • Ларчик просто открывался. К примеру xcompmgr -c -I 12 -F

    добавляет довольнатаки красивый плавный переход между окнами. А веть всё в man’е написано ^^