2009-01-20 7 views
10

Ich bin auf der Suche nach einer anständigen, nicht lahmen Art zu hemmen xscreensaver, kscreensaver oder gnome-Bildschirmschoner, die möglicherweise läuft, vorzugsweise in einem Bildschirmschoner-Agnostic Weise, und es muss absolut schnell ausführen.Gibt es eine vernünftige Möglichkeit, Bildschirmschoner in Linux zu hemmen?

Ich habe die Xscreensaver FAQ (http://www.jwz.org/xscreensaver/faq.html) gelesen.

Ich habe ein gtk-basiertes Spielprogramm, das 30 Frames/Sekunde ausgibt, während man mehrere Audiokanäle mischt, und da es mit einem Joystick gesteuert wird, kommt manchmal "der" Bildschirmschoner ins Spiel. weil es mindestens drei verschiedene populäre Bildschirmschoner gibt, xscreensaver, gnome-screensaver und kscreensaver, jede mit ihren eigenen einzigartigen und klunker Methoden, durch die eine Anwendung sie möglicherweise hemmt.

Hat jemand den Code eingekapselt, um alle diese in einem schnellen Stück Code zu sperren? Oh, und es muss GPL-kompatibel sein.

Gegenwärtig jammert mein Code peinlich über die nicht kooperierenden Bildschirmschoner-Entwickler, wenn irgendein Bildschirmschoner entdeckt wird und der Joystick in Gebrauch ist, und nicht wirklich versucht, irgendetwas anderes als den Benutzer zu beraten, den Bildschirmschoner manuell zu deaktivieren, als der einzige Eine andere Sache, die ich denken kann, ist so unglaublich hässlich, dass ich es einfach ablehne.

Ich frage mich nur, ob jemand anderes in das hineingeraten ist, und was sie getan haben und ob sie etwas getan haben, ob es so hässlich war, wie es mir scheint, oder ob es eine elegante Lösung gibt Es scheint so, als könnte man X-Ereignisse irgendwie synthetisieren, um den Bildschirmschoner zu denken, dass es eine Aktivität gibt, die den Trick auf eine universelle Weise tun könnte, aber ich bin mir wirklich nicht sicher, wie ich das machen soll (und hoffe, dass du es nicht sein musst) Wurzel, um es zu tun.)

Irgendwelche Ideen?

Danke,

- steve


Hmm, unfortuanately, zumindest auf Fedora Core 8, dies nicht zu funktionieren scheinen.

Das xdg-Bildschirmschoner-Skript ist da und scheint zu funktionieren, es funktioniert einfach nicht wirklich.

Sobald Sie das tun „xdg-Bildschirmfenster-ID suspendieren“, wo Fenster-ID aus dem Programm heraus über

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

