google web font

среда, 30 июня 2010 г.

блокировка экрана и не только

Когда-то давно я искал в интернетах способ поймать момент, когда я блокирую экран. То есть мне нужно было, чтобы это делал скрипт. Задача такая:
Когда я отхожу от компьютера и блокирую экран, в системе должно меняться состояние некоторых приложений. Когда я возвращаюсь, состояние должно восстанавливаться.
Так, вроде, понятно. Состояние приложений — это раскладка клавиатуры, статус в джаббере, пауза в проигрывателе. Не найдя правильного способа поймать это событие, я написал bash-скрипт, подарив ему убедительное название locker. Этот скрипт я повесил на сочетание клавиш, которое ранее блокировало экран. Внутри скрипта есть команда, которая блокирует экран по d-bus (дёргает dbus-send и qdbus вперемешку), так что внешне ничего не изменилось: нажимаешь Ctrl+Alt+L — экран блокируется. Только дополнительно теперь ещё и музыка останавливается и psi меняет статус на away.
Ок, с этим моментом разобрались. А как обратно? Теперь я захотел, чтобы когда я вернулся, psi возвращалась в статус "online" и музыка начинала играть снова. Вот тут я и узнал много нового и интересного.
Оказывается, на Maemo есть замечательный сервис: dbus-scripts. Эта штука похожа на крон по всем параметрам: в конфигурационном файле описывается событие, при котором должен быть вызван определённый скрипт, синтаксис этого файла чертовски напоминает crontab и работает оно жутко похожим образом. Порадовался я за владельцев MID на Maemo и пошёл клепать велосипед для своей Gentoo. Если быть точнее, аналог я делать, естественно, не стал, а просто решил задачу самым аццким способом, на который мне только хватило моей извращённой фантазии.
Итак, скрипт, который запускается по Ctrl+Alt+L, имитирует стандартный блокировщик экрана из KDE4, запуская его из себя по d-bus. До блокировки скрипт меняет раскладку и выключает музыку, потом дожидается, пока блокировка будет снята и возвращает всё как было. А поскольку дождаться сигнала из d-bus в шелле невозможно, в скрипте втиснута perl-вставка. Можно было сделать на python, но я же хотел как можно более извращённо сделать. Вот, короче, что получилось:
#!/bin/bash
if [ "x$DESKTOP_SESSION" = "xKDE-4" ]; then
        qdbus org.kde.kxkb /kxkb org.kde.KXKB.setLayout string:us
        qdbus org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop
fi
if [ "$(ps ax | grep cuberok| grep -v grep)" ]; then
        ~/Stuff/cuberok-read-only/bin/cuberok --stop
fi
if [ -n "$(pidof mplayer)" -a -p ~/.mplayer/ctl_pipe ]; then
        echo pause > ~/.mplayer/ctl_pipe
fi
if pidof psi; then
        qdbus org.psi-im.Psi /Main org.psi_im.Psi.Main.setStatus away ''
fi
if pidof deadbeef; then
        deadbeef --stop
fi

perl <<EOF
use Net::DBus::Reactor;
\$s=Net::DBus->session()->get_service('org.kde.screensaver')->get_object('/ScreenSaver','org.freedesktop.ScreenSaver');
\$r=Net::DBus::Reactor->main();
\$s->connect_to_signal('ActiveChanged',sub{\$r->shutdown()});
\$s->Lock;
\$r->run();
exit(0);
EOF

qdbus org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop
if pidof cuberok; then
        ~/Stuff/cuberok-read-only/bin/cuberok --play
fi
if [ -n "$(pidof mplayer)" -a -p ~/.mplayer/ctl_pipe ]; then
        echo play > ~/.mplayer/ctl_pipe
fi
if pidof psi; then
        qdbus org.psi-im.Psi /Main org.psi_im.Psi.Main.setStatus online ''
fi
if pidof deadbeef; then
        deadbeef --play
fi
Полагаю, всё понятно без дополнительных разъяснений. Если не понятно — спрашивайте )))
Перл-вставка сделана по образу и подобию примера отсюда.

Комментариев нет:

Отправить комментарий