[gnome-settings-daemon] power: Add a watchdog to keep X's builtin screen saver disabled



commit a7ad352ce356db6c72eb462dc320411ca4f68687
Author: Rui Matos <tiagomatos gmail com>
Date:   Thu Oct 18 00:44:54 2012 +0200

    power: Add a watchdog to keep X's builtin screen saver disabled
    
    X's builtin screen saver may activate DPMS. Since we want to activate
    DPMS ourselves according to our own policy we must make sure that X's
    screen saver remains disabled.
    
    This code is a copy of the original found in gs-watcher-x11.c from
    gnome-screensaver which stopped being used in GNOME 3.6.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686339

 plugins/power/gsd-power-manager.c |   83 +++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)
---
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index 0e06495..070cf32 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <sys/wait.h>
 #include <glib/gi18n.h>
+#include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include <libupower-glib/upower.h>
 #include <libnotify/notify.h>
@@ -80,6 +81,8 @@
 /* Keep this in sync with gnome-shell */
 #define SCREENSAVER_FADE_TIME                           10 /* seconds */
 
+#define XSCREENSAVER_WATCHDOG_TIMEOUT                   120 /* seconds */
+
 enum {
         GSD_POWER_IDLETIME_NULL_ID,
         GSD_POWER_IDLETIME_DIM_ID,
@@ -197,6 +200,7 @@ struct GsdPowerManagerPrivate
         GsdPowerIdleMode         current_idle_mode;
         guint                    lid_close_safety_timer_id;
         GtkStatusIcon           *status_icon;
+        guint                    xscreensaver_watchdog_timer_id;
 };
 
 enum {
@@ -3621,6 +3625,77 @@ engine_session_active_changed_cb (GnomeSettingsSession *session,
         idle_set_mode (manager, GSD_POWER_IDLE_MODE_NORMAL);
 }
 
+/* This timer goes off every few minutes, whether the user is idle or not,
+   to try and clean up anything that has gone wrong.
+
+   It calls disable_builtin_screensaver() so that if xset has been used,
+   or some other program (like xlock) has messed with the XSetScreenSaver()
+   settings, they will be set back to sensible values (if a server extension
+   is in use, messing with xlock can cause the screensaver to never get a wakeup
+   event, and could cause monitor power-saving to occur, and all manner of
+   heinousness.)
+
+   This code was originally part of gnome-screensaver, see
+   http://git.gnome.org/browse/gnome-screensaver/tree/src/gs-watcher-x11.c?id=fec00b12ec46c86334cfd36b37771cc4632f0d4d#n530
+ */
+static gboolean
+disable_builtin_screensaver (gpointer unused)
+{
+        int current_server_timeout, current_server_interval;
+        int current_prefer_blank,   current_allow_exp;
+        int desired_server_timeout, desired_server_interval;
+        int desired_prefer_blank,   desired_allow_exp;
+
+        XGetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+                         &current_server_timeout,
+                         &current_server_interval,
+                         &current_prefer_blank,
+                         &current_allow_exp);
+
+        desired_server_timeout  = current_server_timeout;
+        desired_server_interval = current_server_interval;
+        desired_prefer_blank    = current_prefer_blank;
+        desired_allow_exp       = current_allow_exp;
+
+        desired_server_interval = 0;
+
+        /* I suspect (but am not sure) that DontAllowExposures might have
+           something to do with powering off the monitor as well, at least
+           on some systems that don't support XDPMS?  Who know... */
+        desired_allow_exp = AllowExposures;
+
+        /* When we're not using an extension, set the server-side timeout to 0,
+           so that the server never gets involved with screen blanking, and we
+           do it all ourselves.  (However, when we *are* using an extension,
+           we tell the server when to notify us, and rather than blanking the
+           screen, the server will send us an X event telling us to blank.)
+        */
+        desired_server_timeout = 0;
+
+        if (desired_server_timeout     != current_server_timeout
+            || desired_server_interval != current_server_interval
+            || desired_prefer_blank    != current_prefer_blank
+            || desired_allow_exp       != current_allow_exp) {
+
+                g_debug ("disabling server builtin screensaver:"
+                         " (xset s %d %d; xset s %s; xset s %s)",
+                         desired_server_timeout,
+                         desired_server_interval,
+                         (desired_prefer_blank ? "blank" : "noblank"),
+                         (desired_allow_exp ? "expose" : "noexpose"));
+
+                XSetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+                                 desired_server_timeout,
+                                 desired_server_interval,
+                                 desired_prefer_blank,
+                                 desired_allow_exp);
+
+                XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE);
+        }
+
+        return TRUE;
+}
+
 gboolean
 gsd_power_manager_start (GsdPowerManager *manager,
                          GError **error)
@@ -3778,6 +3853,9 @@ gsd_power_manager_start (GsdPowerManager *manager,
         /* set the initial dim time that can adapt for the user */
         refresh_idle_dim_settings (manager);
 
+        manager->priv->xscreensaver_watchdog_timer_id = g_timeout_add_seconds (XSCREENSAVER_WATCHDOG_TIMEOUT,
+                                                                               disable_builtin_screensaver,
+                                                                               NULL);
         gnome_settings_profile_end (NULL);
         return TRUE;
 }
@@ -3829,6 +3907,11 @@ gsd_power_manager_stop (GsdPowerManager *manager)
 
         g_clear_object (&manager->priv->idletime);
         g_clear_object (&manager->priv->status_icon);
+
+        if (manager->priv->xscreensaver_watchdog_timer_id > 0) {
+                g_source_remove (manager->priv->xscreensaver_watchdog_timer_id);
+                manager->priv->xscreensaver_watchdog_timer_id = 0;
+        }
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]