Есть ли достойный способ заблокировать заставки в 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)