From b47e4019a12ac84fba31e1c631d878ce03fa3808 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 17 Oct 2012 22:44:54 +0000 Subject: 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 --- 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 #include #include +#include #include #include #include @@ -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 ()), + ¤t_server_timeout, + ¤t_server_interval, + ¤t_prefer_blank, + ¤t_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 -- cgit v0.9.0.2