[Xfce4-commits] [apps/xfce4-screensaver] 01/01: Add DPMS support for the Blank screen saver (bug #15216)

noreply at xfce.org noreply at xfce.org
Sat Aug 3 19:13:24 CEST 2019


This is an automated email from the git hooks/post-receive script.

b   l   u   e   s   a   b   r   e       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository apps/xfce4-screensaver.

commit 05d47e76470b99595725417a671cc55a18f76237
Author: Sean Davis <smd.seandavis at gmail.com>
Date:   Sat Aug 3 13:13:18 2019 -0400

    Add DPMS support for the Blank screen saver (bug #15216)
---
 NEWS                                |  1 +
 src/gs-manager.c                    | 68 +++++++++++++++++++++++++++++++++++--
 src/gs-prefs.c                      | 44 ++++++++++++++++++++++++
 src/gs-prefs.h                      | 19 +++++++++++
 src/xfce4-screensaver-configure     | 49 +++++++++++++++++++++++---
 src/xfce4-screensaver-preferences.c |  6 +++-
 6 files changed, 178 insertions(+), 9 deletions(-)

diff --git a/NEWS b/NEWS
index 1885689..3cd8be8 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
 ============
 - Features:
   - Optional screensaver inhibition for fullscreen apps
+  - Blank screensaver now supports DPMS (Xfce #15216)
 - Build Changes:
   - Add dependency on libwnck >= 3.20
 
diff --git a/src/gs-manager.c b/src/gs-manager.c
index 32533c2..6c42b78 100644
--- a/src/gs-manager.c
+++ b/src/gs-manager.c
@@ -36,9 +36,14 @@
 #include "gs-prefs.h"
 #include "gs-window.h"
 
-static void gs_manager_class_init (GSManagerClass *klass);
-static void gs_manager_init       (GSManager      *manager);
-static void gs_manager_finalize   (GObject        *object);
+static void     gs_manager_class_init (GSManagerClass *klass);
+static void     gs_manager_init       (GSManager      *manager);
+static void     gs_manager_finalize   (GObject        *object);
+
+static gboolean activate_dpms_timeout (GSManager      *manager);
+static void     remove_dpms_timer     (GSManager      *manager);
+static void     add_dpms_timer        (GSManager      *manager,
+                                       glong           timeout);
 
 struct GSManagerPrivate {
     GSList         *windows;
@@ -57,6 +62,7 @@ struct GSManagerPrivate {
 
     guint           lock_timeout_id;
     guint           cycle_timeout_id;
+    guint           dpms_timeout_id;
 
     GSGrab         *grab;
     guint           deepsleep_idle_id;
@@ -511,10 +517,58 @@ gs_manager_init (GSManager *manager) {
     add_deepsleep_idle(manager);
 }
 
+static gboolean
+activate_dpms_timeout (GSManager *manager) {
+    BOOL state;
+    CARD16 power_level;
+
+    if (DPMSInfo(gdk_x11_get_default_xdisplay(), &power_level, &state)) {
+        if (state) {
+            if (power_level == DPMSModeOn) {
+                gs_debug("DPMS: On -> Standby");
+                DPMSForceLevel (gdk_x11_get_default_xdisplay(), DPMSModeStandby);
+                remove_dpms_timer (manager);
+                add_dpms_timer (manager, manager->priv->prefs->dpms_off_timeout);
+                return FALSE;
+            } else if (power_level == DPMSModeStandby || power_level == DPMSModeSuspend) {
+                gs_debug("DPMS: %s -> Off", power_level == DPMSModeStandby ? "Standby" : "Suspend");
+                DPMSForceLevel (gdk_x11_get_default_xdisplay(), DPMSModeOff);
+            }
+        }
+    }
+
+    manager->priv->dpms_timeout_id = 0;
+    return FALSE;
+}
+
+static void
+remove_dpms_timer (GSManager *manager) {
+    if (manager->priv->dpms_timeout_id != 0) {
+        g_source_remove (manager->priv->dpms_timeout_id);
+        manager->priv->dpms_timeout_id = 0;
+    }
+}
+
+static void
+add_dpms_timer (GSManager *manager,
+                glong      timeout) {
+    if (manager->priv->prefs->mode != GS_MODE_BLANK_ONLY)
+        return;
+
+    if (timeout == 0)
+        return;
+
+    gs_debug ("Scheduling DPMS change after screensaver is idling for %i minute", timeout);
+    manager->priv->dpms_timeout_id = g_timeout_add (timeout * 60000,
+                                                    (GSourceFunc)activate_dpms_timeout,
+                                                    manager);
+}
+
 static void
 remove_timers (GSManager *manager) {
     remove_lock_timer (manager);
     remove_cycle_timer (manager);
+    remove_dpms_timer (manager);
 }
 
 static gboolean
@@ -710,6 +764,9 @@ manager_show_window (GSManager *manager,
         add_cycle_timer (manager, manager->priv->prefs->cycle);
     }
 
+    remove_dpms_timer (manager);
+    add_dpms_timer (manager, manager->priv->prefs->dpms_sleep_timeout);
+
     /* FIXME: only emit signal once */
     g_signal_emit (manager, signals[ACTIVATED], 0);
 }
@@ -776,6 +833,8 @@ handle_window_dialog_up (GSManager *manager,
 
         manager_suspend_jobs (manager);
     }
+
+    remove_dpms_timer (manager);
 }
 
 static void
@@ -805,6 +864,9 @@ handle_window_dialog_down (GSManager *manager,
         manager_resume_jobs (manager);
     }
 
+    remove_dpms_timer (manager);
+    add_dpms_timer (manager, manager->priv->prefs->dpms_sleep_timeout);
+
     g_signal_emit (manager, signals[AUTH_REQUEST_END], 0);
 }
 
diff --git a/src/gs-prefs.c b/src/gs-prefs.c
index fef0bc9..74b0d93 100644
--- a/src/gs-prefs.c
+++ b/src/gs-prefs.c
@@ -145,6 +145,30 @@ _gs_prefs_set_cycle_timeout (GSPrefs *prefs,
 }
 
 static void
+_gs_prefs_set_dpms_sleep_timeout (GSPrefs *prefs,
+                                  int      value) {
+    if (value < 0)
+        value = 0;
+
+    if (value > 60)
+        value = 60;
+
+    prefs->dpms_sleep_timeout = value;
+}
+
+static void
+_gs_prefs_set_dpms_off_timeout (GSPrefs *prefs,
+                                int      value) {
+    if (value < 0)
+        value = 0;
+
+    if (value > 60)
+        value = 60;
+
+    prefs->dpms_off_timeout = value;
+}
+
+static void
 _gs_prefs_set_mode (GSPrefs    *prefs,
                     gint        mode) {
     prefs->mode = mode;
@@ -349,6 +373,16 @@ gs_prefs_load_from_settings (GSPrefs *prefs) {
                                     DEFAULT_KEY_CYCLE_DELAY);
     _gs_prefs_set_cycle_timeout (prefs, value);
 
+    value = xfconf_channel_get_double (prefs->priv->channel,
+                                       KEY_DPMS_SLEEP_AFTER,
+                                       DEFAULT_KEY_DPMS_SLEEP_AFTER);
+    _gs_prefs_set_dpms_sleep_timeout (prefs, (int)value);
+
+    value = xfconf_channel_get_double (prefs->priv->channel,
+                                       KEY_DPMS_OFF_AFTER,
+                                       DEFAULT_KEY_DPMS_OFF_AFTER);
+    _gs_prefs_set_dpms_off_timeout (prefs, (int)value);
+
     mode = xfconf_channel_get_int (prefs->priv->channel,
                                    KEY_MODE,
                                    DEFAULT_KEY_MODE);
@@ -485,6 +519,16 @@ key_changed_cb (XfconfChannel *channel,
 
         delay = xfconf_channel_get_int (channel, property, DEFAULT_KEY_CYCLE_DELAY);
         _gs_prefs_set_cycle_timeout (prefs, delay);
+    } else if (strcmp (property, KEY_DPMS_SLEEP_AFTER) == 0) {
+        double delay;
+
+        delay = xfconf_channel_get_double (channel, property, DEFAULT_KEY_DPMS_SLEEP_AFTER);
+        _gs_prefs_set_dpms_sleep_timeout (prefs, (int)delay);
+    } else if (strcmp (property, KEY_DPMS_OFF_AFTER) == 0) {
+        double delay;
+
+        delay = xfconf_channel_get_double (channel, property, DEFAULT_KEY_DPMS_OFF_AFTER);
+        _gs_prefs_set_dpms_off_timeout (prefs, (int)delay);
     } else if (strcmp (property, KEY_KEYBOARD_ENABLED) == 0) {
         gboolean enabled;
 
diff --git a/src/gs-prefs.h b/src/gs-prefs.h
index be02a7b..877110f 100644
--- a/src/gs-prefs.h
+++ b/src/gs-prefs.h
@@ -185,6 +185,22 @@ G_BEGIN_DECLS
 #define KEY_USER_SWITCH_ENABLED "/lock/user-switching/enabled"
 #define DEFAULT_KEY_USER_SWITCH_ENABLED TRUE
 
+/**
+ * Blank screensaver DPMS sleep timeout
+ * This value controls the timeout after blanking the screen to suspend the display.
+ * A value of 0 means that it is disabled.
+ */
+#define KEY_DPMS_SLEEP_AFTER "/screensavers/xfce-blank/dpms-sleep-after"
+#define DEFAULT_KEY_DPMS_SLEEP_AFTER 5
+
+/**
+ * Blank screensaver DPMS power timeout
+ * This value controls the timeout after blanking the screen to power off the display.
+ * A value of 0 means that it is disabled.
+ */
+#define KEY_DPMS_OFF_AFTER "/screensavers/xfce-blank/dpms-off-after"
+#define DEFAULT_KEY_DPMS_OFF_AFTER 15
+
 typedef enum
 {
     GS_MODE_BLANK_ONLY,
@@ -222,6 +238,9 @@ typedef struct
 
     GSList          *themes;   /* the screensaver themes to run */
     GSSaverMode      mode; /* theme selection mode */
+
+    guint            dpms_sleep_timeout; /* blank: # of minutes to wait before sleeping the display */
+    guint            dpms_off_timeout; /* blank: # of minutes after sleep to power off the display */
 } GSPrefs;
 
 typedef struct
diff --git a/src/xfce4-screensaver-configure b/src/xfce4-screensaver-configure
index f367416..7a102be 100755
--- a/src/xfce4-screensaver-configure
+++ b/src/xfce4-screensaver-configure
@@ -132,6 +132,25 @@ class DesktopScreensaverSettings(ScreensaverSettings):
         self.name = name
 
     def load_from_file(self, filename):
+        if self.name == "xfce-blank":
+            self.valid = True
+
+            self.options = self.parse_internal()
+            self.label = _("Blank screen")
+            comment = _("Powered by Display Power Management Signaling (DPMS),\n"
+                        "Xfce Screensaver can automatically suspend your displays\n"
+                        "to save power.\n\n"
+                        "Xfce Power Manager and other applications also manage\n"
+                        "DPMS settings. If your displays are powering off at different\n"
+                        "intervals, be sure to check for conflicting settings.")
+            self.arguments = []
+            self.description = comment
+
+            if self.options:
+                self.configurable = True
+
+            return True
+
         if not os.path.exists(filename):
             return False
 
@@ -163,6 +182,15 @@ class DesktopScreensaverSettings(ScreensaverSettings):
 
     def parse_internal(self):
         options = OrderedDict()
+        if self.name == "xfce-blank":
+            options["dpms-sleep-after"] = {'id': 'dpms-sleep-after', 'type': 'slider',
+                                           'label': _('After blanking, put display to sleep after'),
+                                           'default': 5, 'low': 0, 'high': 60, 'step': 1,
+                                           'low-label': _('Never'), 'high-label': _('60 minutes')}
+            options["dpms-off-after"] = {'id': 'dpms-off-after', 'type': 'slider',
+                                         'label': _('After sleeping, switch display off after'),
+                                         'default': 15, 'low': 0, 'high': 60, 'step': 1,
+                                         'low-label': _('Never'), 'high-label': _('60 minutes')}
         if self.name == "xfce-floaters":
             options["number-of-images"] = {'id': 'number-of-images', 'type': 'spinbutton',
                                            'label': _('Max number of images'), 'argument': '-n %',
@@ -593,10 +621,14 @@ class ConfigurationWindow(Gtk.Window):
 def get_slider_prefs(options):
     digits = 0
     for val in options:
-        val = str(val).split(".")[-1]
-        if val != "0":
-            val = val.rstrip("0")
-            digits = max(digits, len(val))
+        parts = str(val).split(".")
+        if len(parts) < 2:
+            digits = 0
+        else:
+            val = parts[-1]
+            if val != "0":
+                val = val.rstrip("0")
+                digits = max(digits, len(val))
     if digits == 0:
         return {'digits': 0, 'step': 1}
     return {'digits': digits, 'step': 10 ^ (-1 * digits)}
@@ -629,6 +661,9 @@ def get_filename(theme):
             if os.path.exists(cfg):
                 return cfg
 
+    if theme == "xfce-blank":
+        return ""
+
     return None
 
 
@@ -678,6 +713,10 @@ if __name__ == "__main__":
     graphical = not args.check
 
     saver = args.screensaver
+    if saver is None:
+        show_fatal(primary, _("Screensaver required.") % saver)
+        sys.exit(1)
+
     if saver.startswith("screensavers-"):
         saver = saver[13:]
 
@@ -690,7 +729,7 @@ if __name__ == "__main__":
 
     if fname.endswith(".xml"):
         obj = XmlScreensaverSettings(saver)
-    elif fname.endswith(".desktop"):
+    elif fname.endswith(".desktop") or saver == "xfce-blank":
         obj = DesktopScreensaverSettings(saver)
     else:
         locale.textdomain('xfce4-screensaver')
diff --git a/src/xfce4-screensaver-preferences.c b/src/xfce4-screensaver-preferences.c
index a73bfcb..2614cd9 100644
--- a/src/xfce4-screensaver-preferences.c
+++ b/src/xfce4-screensaver-preferences.c
@@ -267,16 +267,20 @@ config_set_theme (const char *theme_id) {
 
     if (theme_id && strcmp (theme_id, "__blank-only") == 0) {
         mode = GS_MODE_BLANK_ONLY;
+        active_theme = g_strdup ("xfce-blank");
     } else if (theme_id && strcmp (theme_id, "__random") == 0) {
         mode = GS_MODE_RANDOM;
 
         /* set the themes key to contain all available screensavers */
         strv = get_all_theme_ids (theme_manager);
     } else {
-        GtkWidget *configure_button = GTK_WIDGET (gtk_builder_get_object (builder, "configure_button"));
         mode = GS_MODE_SINGLE;
         strv = g_strsplit (theme_id, "%%%", 1);
         active_theme = g_strdup (theme_id);
+    }
+
+    if (mode != GS_MODE_RANDOM) {
+        GtkWidget *configure_button = GTK_WIDGET (gtk_builder_get_object (builder, "configure_button"));
         gtk_widget_set_sensitive (configure_button, TRUE);
     }
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list