Oder ob der Fenster-ID über xprop wird bekommen bekommen wird, und xdg-Bildschirmschoner laufen manuell werden zwei Prozesse erstellt:

 
[[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]$ 

und sie sterben nie, auch nach dem Programm, das sie für Gesenke angeblich darauf warten, und der Bildschirmschoner nie wieder aktiviert wird.

 
[[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]$ 

Lauf xdg-Bildschirmschoner Lebenslauf Fenster-ID wird nicht fortgesetzt, um den Bildschirmschoner.

Um den Bildschirmschoner wieder zu aktivieren, muss ich sie manuell töten, und entfernen Sie die Dateien manuell in/tmp Blätter um:

 
[[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]$ 

Also, gute Absichten, aber scheint nicht wirklich zu arbeiten .


Nein, natürlich nicht erwartet, dass es für jeden Rahmen laufen, aber nicht will, dass es Schluckauf verursachen, wenn es ausgeführt wird, ist alles. Mit meinem Gedanken, X-Ereignisse zu synthetisieren, stellte ich mir vor, dass es nur oft genug sein würde, um den Bildschirmschoner zu denken, dass es Aktivität gab.

Mit Blick auf xdg-Bildschirmschoner (das scheint ein Shell-Skript zu sein, das letztlich nur ein "warten" für meinen Prozess - cool) scheint es gemacht zu machen genau das, was ich will. Ich wusste, dass ich nicht der einzige oder der erste sein könnte, der sich diesem Problem stellt.

Danke!

- steve

Antwort

2

Movie-Player deaktivieren normalerweise Bildschirmschoner. Sie könnten um den mplayer-Code herumstöbern, um zu sehen, wie sie es tun.

Für reguläres X verwenden sie XScreenSaverSuspend wo unterstützt. Keine

8

, aber ja ...

Es gibt keine schöne saubere Art und Weise, dies zu tun. Meiner Meinung nach sollte es einen vom X-Server verwalteten Mechanismus geben, den sowohl Bildschirmschoner als auch interessierte Anwendungen freiwillig nutzen können, um die Unterdrückung eines beliebigen Bildschirmschoners während der Laufzeit eines oder mehrerer Programme auszuhandeln. Aber ein solcher Mechanismus existiert meines Wissens noch nicht. GNOME und KDE versuchen, einen DBUS-Ansatz für dieses Problem zu implementieren, aber meiner Meinung nach ist es nicht der richtige Ansatz, selbst wenn es weit verbreitet wird (es ist noch nicht weit genug verbreitet, um sich darauf im 3rd-Party-Code zu stützen).

Allerdings ist xdg-screensaver ein FreeDesktop standardisiertes Shell-Skript, das Sie als Unterprozess zur Steuerung des Bildschirmschoners ausführen können. Es steuert die meisten populären Bildschirmschoner, und der OS-Hersteller wäre dafür verantwortlich, es zu aktualisieren/aufrechtzuerhalten, damit es mit neueren Bildschirmschonern oder besseren Möglichkeiten arbeitet, dies in der Zukunft zu tun. Im Gegensatz zu vielen anderen Kludges wird es den Bildschirmschoner automatisch wieder aktivieren, wenn Ihre Anwendung abstürzt oder über eine Route endet, die vergisst, den Re-Enable-Code aufzurufen. Einzelheiten zur Verwendung finden Sie auf der Handbuchseite.

Als der wahrscheinlich schwierigste Aspekt für einen GTK + -Benutzer wäre die Erstellung des Unterprozesses zur Ausführung des Shell-Skripts (falls Sie dies noch nicht getan haben, sollten Sie ein Tutorial zur Verwendung von fork + exec finden) und die XWindow ID des Hauptfensters Ihrer Anwendung an xdg-screensaver übergeben.

Sie bitten, dass der Code "schnell" sein sollte. Das lässt mich fragen, ob Sie erwarten, dass es jeden Frame ausführen wird - nicht. Die xdg-screensaver-Lösung ermöglicht es Ihnen, den Bildschirmschoner explizit zu deaktivieren oder neu zu aktivieren, anstatt zu versuchen, ihn einmal pro Bild oder ähnlichem zu unterdrücken.

+0

xdg-Bildschirmschoner (Stand xdg-utils Version 1.1.0) nicht den laufenden Screensaver-Programm erkennen: Es enthält eine Funktion detectDE(), die nach mehreren gängigen Desktop-Umgebungen sucht. Beispiel: Wenn Sie KDE als Desktop-Umgebung ausführen, geht xdg-screensaver fälschlicherweise davon aus, dass Sie auch den Standard-Bildschirmschoner von KDE ausführen. Wenn Sie Ihren Desktop angepasst haben und entschieden haben, stattdessen Jamie Zawinskis xscreensaver zu verwenden, ist diese Annahme falsch und xdg-screensaver wird nicht wie angekündigt funktionieren. IMHO ist das ein Fehler. – pefu

+1

Ich habe gerade festgestellt, dass durch die Aktualisierung von xdg-utils auf Version 1.1.1 der Fehler behoben wurde, den ich in meinem Kommentar erwähnt habe. – pefu

2

Es ist nicht eine völlig Desktop-unabhängige Lösung, aber wenn Kern Gnome-Bibliotheken installiert sind (viele GTK-basierten Anwendungen benötigen sie) es auch auf andere Desktop-Umgebungen funktionieren könnte:

deaktivieren Bildschirmschoner:

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

(Re) ermöglichen Bildschirmschoner:

gsettings set org.gnome.desktop.screensaver idle-activation-enabled true 
1

Try this: xdg-screensaver suspend [window id]

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

eine Lösung Bash-Skript:

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 

Es gnome-screensaver funktioniert für.

Und es gibt die kompliziertere DBus „Sperre“ Methode: 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] 
0

Die aktuelle Art und Weise (unter Gnome 3.22 und möglicherweise andere, wie KDE) zu sein scheinen, die einen uninhibition Cookie als uint32 zurück :

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 

, dann ist die Hemmung zu deaktivieren:

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> 

Hier ist eine small script, die den Bildschirmschoner für ein bestimmtes Programm deaktiviert und später beim Beenden wieder herstellt.

(D-Feet war besonders hilfreich, um die sich ständig ändernden D-Bus Methodennamen für introspecting)