summaryrefslogtreecommitdiff
path: root/community/gnome-settings-daemon-updates
diff options
context:
space:
mode:
authorroot <root@rshg054.dnsready.net>2012-10-31 01:35:35 -0700
committerroot <root@rshg054.dnsready.net>2012-10-31 01:35:35 -0700
commit5827948456201df72a1bd73e87977c569129fb27 (patch)
tree4842639ddc958690e68f74c496ea60844200450b /community/gnome-settings-daemon-updates
parent455295fdb5009a8cd7b033a93e01f7450fd3087b (diff)
Wed Oct 31 01:34:59 PDT 2012
Diffstat (limited to 'community/gnome-settings-daemon-updates')
-rw-r--r--community/gnome-settings-daemon-updates/0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch1473
-rw-r--r--community/gnome-settings-daemon-updates/PKGBUILD29
-rw-r--r--community/gnome-settings-daemon-updates/arch.patch274
-rw-r--r--community/gnome-settings-daemon-updates/gnome-settings-daemon.install3
-rw-r--r--community/gnome-settings-daemon-updates/screensaver.patch145
5 files changed, 1776 insertions, 148 deletions
diff --git a/community/gnome-settings-daemon-updates/0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch b/community/gnome-settings-daemon-updates/0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch
new file mode 100644
index 000000000..293a419df
--- /dev/null
+++ b/community/gnome-settings-daemon-updates/0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch
@@ -0,0 +1,1473 @@
+From 79ead5309fe21e77cfe58adc6a9340953c2d52f4 Mon Sep 17 00:00:00 2001
+From: Richard Hughes <richard@hughsie.com>
+Date: Fri, 21 Sep 2012 11:56:53 +0100
+Subject: [PATCH] power and media-keys: Use logind for suspending and
+ rebooting the system
+
+Use the new logind features to suspend and resume but making sure we opt out
+of logind handling the sleep and power keys, and also inhibiting for lid close
+auto-suspend if there is an external monitor connected.
+
+Also use a delay inihibit for logind so that we can do actions on suspend like
+blanking the screen using the screensaver and also poking the screensaver on
+resume.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=680689
+---
+ plugins/common/Makefile.am | 4 +-
+ plugins/common/gsd-power-helper.c | 203 --------
+ plugins/common/gsd-power-helper.h | 35 --
+ plugins/media-keys/gsd-media-keys-manager.c | 156 +++++--
+ plugins/power/gsd-power-manager.c | 699 +++++++++++++++++++---------
+ 5 files changed, 595 insertions(+), 502 deletions(-)
+ delete mode 100644 plugins/common/gsd-power-helper.c
+ delete mode 100644 plugins/common/gsd-power-helper.h
+
+diff --git a/plugins/common/Makefile.am b/plugins/common/Makefile.am
+index 7e50db4..b0e907c 100644
+--- a/plugins/common/Makefile.am
++++ b/plugins/common/Makefile.am
+@@ -6,9 +6,7 @@ libcommon_la_SOURCES = \
+ gsd-keygrab.c \
+ gsd-keygrab.h \
+ gsd-input-helper.c \
+- gsd-input-helper.h \
+- gsd-power-helper.c \
+- gsd-power-helper.h
++ gsd-input-helper.h
+
+ libcommon_la_CPPFLAGS = \
+ $(AM_CPPFLAGS)
+diff --git a/plugins/common/gsd-power-helper.c b/plugins/common/gsd-power-helper.c
+deleted file mode 100644
+index 27d0eda..0000000
+--- a/plugins/common/gsd-power-helper.c
++++ /dev/null
+@@ -1,203 +0,0 @@
+-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+- *
+- * Copyright (C) 2012 Bastien Nocera <hadess@hadess.net>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+- *
+- */
+-
+-#include "config.h"
+-
+-#include "gsd-power-helper.h"
+-
+-#define SYSTEMD_DBUS_NAME "org.freedesktop.login1"
+-#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1"
+-#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager"
+-
+-#define CONSOLEKIT_DBUS_NAME "org.freedesktop.ConsoleKit"
+-#define CONSOLEKIT_DBUS_PATH_MANAGER "/org/freedesktop/ConsoleKit/Manager"
+-#define CONSOLEKIT_DBUS_INTERFACE_MANAGER "org.freedesktop.ConsoleKit.Manager"
+-
+-#ifdef HAVE_SYSTEMD
+-static void
+-systemd_stop (void)
+-{
+- GDBusConnection *bus;
+-
+- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+- g_dbus_connection_call (bus,
+- SYSTEMD_DBUS_NAME,
+- SYSTEMD_DBUS_PATH,
+- SYSTEMD_DBUS_INTERFACE,
+- "PowerOff",
+- g_variant_new ("(b)", FALSE),
+- NULL, 0, G_MAXINT, NULL, NULL, NULL);
+- g_object_unref (bus);
+-}
+-
+-static void
+-systemd_suspend (void)
+-{
+- GDBusConnection *bus;
+-
+- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+- g_dbus_connection_call (bus,
+- SYSTEMD_DBUS_NAME,
+- SYSTEMD_DBUS_PATH,
+- SYSTEMD_DBUS_INTERFACE,
+- "Suspend",
+- g_variant_new ("(b)", TRUE),
+- NULL, 0, G_MAXINT, NULL, NULL, NULL);
+- g_object_unref (bus);
+-}
+-
+-static void
+-systemd_hibernate (void)
+-{
+- GDBusConnection *bus;
+-
+- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+- g_dbus_connection_call (bus,
+- SYSTEMD_DBUS_NAME,
+- SYSTEMD_DBUS_PATH,
+- SYSTEMD_DBUS_INTERFACE,
+- "Hibernate",
+- g_variant_new ("(b)", TRUE),
+- NULL, 0, G_MAXINT, NULL, NULL, NULL);
+- g_object_unref (bus);
+-}
+-
+-#else /* HAVE_SYSTEMD */
+-
+-static void
+-consolekit_stop_cb (GObject *source_object,
+- GAsyncResult *res,
+- gpointer user_data)
+-{
+- GVariant *result;
+- GError *error = NULL;
+-
+- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
+- res,
+- &error);
+- if (result == NULL) {
+- g_warning ("couldn't stop using ConsoleKit: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_variant_unref (result);
+- }
+-}
+-
+-static void
+-consolekit_stop (void)
+-{
+- GError *error = NULL;
+- GDBusProxy *proxy;
+-
+- /* power down the machine in a safe way */
+- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+- NULL,
+- CONSOLEKIT_DBUS_NAME,
+- CONSOLEKIT_DBUS_PATH_MANAGER,
+- CONSOLEKIT_DBUS_INTERFACE_MANAGER,
+- NULL, &error);
+- if (proxy == NULL) {
+- g_warning ("cannot connect to ConsoleKit: %s",
+- error->message);
+- g_error_free (error);
+- return;
+- }
+- g_dbus_proxy_call (proxy,
+- "Stop",
+- NULL,
+- G_DBUS_CALL_FLAGS_NONE,
+- -1, NULL,
+- consolekit_stop_cb, NULL);
+- g_object_unref (proxy);
+-}
+-static void
+-upower_sleep_cb (GObject *source_object,
+- GAsyncResult *res,
+- gpointer user_data)
+-{
+- GVariant *result;
+- GError *error = NULL;
+-
+- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
+- res,
+- &error);
+- if (result == NULL) {
+- g_warning ("couldn't sleep using UPower: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_variant_unref (result);
+- }
+-}
+-
+-static void
+-upower_suspend (GDBusProxy *upower_proxy)
+-{
+- g_dbus_proxy_call (upower_proxy,
+- "Suspend",
+- NULL,
+- G_DBUS_CALL_FLAGS_NONE,
+- -1, NULL,
+- upower_sleep_cb, NULL);
+-}
+-
+-static void
+-upower_hibernate (GDBusProxy *upower_proxy)
+-{
+- g_dbus_proxy_call (upower_proxy,
+- "Hibernate",
+- NULL,
+- G_DBUS_CALL_FLAGS_NONE,
+- -1, NULL,
+- upower_sleep_cb, NULL);
+-}
+-#endif /* HAVE_SYSTEMD */
+-
+-void
+-gsd_power_suspend (GDBusProxy *upower_proxy)
+-{
+-#ifdef HAVE_SYSTEMD
+- systemd_suspend ();
+-#else
+- upower_suspend (upower_proxy);
+-#endif
+-}
+-
+-void
+-gsd_power_poweroff (void)
+-{
+-#ifdef HAVE_SYSTEMD
+- systemd_stop ();
+-#else
+- consolekit_stop ();
+-#endif
+-}
+-
+-void
+-gsd_power_hibernate (GDBusProxy *upower_proxy)
+-{
+-#ifdef HAVE_SYSTEMD
+- systemd_hibernate ();
+-#else
+- upower_hibernate (upower_proxy);
+-#endif
+-}
+diff --git a/plugins/common/gsd-power-helper.h b/plugins/common/gsd-power-helper.h
+deleted file mode 100644
+index e3be14f..0000000
+--- a/plugins/common/gsd-power-helper.h
++++ /dev/null
+@@ -1,35 +0,0 @@
+-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+- *
+- * Copyright (C) 2012 Bastien Nocera <hadess@hadess.net>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+- */
+-
+-#ifndef __GSD_POWER_HELPER_H
+-#define __GSD_POWER_HELPER_H
+-
+-#include <glib.h>
+-
+-G_BEGIN_DECLS
+-
+-#include <gio/gio.h>
+-
+-void gsd_power_suspend (GDBusProxy *upower_proxy);
+-void gsd_power_hibernate (GDBusProxy *upower_proxy);
+-void gsd_power_poweroff (void);
+-
+-G_END_DECLS
+-
+-#endif /* __GSD_POWER_HELPER_H */
+diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
+index 9c84d7f..a2f277e 100644
+--- a/plugins/media-keys/gsd-media-keys-manager.c
++++ b/plugins/media-keys/gsd-media-keys-manager.c
+@@ -39,6 +39,7 @@
+ #include <gdk/gdkx.h>
+ #include <gtk/gtk.h>
+ #include <gio/gdesktopappinfo.h>
++#include <gio/gunixfdlist.h>
+
+ #ifdef HAVE_GUDEV
+ #include <gudev/gudev.h>
+@@ -51,7 +52,6 @@
+ #include "shortcuts-list.h"
+ #include "gsd-osd-window.h"
+ #include "gsd-input-helper.h"
+-#include "gsd-power-helper.h"
+ #include "gsd-enums.h"
+
+ #include <canberra.h>
+@@ -105,6 +105,10 @@ static const gchar introspection_xml[] =
+ #define KEY_CURRENT_INPUT_SOURCE "current"
+ #define KEY_INPUT_SOURCES "sources"
+
++#define SYSTEMD_DBUS_NAME "org.freedesktop.login1"
++#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1"
++#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager"
++
+ #define GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManagerPrivate))
+
+ typedef struct {
+@@ -148,10 +152,13 @@ struct GsdMediaKeysManagerPrivate
+
+ /* Power stuff */
+ GSettings *power_settings;
+- GDBusProxy *upower_proxy;
+ GDBusProxy *power_screen_proxy;
+ GDBusProxy *power_keyboard_proxy;
+
++ /* systemd stuff */
++ GDBusProxy *logind_proxy;
++ gint inhibit_keys_fd;
++
+ /* Multihead stuff */
+ GdkScreen *current_screen;
+ GSList *screens;
+@@ -1618,6 +1625,38 @@ do_toggle_contrast_action (GsdMediaKeysManager *manager)
+ }
+
+ static void
++power_action_suspend (GsdMediaKeysManager *manager)
++{
++#ifndef HAVE_SYSTEMD
++ g_warning ("no systemd support");
++ return;
++#endif
++ g_dbus_proxy_call (manager->priv->logind_proxy,
++ "Suspend",
++ g_variant_new ("(b)", TRUE),
++ G_DBUS_CALL_FLAGS_NONE,
++ G_MAXINT,
++ manager->priv->bus_cancellable,
++ NULL, NULL);
++}
++
++static void
++power_action_hibernate (GsdMediaKeysManager *manager)
++{
++#ifndef HAVE_SYSTEMD
++ g_warning ("no systemd support");
++ return;
++#endif
++ g_dbus_proxy_call (manager->priv->logind_proxy,
++ "Hibernate",
++ g_variant_new ("(b)", TRUE),
++ G_DBUS_CALL_FLAGS_NONE,
++ G_MAXINT,
++ manager->priv->bus_cancellable,
++ NULL, NULL);
++}
++
++static void
+ do_config_power_action (GsdMediaKeysManager *manager,
+ const gchar *config_key)
+ {
+@@ -1627,14 +1666,14 @@ do_config_power_action (GsdMediaKeysManager *manager,
+ config_key);
+ switch (action_type) {
+ case GSD_POWER_ACTION_SUSPEND:
+- gsd_power_suspend (manager->priv->upower_proxy);
++ power_action_suspend (manager);
+ break;
+ case GSD_POWER_ACTION_INTERACTIVE:
+ case GSD_POWER_ACTION_SHUTDOWN:
+ gnome_session_shutdown (manager);
+ break;
+ case GSD_POWER_ACTION_HIBERNATE:
+- gsd_power_hibernate (manager->priv->upower_proxy);
++ power_action_hibernate (manager);
+ break;
+ case GSD_POWER_ACTION_BLANK:
+ case GSD_POWER_ACTION_NOTHING:
+@@ -2248,6 +2287,7 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
+ }
+ #endif /* HAVE_GUDEV */
+
++ g_clear_object (&priv->logind_proxy);
+ if (priv->settings) {
+ g_object_unref (priv->settings);
+ priv->settings = NULL;
+@@ -2268,11 +2308,6 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
+ priv->power_keyboard_proxy = NULL;
+ }
+
+- if (priv->upower_proxy) {
+- g_object_unref (priv->upower_proxy);
+- priv->upower_proxy = NULL;
+- }
+-
+ if (priv->cancellable != NULL) {
+ g_cancellable_cancel (priv->cancellable);
+ g_object_unref (priv->cancellable);
+@@ -2363,9 +2398,85 @@ gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass)
+ }
+
+ static void
++inhibit_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsdMediaKeysManager *manager = GSD_MEDIA_KEYS_MANAGER (user_data);
++ GError *error = NULL;
++ GVariant *res;
++ GUnixFDList *fd_list = NULL;
++ gint idx;
++
++ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
++ if (res == NULL) {
++ g_warning ("Unable to inhibit keypresses: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_get (res, "(h)", &idx);
++ manager->priv->inhibit_keys_fd = g_unix_fd_list_get (fd_list, idx, &error);
++ if (manager->priv->inhibit_keys_fd == -1) {
++ g_warning ("Failed to receive system inhibitor fd: %s", error->message);
++ g_error_free (error);
++ }
++ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_keys_fd);
++ g_object_unref (fd_list);
++ g_variant_unref (res);
++ }
++}
++
++static void
+ gsd_media_keys_manager_init (GsdMediaKeysManager *manager)
+ {
++ GError *error;
++ GDBusConnection *bus;
++
++ error = NULL;
+ manager->priv = GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager);
++
++ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
++ if (bus == NULL) {
++ g_warning ("Failed to connect to system bus: %s",
++ error->message);
++ g_error_free (error);
++ return;
++ }
++
++ manager->priv->logind_proxy =
++ g_dbus_proxy_new_sync (bus,
++ 0,
++ NULL,
++ SYSTEMD_DBUS_NAME,
++ SYSTEMD_DBUS_PATH,
++ SYSTEMD_DBUS_INTERFACE,
++ NULL,
++ &error);
++
++ if (manager->priv->logind_proxy == NULL) {
++ g_warning ("Failed to connect to systemd: %s",
++ error->message);
++ g_error_free (error);
++ }
++
++ g_object_unref (bus);
++
++ g_debug ("Adding system inhibitors for power keys");
++ manager->priv->inhibit_keys_fd = -1;
++ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy,
++ "Inhibit",
++ g_variant_new ("(ssss)",
++ "handle-power-key:handle-suspend-key:handle-hibernate-key",
++ g_get_user_name (),
++ "GNOME handling keypresses",
++ "block"),
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL,
++ inhibit_done,
++ manager);
++
+ }
+
+ static void
+@@ -2382,6 +2493,8 @@ gsd_media_keys_manager_finalize (GObject *object)
+
+ if (media_keys_manager->priv->start_idle_id != 0)
+ g_source_remove (media_keys_manager->priv->start_idle_id);
++ if (media_keys_manager->priv->inhibit_keys_fd != -1)
++ close (media_keys_manager->priv->inhibit_keys_fd);
+
+ G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->finalize (object);
+ }
+@@ -2401,21 +2514,6 @@ xrandr_ready_cb (GObject *source_object,
+ }
+
+ static void
+-upower_ready_cb (GObject *source_object,
+- GAsyncResult *res,
+- GsdMediaKeysManager *manager)
+-{
+- GError *error = NULL;
+-
+- manager->priv->upower_proxy = g_dbus_proxy_new_finish (res, &error);
+- if (manager->priv->upower_proxy == NULL) {
+- g_warning ("Failed to get proxy for upower: %s",
+- error->message);
+- g_error_free (error);
+- }
+-}
+-
+-static void
+ power_screen_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ GsdMediaKeysManager *manager)
+@@ -2517,16 +2615,6 @@ register_manager (GsdMediaKeysManager *manager)
+ manager->priv->bus_cancellable,
+ (GAsyncReadyCallback) on_bus_gotten,
+ manager);
+-
+- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+- G_DBUS_PROXY_FLAGS_NONE,
+- NULL,
+- "org.freedesktop.UPower",
+- "/org/freedesktop/UPower",
+- "org.freedesktop.UPower",
+- NULL,
+- (GAsyncReadyCallback) upower_ready_cb,
+- manager);
+ }
+
+ GsdMediaKeysManager *
+diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
+index 070cf32..18fcedf 100644
+--- a/plugins/power/gsd-power-manager.c
++++ b/plugins/power/gsd-power-manager.c
+@@ -1,7 +1,7 @@
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+- * Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
++ * Copyright (C) 2011-2012 Richard Hughes <richard@hughsie.com>
+ * Copyright (C) 2011 Ritesh Khadgaray <khadgaray@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -32,6 +32,7 @@
+ #include <libupower-glib/upower.h>
+ #include <libnotify/notify.h>
+ #include <canberra-gtk.h>
++#include <gio/gunixfdlist.h>
+
+ #define GNOME_DESKTOP_USE_UNSTABLE_API
+ #include <libgnome-desktop/gnome-rr.h>
+@@ -43,7 +44,6 @@
+ #include "gnome-settings-session.h"
+ #include "gsd-enums.h"
+ #include "gsd-power-manager.h"
+-#include "gsd-power-helper.h"
+
+ #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager"
+ #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager"
+@@ -78,6 +78,10 @@
+ #define GSD_POWER_MANAGER_RECALL_DELAY 30 /* seconds */
+ #define GSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT 30 /* seconds */
+
++#define SYSTEMD_DBUS_NAME "org.freedesktop.login1"
++#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1"
++#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager"
++
+ /* Keep this in sync with gnome-shell */
+ #define SCREENSAVER_FADE_TIME 10 /* seconds */
+
+@@ -193,14 +197,20 @@ struct GsdPowerManagerPrivate
+ ca_context *canberra_context;
+ ca_proplist *critical_alert_loop_props;
+ guint32 critical_alert_timeout_id;
+- GDBusProxy *screensaver_proxy;
+ GDBusProxy *session_proxy;
+ GDBusProxy *session_presence_proxy;
+ GpmIdletime *idletime;
+ GsdPowerIdleMode current_idle_mode;
+- guint lid_close_safety_timer_id;
+ GtkStatusIcon *status_icon;
+ guint xscreensaver_watchdog_timer_id;
++
++ /* systemd stuff */
++ GDBusProxy *logind_proxy;
++ gint inhibit_lid_switch_fd;
++ gboolean inhibit_lid_switch_taken;
++ gint inhibit_suspend_fd;
++ gboolean inhibit_suspend_taken;
++ guint inhibit_lid_switch_timer_id;
+ };
+
+ enum {
+@@ -217,8 +227,8 @@ static GIcon *engine_get_icon (GsdPowerManager *manager);
+ static gchar *engine_get_summary (GsdPowerManager *manager);
+ static void do_power_action_type (GsdPowerManager *manager, GsdPowerActionType action_type);
+ static void do_lid_closed_action (GsdPowerManager *manager);
+-static void lock_screensaver (GsdPowerManager *manager);
+-static void kill_lid_close_safety_timer (GsdPowerManager *manager);
++static void uninhibit_lid_switch (GsdPowerManager *manager);
++static gboolean external_monitor_is_connected (GnomeRRScreen *screen);
+
+ G_DEFINE_TYPE (GsdPowerManager, gsd_power_manager, G_TYPE_OBJECT)
+
+@@ -2048,6 +2058,57 @@ gnome_session_shutdown (void)
+ }
+
+ static void
++action_poweroff (GsdPowerManager *manager)
++{
++ if (manager->priv->logind_proxy == NULL) {
++ g_warning ("no systemd support");
++ return;
++ }
++ g_dbus_proxy_call (manager->priv->logind_proxy,
++ "PowerOff",
++ g_variant_new ("(b)", FALSE),
++ G_DBUS_CALL_FLAGS_NONE,
++ G_MAXINT,
++ NULL,
++ NULL,
++ NULL);
++}
++
++static void
++action_suspend (GsdPowerManager *manager)
++{
++ if (manager->priv->logind_proxy == NULL) {
++ g_warning ("no systemd support");
++ return;
++ }
++ g_dbus_proxy_call (manager->priv->logind_proxy,
++ "Suspend",
++ g_variant_new ("(b)", FALSE),
++ G_DBUS_CALL_FLAGS_NONE,
++ G_MAXINT,
++ NULL,
++ NULL,
++ NULL);
++}
++
++static void
++action_hibernate (GsdPowerManager *manager)
++{
++ if (manager->priv->logind_proxy == NULL) {
++ g_warning ("no systemd support");
++ return;
++ }
++ g_dbus_proxy_call (manager->priv->logind_proxy,
++ "Hibernate",
++ g_variant_new ("(b)", FALSE),
++ G_DBUS_CALL_FLAGS_NONE,
++ G_MAXINT,
++ NULL,
++ NULL,
++ NULL);
++}
++
++static void
+ do_power_action_type (GsdPowerManager *manager,
+ GsdPowerActionType action_type)
+ {
+@@ -2056,19 +2117,19 @@ do_power_action_type (GsdPowerManager *manager,
+
+ switch (action_type) {
+ case GSD_POWER_ACTION_SUSPEND:
+- gsd_power_suspend (manager->priv->upower_proxy);
++ action_suspend (manager);
+ break;
+ case GSD_POWER_ACTION_INTERACTIVE:
+ gnome_session_shutdown ();
+ break;
+ case GSD_POWER_ACTION_HIBERNATE:
+- gsd_power_hibernate (manager->priv->upower_proxy);
++ action_hibernate (manager);
+ break;
+ case GSD_POWER_ACTION_SHUTDOWN:
+ /* this is only used on critically low battery where
+ * hibernate is not available and is marginally better
+ * than just powering down the computer mid-write */
+- gsd_power_poweroff ();
++ action_poweroff (manager);
+ break;
+ case GSD_POWER_ACTION_BLANK:
+ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
+@@ -2140,85 +2201,20 @@ upower_kbd_toggle (GsdPowerManager *manager,
+ return ret;
+ }
+
+-static void
+-do_lid_open_action (GsdPowerManager *manager)
+-{
+- gboolean ret;
+- GError *error = NULL;
+-
+- /* play a sound, using sounds from the naming spec */
+- ca_context_play (manager->priv->canberra_context, 0,
+- CA_PROP_EVENT_ID, "lid-open",
+- /* TRANSLATORS: this is the sound description */
+- CA_PROP_EVENT_DESCRIPTION, _("Lid has been opened"),
+- NULL);
+-
+- /* ensure we turn the panel back on after lid open */
+- ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
+- GNOME_RR_DPMS_ON,
+- &error);
+- if (!ret) {
+- g_warning ("failed to turn the panel on after lid open: %s",
+- error->message);
+- g_clear_error (&error);
+- }
+-
+- /* only toggle keyboard if present and already toggled off */
+- if (manager->priv->upower_kdb_proxy != NULL &&
+- manager->priv->kbd_brightness_old != -1) {
+- ret = upower_kbd_toggle (manager, &error);
+- if (!ret) {
+- g_warning ("failed to turn the kbd backlight on: %s",
+- error->message);
+- g_error_free (error);
+- }
+- }
+-
+- kill_lid_close_safety_timer (manager);
+-}
+-
+ static gboolean
+-is_on (GnomeRROutput *output)
++inhibit_lid_switch_timer_cb (GsdPowerManager *manager)
+ {
+- GnomeRRCrtc *crtc;
+-
+- crtc = gnome_rr_output_get_crtc (output);
+- if (!crtc)
+- return FALSE;
+- return gnome_rr_crtc_get_current_mode (crtc) != NULL;
+-}
+-
+-static gboolean
+-non_laptop_outputs_are_all_off (GnomeRRScreen *screen)
+-{
+- GnomeRROutput **outputs;
+- int i;
+-
+- outputs = gnome_rr_screen_list_outputs (screen);
+- for (i = 0; outputs[i] != NULL; i++) {
+- if (gnome_rr_output_is_laptop (outputs[i]))
+- continue;
+-
+- if (is_on (outputs[i]))
+- return FALSE;
++ if (!external_monitor_is_connected (manager->priv->x11_screen) ||
++ g_settings_get_boolean (manager->priv->settings,
++ "lid-close-suspend-with-external-monitor")) {
++ g_debug ("no external monitors for a while; uninhibiting lid close");
++ uninhibit_lid_switch (manager);
++ manager->priv->inhibit_lid_switch_timer_id = 0;
++ return G_SOURCE_REMOVE;
+ }
+
+- return TRUE;
+-}
+-
+-/* Timeout callback used to check conditions when the laptop's lid is closed but
+- * the machine is not suspended yet. We try to suspend again, so that the laptop
+- * won't overheat if placed in a backpack.
+- */
+-static gboolean
+-lid_close_safety_timer_cb (GsdPowerManager *manager)
+-{
+- manager->priv->lid_close_safety_timer_id = 0;
+-
+- g_debug ("lid has been closed for a while; trying to suspend again");
+- do_lid_closed_action (manager);
+-
+- return FALSE;
++ g_debug ("external monitor still there; trying again later");
++ return G_SOURCE_CONTINUE;
+ }
+
+ /* Sets up a timer to be triggered some seconds after closing the laptop lid
+@@ -2226,82 +2222,73 @@ lid_close_safety_timer_cb (GsdPowerManager *manager)
+ * again in the timeout handler to see if we can suspend then.
+ */
+ static void
+-setup_lid_close_safety_timer (GsdPowerManager *manager)
++setup_inhibit_lid_switch_timer (GsdPowerManager *manager)
+ {
+- if (manager->priv->lid_close_safety_timer_id != 0)
++ if (manager->priv->inhibit_lid_switch_timer_id != 0) {
++ g_debug ("lid close safety timer already set up");
+ return;
++ }
++
++ g_debug ("setting up lid close safety timer");
+
+- manager->priv->lid_close_safety_timer_id = g_timeout_add_seconds (GSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT,
+- (GSourceFunc) lid_close_safety_timer_cb,
++ manager->priv->inhibit_lid_switch_timer_id = g_timeout_add_seconds (GSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT,
++ (GSourceFunc) inhibit_lid_switch_timer_cb,
+ manager);
+- g_source_set_name_by_id (manager->priv->lid_close_safety_timer_id, "[GsdPowerManager] lid close safety timer");
++ g_source_set_name_by_id (manager->priv->inhibit_lid_switch_timer_id, "[GsdPowerManager] lid close safety timer");
+ }
+
+ static void
+-kill_lid_close_safety_timer (GsdPowerManager *manager)
++restart_inhibit_lid_switch_timer (GsdPowerManager *manager)
+ {
+- if (manager->priv->lid_close_safety_timer_id != 0) {
+- g_source_remove (manager->priv->lid_close_safety_timer_id);
+- manager->priv->lid_close_safety_timer_id = 0;
++ if (manager->priv->inhibit_lid_switch_timer_id != 0) {
++ g_debug ("restarting lid close safety timer");
++ g_source_remove (manager->priv->inhibit_lid_switch_timer_id);
++ manager->priv->inhibit_lid_switch_timer_id = 0;
++ setup_inhibit_lid_switch_timer (manager);
+ }
+ }
+
+ static void
+-suspend_with_lid_closed (GsdPowerManager *manager)
++do_lid_open_action (GsdPowerManager *manager)
+ {
+ gboolean ret;
+ GError *error = NULL;
+- GsdPowerActionType action_type;
+
+- /* maybe lock the screen if the lid is closed */
+- lock_screensaver (manager);
+-
+- /* we have different settings depending on AC state */
+- if (up_client_get_on_battery (manager->priv->up_client)) {
+- action_type = g_settings_get_enum (manager->priv->settings,
+- "lid-close-battery-action");
+- } else {
+- action_type = g_settings_get_enum (manager->priv->settings,
+- "lid-close-ac-action");
+- }
+-
+- /* check we won't melt when the lid is closed */
+- if (action_type != GSD_POWER_ACTION_SUSPEND &&
+- action_type != GSD_POWER_ACTION_HIBERNATE) {
+- if (up_client_get_lid_force_sleep (manager->priv->up_client)) {
+- g_warning ("to prevent damage, now forcing suspend");
+- do_power_action_type (manager, GSD_POWER_ACTION_SUSPEND);
+- return;
+- }
+- }
++ /* play a sound, using sounds from the naming spec */
++ ca_context_play (manager->priv->canberra_context, 0,
++ CA_PROP_EVENT_ID, "lid-open",
++ /* TRANSLATORS: this is the sound description */
++ CA_PROP_EVENT_DESCRIPTION, _("Lid has been opened"),
++ NULL);
+
+- /* ensure we turn the panel back on after resume */
++ /* ensure we turn the panel back on after lid open */
+ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
+- GNOME_RR_DPMS_OFF,
++ GNOME_RR_DPMS_ON,
+ &error);
+ if (!ret) {
+- g_warning ("failed to turn the panel off after lid close: %s",
++ g_warning ("failed to turn the panel on after lid open: %s",
+ error->message);
+- g_error_free (error);
++ g_clear_error (&error);
+ }
+
+- /* only toggle keyboard if present and not already toggled */
+- if (manager->priv->upower_kdb_proxy &&
+- manager->priv->kbd_brightness_old == -1) {
++ /* only toggle keyboard if present and already toggled off */
++ if (manager->priv->upower_kdb_proxy != NULL &&
++ manager->priv->kbd_brightness_old != -1) {
+ ret = upower_kbd_toggle (manager, &error);
+ if (!ret) {
+- g_warning ("failed to turn the kbd backlight off: %s",
++ g_warning ("failed to turn the kbd backlight on: %s",
+ error->message);
+ g_error_free (error);
+ }
+ }
+-
+- do_power_action_type (manager, action_type);
+ }
+
+ static void
+ do_lid_closed_action (GsdPowerManager *manager)
+ {
++ gboolean ret;
++ GError *error = NULL;
++
+ /* play a sound, using sounds from the naming spec */
+ ca_context_play (manager->priv->canberra_context, 0,
+ CA_PROP_EVENT_ID, "lid-close",
+@@ -2309,21 +2296,22 @@ do_lid_closed_action (GsdPowerManager *manager)
+ CA_PROP_EVENT_DESCRIPTION, _("Lid has been closed"),
+ NULL);
+
++ /* turn the panel off if the lid is closed (mainly for Dells...) */
++ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
++ GNOME_RR_DPMS_OFF,
++ &error);
++ if (!ret) {
++ g_warning ("failed to turn the panel off after lid close: %s",
++ error->message);
++ g_error_free (error);
++ }
++
+ /* refresh RANDR so we get an accurate view of what monitors are plugged in when the lid is closed */
+ gnome_rr_screen_refresh (manager->priv->x11_screen, NULL); /* NULL-GError */
+
+- /* perform policy action */
+- if (g_settings_get_boolean (manager->priv->settings, "lid-close-suspend-with-external-monitor")
+- || non_laptop_outputs_are_all_off (manager->priv->x11_screen)) {
+- g_debug ("lid is closed; suspending or hibernating");
+- suspend_with_lid_closed (manager);
+- } else {
+- g_debug ("lid is closed; not suspending nor hibernating since some external monitor outputs are still active");
+- setup_lid_close_safety_timer (manager);
+- }
++ restart_inhibit_lid_switch_timer (manager);
+ }
+
+-
+ static void
+ up_client_changed_cb (UpClient *client, GsdPowerManager *manager)
+ {
+@@ -2343,6 +2331,7 @@ up_client_changed_cb (UpClient *client, GsdPowerManager *manager)
+ if (manager->priv->lid_is_closed == tmp)
+ return;
+ manager->priv->lid_is_closed = tmp;
++ g_debug ("up changed: lid is now %s", tmp ? "closed" : "open");
+
+ /* fake a keypress */
+ if (tmp)
+@@ -3294,30 +3283,6 @@ gsd_power_manager_class_init (GsdPowerManagerClass *klass)
+ }
+
+ static void
+-sleep_cb_screensaver_proxy_ready_cb (GObject *source_object,
+- GAsyncResult *res,
+- gpointer user_data)
+-{
+- GError *error = NULL;
+- GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
+-
+- manager->priv->screensaver_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+- if (manager->priv->screensaver_proxy == NULL) {
+- g_warning ("Could not connect to gnome-screensaver: %s",
+- error->message);
+- g_error_free (error);
+- return;
+- }
+-
+- /* Finish the upower_notify_sleep_cb() call by locking the screen */
+- g_debug ("gnome-screensaver activated, doing gnome-screensaver lock");
+- g_dbus_proxy_call (manager->priv->screensaver_proxy,
+- "Lock",
+- NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+- NULL, NULL, NULL);
+-}
+-
+-static void
+ idle_dbus_signal_cb (GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+@@ -3469,75 +3434,38 @@ out:
+ }
+
+ static void
+-lock_screensaver (GsdPowerManager *manager)
++lock_screensaver (GsdPowerManager *manager,
++ GSourceFunc done_cb)
+ {
+ gboolean do_lock;
+
+ do_lock = g_settings_get_boolean (manager->priv->settings_screensaver,
+ "lock-enabled");
+- if (!do_lock)
++ if (!do_lock && done_cb) {
++ done_cb (manager);
+ return;
+-
+- if (manager->priv->screensaver_proxy != NULL) {
+- g_debug ("doing gnome-screensaver lock");
+- g_dbus_proxy_call (manager->priv->screensaver_proxy,
+- "Lock",
+- NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+- NULL, NULL, NULL);
+- } else {
+- /* connect to the screensaver first */
+- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+- NULL,
+- GS_DBUS_NAME,
+- GS_DBUS_PATH,
+- GS_DBUS_INTERFACE,
+- NULL,
+- sleep_cb_screensaver_proxy_ready_cb,
+- manager);
+ }
+-}
+-
+-static void
+-upower_notify_sleep_cb (UpClient *client,
+- UpSleepKind sleep_kind,
+- GsdPowerManager *manager)
+-{
+- lock_screensaver (manager);
+-}
+-
+-static void
+-upower_notify_resume_cb (UpClient *client,
+- UpSleepKind sleep_kind,
+- GsdPowerManager *manager)
+-{
+- gboolean ret;
+- GError *error = NULL;
+-
+- /* this displays the unlock dialogue so the user doesn't have
+- * to move the mouse or press any key before the window comes up */
+- if (manager->priv->screensaver_proxy != NULL) {
+- g_dbus_proxy_call (manager->priv->screensaver_proxy,
+- "SimulateUserActivity",
+- NULL,
+- G_DBUS_CALL_FLAGS_NONE,
+- -1, NULL, NULL, NULL);
+- }
+-
+- /* close existing notifications on resume, the system power
+- * state is probably different now */
+- notify_close_if_showing (manager->priv->notification_low);
+- notify_close_if_showing (manager->priv->notification_discharging);
+
+- /* ensure we turn the panel back on after resume */
+- ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
+- GNOME_RR_DPMS_ON,
+- &error);
+- if (!ret) {
+- g_warning ("failed to turn the panel on after resume: %s",
+- error->message);
+- g_error_free (error);
+- }
++ g_dbus_connection_call (manager->priv->connection,
++ GS_DBUS_NAME,
++ GS_DBUS_PATH,
++ GS_DBUS_INTERFACE,
++ "Lock",
++ NULL, NULL,
++ G_DBUS_CALL_FLAGS_NONE, -1,
++ NULL, NULL, NULL);
++
++ /* Wait until gnome-shell shield animation is done
++ *
++ * FIXME: the shell should mark the lock as active
++ * when the shield is down, then we could wait for
++ * that. This would also fix the problem that we wait
++ * needlessly when the shell has already locked the
++ * screen because it is initiating the suspend.
++ *
++ * https://bugzilla.gnome.org/show_bug.cgi?id=685053
++ */
++ g_timeout_add (500, done_cb, manager);
+ }
+
+ static void
+@@ -3696,6 +3624,287 @@ disable_builtin_screensaver (gpointer unused)
+ return TRUE;
+ }
+
++static void
++inhibit_lid_switch_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
++ GError *error = NULL;
++ GVariant *res;
++ GUnixFDList *fd_list = NULL;
++ gint idx;
++
++ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
++ if (res == NULL) {
++ g_warning ("Unable to inhibit lid switch: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_get (res, "(h)", &idx);
++ manager->priv->inhibit_lid_switch_fd = g_unix_fd_list_get (fd_list, idx, &error);
++ if (manager->priv->inhibit_lid_switch_fd == -1) {
++ g_warning ("Failed to receive system inhibitor fd: %s", error->message);
++ g_error_free (error);
++ }
++ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_lid_switch_fd);
++ g_object_unref (fd_list);
++ g_variant_unref (res);
++ }
++}
++
++static void
++inhibit_lid_switch (GsdPowerManager *manager)
++{
++ GVariant *params;
++
++ if (manager->priv->inhibit_lid_switch_taken) {
++ g_debug ("already inhibited lid-switch");
++ return;
++ }
++ g_debug ("Adding lid switch system inhibitor");
++ manager->priv->inhibit_lid_switch_taken = TRUE;
++
++ params = g_variant_new ("(ssss)",
++ "handle-lid-switch",
++ g_get_user_name (),
++ "Multiple displays attached",
++ "block");
++ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy,
++ "Inhibit",
++ params,
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL,
++ inhibit_lid_switch_done,
++ manager);
++}
++
++static void
++uninhibit_lid_switch (GsdPowerManager *manager)
++{
++ if (manager->priv->inhibit_lid_switch_fd == -1) {
++ g_debug ("no lid-switch inhibitor");
++ return;
++ }
++ g_debug ("Removing lid switch system inhibitor");
++ close (manager->priv->inhibit_lid_switch_fd);
++ manager->priv->inhibit_lid_switch_fd = -1;
++ manager->priv->inhibit_lid_switch_taken = FALSE;
++}
++
++static void
++inhibit_suspend_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
++ GError *error = NULL;
++ GVariant *res;
++ GUnixFDList *fd_list = NULL;
++ gint idx;
++
++ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
++ if (res == NULL) {
++ g_warning ("Unable to inhibit suspend: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_get (res, "(h)", &idx);
++ manager->priv->inhibit_suspend_fd = g_unix_fd_list_get (fd_list, idx, &error);
++ if (manager->priv->inhibit_suspend_fd == -1) {
++ g_warning ("Failed to receive system inhibitor fd: %s", error->message);
++ g_error_free (error);
++ }
++ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_suspend_fd);
++ g_object_unref (fd_list);
++ g_variant_unref (res);
++ }
++}
++
++/* We take a delay inhibitor here, which causes logind to send a
++ * PrepareToSleep signal, which gives us a chance to lock the screen
++ * and do some other preparations.
++ */
++static void
++inhibit_suspend (GsdPowerManager *manager)
++{
++ if (manager->priv->inhibit_suspend_taken) {
++ g_debug ("already inhibited lid-switch");
++ return;
++ }
++ g_debug ("Adding suspend delay inhibitor");
++ manager->priv->inhibit_suspend_taken = TRUE;
++ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy,
++ "Inhibit",
++ g_variant_new ("(ssss)",
++ "sleep",
++ g_get_user_name (),
++ "GNOME needs to lock the screen",
++ "delay"),
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL,
++ inhibit_suspend_done,
++ manager);
++}
++
++static void
++uninhibit_suspend (GsdPowerManager *manager)
++{
++ if (manager->priv->inhibit_suspend_fd == -1) {
++ g_debug ("no suspend delay inhibitor");
++ return;
++ }
++ g_debug ("Removing suspend delay inhibitor");
++ close (manager->priv->inhibit_suspend_fd);
++ manager->priv->inhibit_suspend_fd = -1;
++ manager->priv->inhibit_suspend_taken = TRUE;
++}
++
++static gboolean
++randr_output_is_on (GnomeRROutput *output)
++{
++ GnomeRRCrtc *crtc;
++
++ crtc = gnome_rr_output_get_crtc (output);
++ if (!crtc)
++ return FALSE;
++ return gnome_rr_crtc_get_current_mode (crtc) != NULL;
++}
++
++static gboolean
++external_monitor_is_connected (GnomeRRScreen *screen)
++{
++ GnomeRROutput **outputs;
++ guint i;
++
++ if (g_file_test ("/tmp/external_connected", G_FILE_TEST_EXISTS))
++ return TRUE;
++
++ /* see if we have more than one screen plugged in */
++ outputs = gnome_rr_screen_list_outputs (screen);
++ for (i = 0; outputs[i] != NULL; i++) {
++ if (randr_output_is_on (outputs[i]) &&
++ !gnome_rr_output_is_laptop (outputs[i]))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static void
++on_randr_event (GnomeRRScreen *screen, gpointer user_data)
++{
++ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
++
++ /* when a second monitor is plugged in, we take the
++ * handle-lid-switch inhibitor lock of logind to prevent
++ * it from suspending.
++ *
++ * Uninhibiting is done in the inhibit_lid_switch_timer,
++ * since we want to give users a few seconds when unplugging
++ * and replugging an external monitor, not suspend right away.
++ */
++ if (external_monitor_is_connected (screen) &&
++ !g_settings_get_boolean (manager->priv->settings,
++ "lid-close-suspend-with-external-monitor")) {
++ inhibit_lid_switch (manager);
++ setup_inhibit_lid_switch_timer (manager);
++ }
++ else {
++ restart_inhibit_lid_switch_timer (manager);
++ }
++}
++
++static gboolean
++screen_lock_done_cb (gpointer data)
++{
++ GsdPowerManager *manager = data;
++
++ /* lift the delay inhibit, so logind can proceed */
++ uninhibit_suspend (manager);
++
++ return FALSE;
++}
++
++static void
++handle_suspend_actions (GsdPowerManager *manager)
++{
++ gboolean ret;
++ GError *error = NULL;
++
++ /* ensure we turn the panel back on after resume */
++ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
++ GNOME_RR_DPMS_ON,
++ &error);
++ if (!ret) {
++ g_warning ("failed to turn the panel on after resume: %s",
++ error->message);
++ g_error_free (error);
++ }
++
++ lock_screensaver (manager, screen_lock_done_cb);
++}
++
++static void
++handle_resume_actions (GsdPowerManager *manager)
++{
++ gboolean ret;
++ GError *error = NULL;
++
++ /* this displays the unlock dialogue so the user doesn't have
++ * to move the mouse or press any key before the window comes up */
++ g_dbus_connection_call (manager->priv->connection,
++ GS_DBUS_NAME,
++ GS_DBUS_PATH,
++ GS_DBUS_INTERFACE,
++ "SimulateUserActivity",
++ NULL, NULL,
++ G_DBUS_CALL_FLAGS_NONE, -1,
++ NULL, NULL, NULL);
++
++ /* close existing notifications on resume, the system power
++ * state is probably different now */
++ notify_close_if_showing (manager->priv->notification_low);
++ notify_close_if_showing (manager->priv->notification_discharging);
++
++ /* ensure we turn the panel back on after resume */
++ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
++ GNOME_RR_DPMS_ON,
++ &error);
++ if (!ret) {
++ g_warning ("failed to turn the panel on after resume: %s",
++ error->message);
++ g_error_free (error);
++ }
++
++ /* set up the delay again */
++ inhibit_suspend (manager);
++}
++
++static void
++logind_proxy_signal_cb (GDBusProxy *proxy,
++ const gchar *sender_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data)
++{
++ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
++ gboolean is_about_to_suspend;
++
++ if (g_strcmp0 (signal_name, "PrepareForSleep") != 0)
++ return;
++ g_variant_get (parameters, "(b)", &is_about_to_suspend);
++ if (is_about_to_suspend) {
++ handle_suspend_actions (manager);
++ } else {
++ handle_resume_actions (manager);
++ }
++}
++
+ gboolean
+ gsd_power_manager_start (GsdPowerManager *manager,
+ GError **error)
+@@ -3705,6 +3914,25 @@ gsd_power_manager_start (GsdPowerManager *manager,
+ g_debug ("Starting power manager");
+ gnome_settings_profile_start (NULL);
+
++ manager->priv->logind_proxy =
++ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
++ 0,
++ NULL,
++ SYSTEMD_DBUS_NAME,
++ SYSTEMD_DBUS_PATH,
++ SYSTEMD_DBUS_INTERFACE,
++ NULL,
++ error);
++ if (manager->priv->logind_proxy == NULL) {
++ g_warning ("no systemd support");
++ return FALSE;
++ }
++ g_signal_connect (manager->priv->logind_proxy, "g-signal",
++ G_CALLBACK (logind_proxy_signal_cb),
++ manager);
++ /* Set up a delay inhibitor to be informed about suspend attempts */
++ inhibit_suspend (manager);
++
+ /* track the active session */
+ manager->priv->session = gnome_settings_session_new ();
+ g_signal_connect (manager->priv->session, "notify::state",
+@@ -3719,10 +3947,6 @@ gsd_power_manager_start (GsdPowerManager *manager,
+ G_CALLBACK (engine_settings_key_changed_cb), manager);
+ manager->priv->settings_screensaver = g_settings_new ("org.gnome.desktop.screensaver");
+ manager->priv->up_client = up_client_new ();
+- g_signal_connect (manager->priv->up_client, "notify-sleep",
+- G_CALLBACK (upower_notify_sleep_cb), manager);
+- g_signal_connect (manager->priv->up_client, "notify-resume",
+- G_CALLBACK (upower_notify_resume_cb), manager);
+ manager->priv->lid_is_closed = up_client_get_lid_is_closed (manager->priv->up_client);
+ g_signal_connect (manager->priv->up_client, "device-added",
+ G_CALLBACK (engine_device_added_cb), manager);
+@@ -3836,6 +4060,9 @@ gsd_power_manager_start (GsdPowerManager *manager,
+ manager->priv->x11_screen = gnome_rr_screen_new (gdk_screen_get_default (), error);
+ if (manager->priv->x11_screen == NULL)
+ return FALSE;
++ g_signal_connect (manager->priv->x11_screen, "changed", G_CALLBACK (on_randr_event), manager);
++ /* set up initial state */
++ on_randr_event (manager->priv->x11_screen, manager);
+
+ /* ensure the default dpms timeouts are cleared */
+ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
+@@ -3865,6 +4092,11 @@ gsd_power_manager_stop (GsdPowerManager *manager)
+ {
+ g_debug ("Stopping power manager");
+
++ if (manager->priv->inhibit_lid_switch_timer_id != 0) {
++ g_source_remove (manager->priv->inhibit_lid_switch_timer_id);
++ manager->priv->inhibit_lid_switch_timer_id = 0;
++ }
++
+ if (manager->priv->bus_cancellable != NULL) {
+ g_cancellable_cancel (manager->priv->bus_cancellable);
+ g_object_unref (manager->priv->bus_cancellable);
+@@ -3876,8 +4108,6 @@ gsd_power_manager_stop (GsdPowerManager *manager)
+ manager->priv->introspection_data = NULL;
+ }
+
+- kill_lid_close_safety_timer (manager);
+-
+ g_signal_handlers_disconnect_by_data (manager->priv->up_client, manager);
+
+ g_clear_object (&manager->priv->connection);
+@@ -3885,6 +4115,19 @@ gsd_power_manager_stop (GsdPowerManager *manager)
+ g_clear_object (&manager->priv->settings);
+ g_clear_object (&manager->priv->settings_screensaver);
+ g_clear_object (&manager->priv->up_client);
++
++ if (manager->priv->inhibit_lid_switch_fd != -1) {
++ close (manager->priv->inhibit_lid_switch_fd);
++ manager->priv->inhibit_lid_switch_fd = -1;
++ manager->priv->inhibit_lid_switch_taken = FALSE;
++ }
++ if (manager->priv->inhibit_suspend_fd != -1) {
++ close (manager->priv->inhibit_suspend_fd);
++ manager->priv->inhibit_suspend_fd = -1;
++ manager->priv->inhibit_suspend_taken = FALSE;
++ }
++
++ g_clear_object (&manager->priv->logind_proxy);
+ g_clear_object (&manager->priv->x11_screen);
+
+ g_ptr_array_unref (manager->priv->devices_array);
+@@ -3918,6 +4161,8 @@ static void
+ gsd_power_manager_init (GsdPowerManager *manager)
+ {
+ manager->priv = GSD_POWER_MANAGER_GET_PRIVATE (manager);
++ manager->priv->inhibit_lid_switch_fd = -1;
++ manager->priv->inhibit_suspend_fd = -1;
+ }
+
+ static void
+--
+1.7.12.2
+
diff --git a/community/gnome-settings-daemon-updates/PKGBUILD b/community/gnome-settings-daemon-updates/PKGBUILD
index 02308740b..dd06076c5 100644
--- a/community/gnome-settings-daemon-updates/PKGBUILD
+++ b/community/gnome-settings-daemon-updates/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id: PKGBUILD 70738 2012-05-16 07:55:23Z jconder $
+# $Id: PKGBUILD 79121 2012-10-30 23:06:37Z heftig $
# Maintainer: Jonathan Conder <jonno.conder@gmail.com>
_pkgname=gnome-settings-daemon
pkgname=$_pkgname-updates
-pkgver=3.4.2
+pkgver=3.6.1
pkgrel=1
pkgdesc="Updates plugin for the GNOME Settings daemon"
arch=('i686' 'x86_64')
@@ -14,24 +14,29 @@ options=('!emptydirs' '!libtool')
install=$_pkgname.install
url="http://www.gnome.org"
source=("http://ftp.gnome.org/pub/gnome/sources/$_pkgname/${pkgver%.*}/$_pkgname-$pkgver.tar.xz"
- 'systemd-fallback.patch'
+ 'screensaver.patch'
+ '0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch'
'arch.patch')
-sha256sums=('00499118c80474981f3389ef518e2d001f1b1a3b1fb78e54859d59f3bee38ff4'
- '82b721d0e274af15ed2770052d550d3162d2d37e5e9ee5e6fcebac1ed6cb8199'
- '727ab3e8181464af32ba604b2931b77cd6d4fbf34e10bbba99bb213eb992466e')
+sha256sums=('1fe96e0709d7c618d90cc1bfcddc46eede3c2cdb305f5e7f4cb388d43dd5526a'
+ 'd2c32fa0262e4d0e97fc07fb631ad2627b4f2ae273e2cb3028236d9725711880'
+ 'f23db348593f58da755889928d7fa75817479d9ad5be67cc7a2f8cbc5db23632'
+ '32f18a02698bb24aa8ae293eb7bf74a8261e3ce2c5149d259a87bd14500089ea')
build() {
cd "$srcdir/$_pkgname-$pkgver"
+ patch -Np1 -i "$srcdir/screensaver.patch"
+ patch -Np1 -i "$srcdir/0001-power-and-media-keys-Use-logind-for-suspending-and-r.patch"
patch -Np1 -i "$srcdir/arch.patch"
- patch -Np1 -i "$srcdir/systemd-fallback.patch"
- gnome-autogen.sh --prefix=/usr \
+ aclocal
+ automake
+ ./configure --prefix=/usr \
--sysconfdir=/etc \
- --localstatedir=/var \
- --libexecdir=/usr/lib/gnome-settings-daemon \
- --disable-static \
- --enable-systemd
+ --localstatedir=/var \
+ --libexecdir=/usr/lib/gnome-settings-daemon \
+ --disable-static \
+ --enable-systemd
#https://bugzilla.gnome.org/show_bug.cgi?id=656231
sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
diff --git a/community/gnome-settings-daemon-updates/arch.patch b/community/gnome-settings-daemon-updates/arch.patch
index 6718e4db9..df70cd9f8 100644
--- a/community/gnome-settings-daemon-updates/arch.patch
+++ b/community/gnome-settings-daemon-updates/arch.patch
@@ -1,17 +1,17 @@
diff --git a/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in
-index c09096a..3fa4159 100644
+index 9af2718..bb45e48 100644
--- a/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in
-@@ -31,7 +31,7 @@
- <_description>Automatically download updates in the background without confirmation. Updates will be auto-downloaded when using wired network connnections, and also WiFi if 'connection-use-wifi' is enabled and mobile broadband if 'connection-use-mobile' is enabled.</_description>
+@@ -16,7 +16,7 @@
+ <_description>Use mobile broadband connections such as GSM and CDMA to check for updates.</_description>
</key>
- <key name="auto-update-type" enum="org.gnome.settings-daemon.GsdUpdateType">
-- <default>'security'</default>
-+ <default>'none'</default>
- <_summary>Automatically install these types of updates</_summary>
- <_description>Automatically install these types of updates.</_description>
+ <key name="auto-download-updates" type="b">
+- <default>true</default>
++ <default>false</default>
+ <_summary>Automatically download updates in the background without confirmation</_summary>
+ <_description>Automatically download updates in the background without confirmation. Updates will be auto-downloaded when using wired network connnections, and mobile broadband if 'connection-use-mobile' is enabled.</_description>
</key>
-@@ -56,7 +56,7 @@
+@@ -36,7 +36,7 @@
<_description>The last time we notified the user about non-critical updates. Value is in seconds since the epoch, or zero for never.</_description>
</key>
<key name="frequency-get-upgrades" type="i">
@@ -21,7 +21,7 @@ index c09096a..3fa4159 100644
<_description>How often to check for distribution upgrades. Value is in seconds.</_description>
</key>
diff --git a/plugins/updates/Makefile.am b/plugins/updates/Makefile.am
-index 9510c65..191092d 100644
+index 81c7179..6fd3534 100644
--- a/plugins/updates/Makefile.am
+++ b/plugins/updates/Makefile.am
@@ -15,7 +15,9 @@ libupdates_la_SOURCES = \
@@ -36,10 +36,10 @@ index 9510c65..191092d 100644
libupdates_la_CPPFLAGS = \
-I$(top_srcdir)/gnome-settings-daemon \
diff --git a/plugins/updates/gsd-updates-manager.c b/plugins/updates/gsd-updates-manager.c
-index 4ed046c..9842b32 100644
+index 95ee1c4..7b26c06 100644
--- a/plugins/updates/gsd-updates-manager.c
+++ b/plugins/updates/gsd-updates-manager.c
-@@ -32,6 +32,7 @@
+@@ -33,6 +33,7 @@
#include "gsd-updates-manager.h"
#include "gsd-updates-firmware.h"
#include "gsd-updates-refresh.h"
@@ -47,44 +47,41 @@ index 4ed046c..9842b32 100644
#include "gsd-updates-common.h"
#include "gnome-settings-profile.h"
-@@ -46,6 +47,7 @@ struct GsdUpdatesManagerPrivate
+@@ -47,6 +48,7 @@ struct GsdUpdatesManagerPrivate
GCancellable *cancellable;
GsdUpdatesRefresh *refresh;
GsdUpdatesFirmware *firmware;
+ GsdUpdatesWatch *watch;
+ GSettings *settings_proxy;
GSettings *settings_ftp;
GSettings *settings_gsd;
- GSettings *settings_http;
-@@ -1358,6 +1360,9 @@ gsd_updates_manager_start (GsdUpdatesManager *manager,
+@@ -1360,6 +1362,9 @@ gsd_updates_manager_start (GsdUpdatesManager *manager,
g_signal_connect (manager->priv->refresh, "get-updates",
G_CALLBACK (due_get_updates_cb), manager);
-+ /* watch transaction progress */
-+ manager->priv->watch = gsd_updates_watch_new ();
-+
- /* get http settings */
- manager->priv->settings_http = g_settings_new ("org.gnome.system.proxy.http");
- g_signal_connect (manager->priv->settings_http, "changed",
-@@ -1463,6 +1468,10 @@ gsd_updates_manager_stop (GsdUpdatesManager *manager)
- g_object_unref (manager->priv->firmware);
- manager->priv->firmware = NULL;
- }
-+ if (manager->priv->watch != NULL) {
-+ g_object_unref (manager->priv->watch);
-+ manager->priv->watch = NULL;
-+ }
- if (manager->priv->proxy_session != NULL) {
- g_object_unref (manager->priv->proxy_session);
- manager->priv->proxy_session = NULL;
++ /* watch transaction progress */
++ manager->priv->watch = gsd_updates_watch_new ();
++
+ /* get proxy settings */
+ manager->priv->settings_proxy = g_settings_new ("org.gnome.system.proxy");
+ g_signal_connect (manager->priv->settings_proxy, "changed",
+@@ -1455,6 +1460,7 @@ gsd_updates_manager_stop (GsdUpdatesManager *manager)
+ g_clear_object (&manager->priv->task);
+ g_clear_object (&manager->priv->refresh);
+ g_clear_object (&manager->priv->firmware);
++ g_clear_object (&manager->priv->watch);
+ g_clear_object (&manager->priv->proxy_session);
+ g_clear_object (&manager->priv->volume_monitor);
+ g_clear_object (&manager->priv->cancellable);
diff --git a/plugins/updates/gsd-updates-watch.c b/plugins/updates/gsd-updates-watch.c
new file mode 100644
-index 0000000..37d8778
+index 0000000..d3a0202
--- /dev/null
+++ b/plugins/updates/gsd-updates-watch.c
-@@ -0,0 +1,179 @@
+@@ -0,0 +1,186 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
-+ * Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
++ * Copyright (C) 2011-2012 Jonathan Conder <jonno.conder@gmail.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
@@ -116,160 +113,167 @@ index 0000000..37d8778
+
+struct GsdUpdatesWatchPrivate
+{
-+ PkTransactionList *tlist;
-+ PkClient *client;
++ PkTransactionList *tlist;
++ PkClient *client;
+};
+
+G_DEFINE_TYPE (GsdUpdatesWatch, gsd_updates_watch, G_TYPE_OBJECT)
+
+static void
++on_notification_closed (NotifyNotification *notification, gpointer data)
++{
++ g_object_unref (notification);
++}
++
++static void
+gsd_updates_watch_message_cb (PkMessage *item, GsdUpdatesWatch *watch)
+{
-+ NotifyNotification *notification;
-+ gchar *details = NULL;
-+ const gchar *title, *message;
-+ GError *error = NULL;
-+
-+ g_return_if_fail (PK_IS_MESSAGE (item));
-+ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
-+
-+ g_object_get (item, "details", &details, NULL);
-+ title = _("More information");
-+ message = details;
-+
-+ /* use a better title if available */
-+ if (g_str_has_prefix (details, "<b>")) {
-+ gchar *end = g_strstr_len (details, -1, "</b>\n");
-+ if (end != NULL && g_strstr_len (details, end - details, "\n") == NULL) {
-+ title = details + 3;
-+ *end = '\0';
-+ message = end + 5;
-+ }
-+ }
-+
-+ /* display a notification */
-+ notification = notify_notification_new (title, message, NULL);
-+ notify_notification_set_app_name (notification, _("Software Updates"));
-+ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
-+ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
-+
-+ if (!notify_notification_show (notification, &error)) {
-+ g_warning ("error: %s", error->message);
-+ g_error_free (error);
-+ }
-+
-+ g_free (details);
++ NotifyNotification *notification;
++ gchar *details = NULL;
++ const gchar *title, *message;
++ GError *error = NULL;
++
++ g_return_if_fail (PK_IS_MESSAGE (item));
++ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
++
++ g_object_get (item, "details", &details, NULL);
++ title = _("More information");
++ message = details;
++
++ /* use a better title if available */
++ if (g_str_has_prefix (details, "<b>")) {
++ gchar *end = g_strstr_len (details, -1, "</b>\n");
++ if (end != NULL && g_strstr_len (details, end - details, "\n") == NULL) {
++ title = details + 3;
++ *end = '\0';
++ message = end + 5;
++ }
++ }
++
++ /* display a notification */
++ notification = notify_notification_new (title, message, NULL);
++ notify_notification_set_app_name (notification, _("Software Updates"));
++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
++
++ g_signal_connect (notification, "closed", G_CALLBACK (on_notification_closed), NULL);
++ if (!notify_notification_show (notification, &error)) {
++ g_warning ("error: %s", error->message);
++ g_error_free (error);
++ }
++
++ g_free (details);
+}
+
+static void
+gsd_updates_watch_adopt_cb (PkClient *client, GAsyncResult *res, GsdUpdatesWatch *watch)
+{
-+ PkResults *results;
-+ PkProgress *progress = NULL;
-+ guint uid;
-+ GPtrArray *array;
-+ GError *error = NULL;
-+
-+ g_return_if_fail (PK_IS_CLIENT (client));
-+ g_return_if_fail (G_IS_ASYNC_RESULT (res));
-+ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
-+
-+ results = pk_client_generic_finish (client, res, &error);
-+ if (results == NULL) {
-+ g_warning ("failed to adopt: %s", error->message);
-+ g_error_free (error);
-+ goto out;
-+ }
-+
-+ g_object_get (results, "progress", &progress, NULL);
-+ g_object_get (progress, "uid", &uid, NULL);
-+
-+ /* only display messages from the same user */
-+ if (uid != getuid ()) {
-+ g_printerr ("ignoring messages\n");
-+ goto out;
-+ }
-+
-+ array = pk_results_get_message_array (results);
-+ g_ptr_array_foreach (array, (GFunc) gsd_updates_watch_message_cb, watch);
-+ g_ptr_array_unref (array);
++ PkResults *results;
++ PkProgress *progress = NULL;
++ guint uid;
++ GPtrArray *array;
++ GError *error = NULL;
++
++ g_return_if_fail (PK_IS_CLIENT (client));
++ g_return_if_fail (G_IS_ASYNC_RESULT (res));
++ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
++
++ results = pk_client_generic_finish (client, res, &error);
++ if (results == NULL) {
++ g_warning ("failed to adopt: %s", error->message);
++ g_error_free (error);
++ goto out;
++ }
++
++ g_object_get (results, "progress", &progress, NULL);
++ g_object_get (progress, "uid", &uid, NULL);
++
++ /* only display messages from the same user */
++ if (uid != getuid ()) {
++ g_printerr ("ignoring messages\n");
++ goto out;
++ }
++
++ array = pk_results_get_message_array (results);
++ g_ptr_array_foreach (array, (GFunc) gsd_updates_watch_message_cb, watch);
++ g_ptr_array_unref (array);
+
+out:
-+ if (progress != NULL) {
-+ g_object_unref (progress);
-+ }
-+ if (results != NULL) {
-+ g_object_unref (results);
-+ }
++ if (progress != NULL) {
++ g_object_unref (progress);
++ }
++ if (results != NULL) {
++ g_object_unref (results);
++ }
+}
+
+static void
+gsd_updates_watch_tlist_added_cb (PkTransactionList *tlist, const gchar *tid, GsdUpdatesWatch *watch)
+{
-+ g_return_if_fail (PK_IS_TRANSACTION_LIST (tlist));
-+ g_return_if_fail (tid != NULL);
-+ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
++ g_return_if_fail (PK_IS_TRANSACTION_LIST (tlist));
++ g_return_if_fail (tid != NULL);
++ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
+
-+ /* listen for messages */
-+ pk_client_adopt_async (watch->priv->client, tid, NULL, NULL, NULL,
-+ (GAsyncReadyCallback) gsd_updates_watch_adopt_cb, watch);
++ /* listen for messages */
++ pk_client_adopt_async (watch->priv->client, tid, NULL, NULL, NULL,
++ (GAsyncReadyCallback) gsd_updates_watch_adopt_cb, watch);
+}
+
+static void
+gsd_updates_watch_init (GsdUpdatesWatch *watch)
+{
-+ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
++ g_return_if_fail (GSD_IS_UPDATES_WATCH (watch));
+
-+ watch->priv = GSD_UPDATES_WATCH_GET_PRIVATE (watch);
-+ watch->priv->tlist = pk_transaction_list_new ();
-+ watch->priv->client = pk_client_new ();
++ watch->priv = GSD_UPDATES_WATCH_GET_PRIVATE (watch);
++ watch->priv->tlist = pk_transaction_list_new ();
++ watch->priv->client = pk_client_new ();
+
-+ g_signal_connect (watch->priv->tlist, "added",
-+ G_CALLBACK (gsd_updates_watch_tlist_added_cb), watch);
++ g_signal_connect (watch->priv->tlist, "added",
++ G_CALLBACK (gsd_updates_watch_tlist_added_cb), watch);
+}
+
+static void
+gsd_updates_watch_finalize (GObject *object)
+{
-+ GsdUpdatesWatch *watch;
++ GsdUpdatesWatch *watch;
+
-+ g_return_if_fail (GSD_IS_UPDATES_WATCH (object));
++ g_return_if_fail (GSD_IS_UPDATES_WATCH (object));
+
-+ watch = GSD_UPDATES_WATCH (object);
-+ g_return_if_fail (watch->priv != NULL);
++ watch = GSD_UPDATES_WATCH (object);
++ g_return_if_fail (watch->priv != NULL);
+
-+ if (watch->priv->tlist != NULL) {
-+ g_object_unref (watch->priv->tlist);
-+ }
-+ if (watch->priv->client != NULL) {
-+ g_object_unref (watch->priv->client);
-+ }
++ if (watch->priv->tlist != NULL) {
++ g_object_unref (watch->priv->tlist);
++ }
++ if (watch->priv->client != NULL) {
++ g_object_unref (watch->priv->client);
++ }
+
-+ G_OBJECT_CLASS (gsd_updates_watch_parent_class)->finalize (object);
++ G_OBJECT_CLASS (gsd_updates_watch_parent_class)->finalize (object);
+}
+
+GsdUpdatesWatch *
+gsd_updates_watch_new (void)
+{
-+ return GSD_UPDATES_WATCH (g_object_new (GSD_TYPE_UPDATES_WATCH, NULL));
++ return GSD_UPDATES_WATCH (g_object_new (GSD_TYPE_UPDATES_WATCH, NULL));
+}
+
+static void
+gsd_updates_watch_class_init (GsdUpdatesWatchClass *klass)
+{
-+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
-+ object_class->finalize = gsd_updates_watch_finalize;
-+ g_type_class_add_private (klass, sizeof (GsdUpdatesWatchPrivate));
++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
++ object_class->finalize = gsd_updates_watch_finalize;
++ g_type_class_add_private (klass, sizeof (GsdUpdatesWatchPrivate));
+}
diff --git a/plugins/updates/gsd-updates-watch.h b/plugins/updates/gsd-updates-watch.h
new file mode 100644
-index 0000000..d90976e
+index 0000000..439464f
--- /dev/null
+++ b/plugins/updates/gsd-updates-watch.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
-+ * Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
++ * Copyright (C) 2011-2012 Jonathan Conder <jonno.conder@gmail.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
diff --git a/community/gnome-settings-daemon-updates/gnome-settings-daemon.install b/community/gnome-settings-daemon-updates/gnome-settings-daemon.install
index 326aa98a2..f7e8c46ac 100644
--- a/community/gnome-settings-daemon-updates/gnome-settings-daemon.install
+++ b/community/gnome-settings-daemon-updates/gnome-settings-daemon.install
@@ -1,5 +1,6 @@
post_install() {
- glib-compile-schemas usr/share/glib-2.0/schemas
+ glib-compile-schemas /usr/share/glib-2.0/schemas
+ gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor
}
post_upgrade() {
diff --git a/community/gnome-settings-daemon-updates/screensaver.patch b/community/gnome-settings-daemon-updates/screensaver.patch
new file mode 100644
index 000000000..bbcfe3430
--- /dev/null
+++ b/community/gnome-settings-daemon-updates/screensaver.patch
@@ -0,0 +1,145 @@
+From b47e4019a12ac84fba31e1c631d878ce03fa3808 Mon Sep 17 00:00:00 2001
+From: Rui Matos <tiagomatos@gmail.com>
+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 <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
+--
+cgit v0.9.0.2