Есть ли достойный способ запретить заставки в Linux? - PullRequest
10 голосов
/ 20 января 2009

Я ищу достойный, не отстойный способ запрета xscreensaver, kscreensaver или gnome-screensaver, который может быть запущен, предпочтительно не зависящим от скринсейвера, и он абсолютно положительно должен выполняться fast .

Я прочитал FAQ по xscreensaver (http://www.jwz.org/xscreensaver/faq.html).

У меня есть игровая программа на основе gtk, которая выдает 30 кадров в секунду, смешивая несколько каналов звука, и, поскольку она управляется джойстиком, иногда включается экранная заставка «я». Я помещаю «в» в кавычки, потому что Существует как минимум три разных популярных заставки: xscreensaver, gnome-screensaver и kscreensaver, каждая из которых имеет свои собственные уникальные и клунки методы, с помощью которых приложение может их запретить.

Кто-нибудь инкапсулировал код, чтобы запретить все это в быстрый кусок кода? О, и он должен быть совместим с GPL.

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

Просто интересно, сталкивался ли кто-то еще с этим, и что они сделали, и если они что-то сделали, если бы это было так безобразно, как мне кажется, это должно было бы быть, или было бы какое-то элегантное решение там? ... Похоже, что, возможно, синтезировать X-события так, чтобы обмануть заставку, заставив ее думать, что какая-то деятельность могла бы добиться цели универсальным способом, но я действительно не уверен, как это сделать (и надеюсь, что вам не нужно быть пользователем root). сделать это.)

Есть идеи?

Спасибо

- Стив


Хм, к сожалению, по крайней мере на Fedora Core 8, это не работает.

Сценарий xdg-screensaver уже есть и, кажется, предназначен для работы, он просто не работает.

Как только вы сделаете «xdg-screensaver suspend window-id», где идентификатор окна получается изнутри программы через

xwindow_id = GDK_WINDOW_XWINDOW (GTK_WIDGET (widget)->window);

Или, если идентификатор окна получен через xprop, и xdg-screensaver запускается вручную, создаются два процесса:

[scameron@zuul 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
[scameron@zuul wordwarvi]$ 

И они никогда не умирают, даже после того, как программа, которую они якобы ожидают, умирает, и заставка никогда не включается снова.

[scameron@zuul wordwarvi]$ xdg-screensaver status
disabled
[scameron@zuul wordwarvi]$ ls -ltr /tmp | grep xdg
-rw------- 1 scameron scameron    15 2009-01-20 20:12 xdg-screensaver-scameron--0.0
[scameron@zuul wordwarvi]$ 

Запуск xdg-screensaver. Идентификатор окна возобновления не возобновляет работу заставки.

Чтобы снова включить скринсейвер, я должен вручную убить их и вручную удалить файлы, которые он оставляет в / tmp:

[scameron@zuul wordwarvi]$ kill 4218 4223
[scameron@zuul wordwarvi]$ rm /tmp/xdg-screensaver-scameron--0.0 
[scameron@zuul wordwarvi]$ xdg-screensaver status
enabled
[scameron@zuul wordwarvi]$ 

Итак, благие намерения, но, похоже, на самом деле не работают.


Нет, конечно, не ожидая, что он будет запускаться каждый кадр, но не хочу, чтобы он вызывал икоты, когда он все-таки работает, и все. С моей мыслью о синтезе событий X я подумал, что этого будет достаточно часто, чтобы заставка заставляла думать, что активность есть.

Глядя на xdg-screensaver (который, похоже, является сценарием оболочки, который в конечном итоге просто «ждет» моего процесса - круто), кажется, он сделан именно для того, что я хочу. Я знал, что не могу быть единственным или первым, кто столкнется с этой проблемой.

Спасибо!

- Стив

Ответы [ 5 ]

8 голосов
/ 20 января 2009

Нет, но да ...

Нет хорошего чистого способа сделать это. По моему мнению, должен существовать механизм, управляемый X-сервером, который добровольно могут использовать как хранители экрана, так и заинтересованные приложения для согласования подавления любой хранителя экрана во время выполнения одной или нескольких программ. Но такого механизма пока не существует, насколько мне известно. GNOME и KDE, похоже, реализуют подход DBUS к этой проблеме, но, на мой взгляд, даже если он станет широко распространенным (пока еще недостаточно распространенным, чтобы полагаться на него в стороннем коде), это неправильный подход.

Однако xdg-screensaver - это стандартизированный скрипт оболочки FreeDesktop, который вы можете запускать как подпроцесс для управления заставкой. Он контролирует большинство популярных заставок, и поставщик ОС будет нести ответственность за его обновление / поддержание для работы с новыми заставками или более эффективными способами сделать это в будущем. В отличие от многих других kludges, он автоматически включит экранную заставку, если ваше приложение выйдет из строя или выйдет по какому-либо маршруту, который забудет вызвать код повторного включения. Подробнее о том, как его использовать, см. На странице руководства.

Как пользователь GTK +, возможно, наиболее сложными аспектами этого для вас будет создание подпроцесса для запуска сценария оболочки (если вы этого не сделали раньше, вам захочется найти руководство по использованию fork + exec) и получение идентификатора XWindow главного окна вашего приложения для передачи в xdg-screensaver.

Вы спрашиваете, что код должен быть "быстрым". Это заставляет меня задуматься, ожидаете ли вы запускать его каждый кадр - не надо. Решение xdg-screensaver позволяет вам явно отключить или включить экранную заставку, вместо того, чтобы пытаться подавлять ее один раз за кадр или что-то в этом роде.

2 голосов
/ 21 апреля 2017

Текущий способ (в Gnome 3.22 и, возможно, других, таких как KDE), выглядит следующим образом, который возвращает файл cookie для запрета как 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>

Вот маленький скрипт , который отключает заставку для данной программы, а затем восстанавливает ее при выходе.

( D-Feet особенно полезен для анализа постоянно меняющихся имен методов D-Bus)

2 голосов
/ 25 января 2015

Попробуйте это: xdg-screensaver suspend [window id]

(см .: http://portland.freedesktop.org/xdg-utils-1.0/xdg-screensaver.html)

решение Bash-скрипта:

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

Работает для заставки гнома.

И есть более сложный метод запрета 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]
2 голосов
/ 01 июля 2013

Это не полностью независимое от рабочего стола решение, но если установлены базовые библиотеки Gnome (для них требуется много приложений на основе GTK), оно может работать и в других средах рабочего стола:

Отключить заставку:

gsettings set org.gnome.desktop.screensaver idle-activation-enabled false

(Re) включить заставку:

gsettings set org.gnome.desktop.screensaver idle-activation-enabled true
2 голосов
/ 20 января 2009

Кино-плееры обычно отключают заставки. Вы можете просмотреть код mplayer , чтобы увидеть, как они это делают.

Для обычного X они используют XScreenSaverSuspend , где поддерживается.

...