Есть ли достойный способ заблокировать заставки в Linux?
Я ищу достойный, не хромой способ блокировать xscreensaver, kscreensaver или gnome-screensaver, который может работать, желательно в агностической заставке, и это абсолютно необходимо выполнить быстро.
Я читал FAQ xscreensaver (http://www.jwz.org/xscreensaver/faq.html).
У меня есть игровая программа на основе gtk, которая проворачивает 30 кадров в секунду, смешивая несколько каналов аудио, и поскольку она управляется джойстиком, иногда запускается скринсейвер. Я помещаю "кавычки", потому что есть по крайней мере три разных популярных заставки, xscreensaver, gnome-screensaver и kscreensaver, каждый со своими уникальными и klunky методами, с помощью которых приложение может блокировать их.
Кто-нибудь инкапсулировал код, чтобы запретить все это в быстрый фрагмент кода? О, и это должно быть совместимо с GPL.
В настоящее время мой код просто жалобно жалуется на разработчиков, не поддерживающих скринсейвер, если какой-либо скринсейвер обнаружен и джойстик используется, и на самом деле не пытается ничего сделать, кроме как рекомендовать пользователю вручную отключить скринсейвер, так как единственный вещь, которую я могу думать, так невероятно уродлива, что я просто отказываюсь это делать.
Просто интересно, если кто-то еще столкнется с этим, и что они сделали, и если они что-нибудь сделали, если бы это было так же безобразно, как мне кажется, это должно было бы быть, или если там было какое-то изящное решение... Похоже, что, возможно, синтезируя X-события каким-то образом, чтобы обмануть заставку, подумав, что какая-то деятельность может сделать трюк универсальным способом, но я действительно не знаю, как это сделать (и надеемся, что вам не нужно быть root для этого.)
Любые идеи?
Спасибо,
- steve
Хм, к сожалению, по крайней мере на ядре Fedora 8, это не работает.
Заставка xdg script существует и, похоже, предназначена для работы, она просто не работает.
Как только вы выполните "xdg-screensaver suspend window-id", где идентификатор окна получает из программы через
xwindow_id = GDK_WINDOW_XWINDOW (GTK_WIDGET (widget)->window);
Или выполняется ли идентификатор окна через xprop, а xdg-screensaver запускается вручную, создаются два процесса:
[[email protected] wordwarvi]$ ps -efa | grep xdg
scameron 4218 1 0 20:12 pts/2 00:00:00 /bin/sh /usr/bin/xdg-screensaver suspend 0x3a00004
scameron 4223 1 0 20:12 pts/2 00:00:00 /bin/sh /usr/bin/xdg-screensaver suspend 0x3a00004
scameron 4313 3151 0 20:15 pts/1 00:00:00 grep xdg
[[email protected] wordwarvi]$
И они никогда не умирают, даже после программы они якобы ждут штампов, и скринсейвер никогда не будет снова включен.
[[email protected] wordwarvi]$ xdg-screensaver status
disabled
[[email protected] wordwarvi]$ ls -ltr /tmp | grep xdg
-rw------- 1 scameron scameron 15 2009-01-20 20:12 xdg-screensaver-scameron--0.0
[[email protected] wordwarvi]$
Запуск xdg-screensaver resume-id не возобновляет скринсейвер.
Чтобы снова включить скринсейвер, я должен вручную их убить и вручную удалить файлы, которые он оставляет в /tmp:
[[email protected] wordwarvi]$ kill 4218 4223
[[email protected] wordwarvi]$ rm /tmp/xdg-screensaver-scameron--0.0
[[email protected] wordwarvi]$ xdg-screensaver status
enabled
[[email protected] wordwarvi]$
Итак, хорошие намерения, но, похоже, на самом деле не работают.
Нет, конечно, не ожидая запускать каждый кадр, но не хочу, чтобы он вызывал икоту, когда он запускался, - это все. С моей мыслью синтезировать X-события, я думал, что это будет достаточно часто, чтобы заставить экранную заставку думать, что есть активность.
Глядя на xdg-screensaver (который, кажется, представляет собой оболочку script, которая в конечном итоге просто "ждет" моего процесса - круто), похоже, что мне нужно сделать именно то, что я хочу. Я знал, что не могу быть единственным или первым, кто столкнулся с этой проблемой.
Спасибо!
- steve
Ответы
Ответ 1
Нет, но да...
Там нет хорошего чистого способа сделать это. На мой взгляд, должен существовать механизм, управляемый сервером X, который как скринсейверы, так и заинтересованные приложения могут добровольно использовать для согласования подавления любой хранитель экрана во время работы одной или нескольких программ. Но до сих пор не существует такого механизма. GNOME и KDE стремятся реализовать подход DBUS к этой проблеме, но, на мой взгляд, даже если он становится широко распространенным (он еще недостаточно распространен, чтобы полагаться на него в стороннем коде), это не правильный подход.
Однако, xdg-screensaver - это стандартизованная оболочка FreeDesktop script, которую вы можете запускать в качестве подпроцесса для управления заставкой. Он контролирует самые популярные скринсейверы, и поставщик ОС будет отвечать за его обновление/поддержание его работы с новыми заставками или лучшими способами сделать это в будущем. В отличие от многих других kludges, он автоматически перезапустит скринсейвер, если ваше приложение выйдет из строя или выйдет через какой-то маршрут, который забывает вызвать код повторного включения. Подробнее о том, как его использовать, см. на странице руководства.
Как пользователь GTK +, возможно, самые сложные аспекты этого для вас будут создавать подпроцесс для запуска оболочки script (если вы этого еще не сделали, прежде чем вам захочется найти учебник об использовании fork + exec ) и получить XWindow ID главного окна вашего приложения, чтобы предоставить xdg-screensaver.
Вы спрашиваете, что код должен быть "быстрым". Это заставляет меня задаться вопросом, ожидаете ли вы запустить его в каждом кадре - не делайте этого. Решение xdg-screensaver позволяет вам отключить или поменять экранную заставку явно, вместо того, чтобы пытаться ее подавить один раз за кадр или что-то в этом роде.
Ответ 2
Кинопроигрыватели обычно отключают заставки. Вы можете созвать mplayer -code, чтобы узнать, как они это делают.
Для обычного X они используют XScreenSaverSuspend, где поддерживается.
Ответ 3
Это не полностью настольное агностическое решение, но если установлены основные библиотеки Gnome (для них требуются многие приложения на базе GTK), он может работать и на других средах рабочего стола:
Отключить заставку:
gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
(Re) включить заставку:
gsettings set org.gnome.desktop.screensaver idle-activation-enabled true
Ответ 4
Попробуйте следующее: xdg-screensaver suspend [window id]
(см.: http://portland.freedesktop.org/xdg-utils-1.0/xdg-screensaver.html)
a Bash script решение:
activ_win_id=`DISPLAY=:0.${display} xprop -root _NET_ACTIVE_WINDOW`
activ_win_id=${activ_win_id:40:9}
xdg-screensaver suspend $activ_win_id
Он работает для gnome-screensaver.
И там более сложный метод "запрета" DBus: https://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html#gs-method-Inhibit
dbus-send --session \
--dest=org.gnome.ScreenSaver \
--type=method_call \
--print-reply \
--reply-timeout=20000 \
/org/gnome/ScreenSaver \
org.gnome.ScreenSaver.Inhibit \
[application name e.g. ""] \
[reason e.g."playing a game"] \
[non-zero-random-integer e.g. 123]
Ответ 5
Текущий способ (под Gnome 3.22 и, возможно, другие, такие как KDE), похоже, таков, что возвращает файл cookie uninhibition как uint32
:
dbus-send --session \
--dest=org.freedesktop.ScreenSaver \
--type=method_call \
--print-reply \
--reply-timeout=20000 \
/org/freedesktop/ScreenSaver \
org.freedesktop.ScreenSaver.Inhibit \
string:program string:reason
Затем, чтобы отключить торможение:
dbus-send --session \
--dest=org.freedesktop.ScreenSaver \
--type=method_call \
--print-reply \
--reply-timeout=20000 \
/org/freedesktop/ScreenSaver \
org.freedesktop.ScreenSaver.UnInhibit \
uint32:<inhibit-cookie>
Вот small script, который отключает скринсейвер для данной программы, а затем восстанавливает его при выходе.
(D-Feet особенно полезен для интроспекции постоянно меняющихся имен метода D-Bus)