summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-11-21 14:20:37 +0000
committerRichard Hughes <richard@hughsie.com>2012-11-21 14:20:43 +0000
commita95d9cdf0d1e69c171a17af7fbb8f75869cd54b9 (patch)
tree01c616c62c473f6ada1470abb6f84bf1c86b84b6
parenta15f3d83b0ffa7b05b7f3e571b60eab9785000e0 (diff)
downloadgnome-settings-daemon-a95d9cdf0d1e69c171a17af7fbb8f75869cd54b9.tar.gz
gsd-xrandr: Add new follow-lid behavior and tie gsd-power lid-close to gsd-xrandr
There are two problems in the implementation of "turn off laptop screen when lid closed", First, it is not enabled at startup. Second, it conflicts with the gsd-power option to never use external monitors with the lid closed. To fix this, unify the gsd-xrandr default-monitors-setup setting with the aforementioned gsd-power option. The default-monitors-option now has four settings. The new follow-lid mode is the default and matches earlier behavior, plus it also checks the laptop lid state at startup. The follow-lid and clone mode still turn off the laptop screen when the lid is closed, the dock and do-nothing mode leave it apart. With this in place, gsd-power does not need anymore the special option for lid-close-suspend-with-external-monitor. It can just look at the default-monitors-setup setting, and only suspend if that setting is "do-nothing". All other settings imply that you want to keep working on the external monitor.
-rw-r--r--data/gsd-enums.h3
-rw-r--r--data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in11
-rw-r--r--data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in4
-rw-r--r--plugins/power/gsd-power-manager.c35
-rw-r--r--plugins/xrandr/gsd-xrandr-manager.c18
5 files changed, 44 insertions, 27 deletions
diff --git a/data/gsd-enums.h b/data/gsd-enums.h
index 99d9fbad..8b8f2f5e 100644
--- a/data/gsd-enums.h
+++ b/data/gsd-enums.h
@@ -79,7 +79,8 @@ typedef enum
{
GSD_XRANDR_BOOT_BEHAVIOUR_DO_NOTHING,
GSD_XRANDR_BOOT_BEHAVIOUR_CLONE,
- GSD_XRANDR_BOOT_BEHAVIOUR_DOCK
+ GSD_XRANDR_BOOT_BEHAVIOUR_DOCK,
+ GSD_XRANDR_BOOT_BEHAVIOUR_FOLLOW_LID
} GsdXrandrBootBehaviour;
typedef enum
diff --git a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in
index 3d1495a5..d10f6c14 100644
--- a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in
@@ -81,17 +81,6 @@
<summary>Power button action</summary>
<description>The action to take when the system power button is pressed.</description>
</key>
- <key name="lid-close-suspend-with-external-monitor" type="b">
- <default>false</default>
- <summary>Laptop lid, when closed, will suspend even if there is an external monitor plugged in</summary>
- <description>With no external monitors plugged in, closing a laptop's lid
- will suspend the machine (as set by the lid-close-battery-action and
- lid-close-ac-action keys). By default, however, closing the lid when
- an external monitor is present will not suspend the machine, so that one can keep
- working on that monitor (e.g. for docking stations or media viewers). Set this
- key to False to keep the default behavior, or to True to suspend the laptop whenever the
- lid is closed and regardless of external monitors.</description>
- </key>
<key name="critical-battery-action" enum="org.gnome.settings-daemon.GsdPowerActionType">
<default>'hibernate'</default>
<summary>Battery critical low action</summary>
diff --git a/data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in
index 51f87bbf..f3c2dc37 100644
--- a/data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in
@@ -16,9 +16,9 @@
<_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
</key>
<key name="default-monitors-setup" enum="org.gnome.settings-daemon.GsdXrandrBootBehaviour">
- <default>'do-nothing'</default>
+ <default>'follow-lid'</default>
<_summary>Whether to turn off specific monitors after boot</_summary>
- <_description>'clone' will display the same thing on all monitors, 'dock' will switch off the internal monitor, 'do-nothing' will use the default Xorg behaviour (extend the desktop in recent versions)</_description>
+ <_description>'clone' will display the same thing on all monitors, 'dock' will switch off the internal monitor, 'do-nothing' will use the default Xorg behaviour (extend the desktop in recent versions). The default, 'follow-lid', will choose between 'do-nothing' and 'dock' depending on whether the lid is (respectively) open or closed.</_description>
</key>
</schema>
</schemalist>
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index b17ac6c0..3412dd32 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -56,6 +56,7 @@
#define UPOWER_DBUS_INTERFACE_KBDBACKLIGHT "org.freedesktop.UPower.KbdBacklight"
#define GSD_POWER_SETTINGS_SCHEMA "org.gnome.settings-daemon.plugins.power"
+#define GSD_XRANDR_SETTINGS_SCHEMA "org.gnome.settings-daemon.plugins.xrandr"
#define GSD_DBUS_SERVICE "org.gnome.SettingsDaemon"
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
@@ -159,6 +160,7 @@ struct GsdPowerManagerPrivate
gboolean lid_is_closed;
GSettings *settings;
GSettings *settings_screensaver;
+ GSettings *settings_xrandr;
UpClient *up_client;
GDBusNodeInfo *introspection_data;
GDBusConnection *connection;
@@ -2143,11 +2145,21 @@ upower_kbd_toggle (GsdPowerManager *manager,
}
static gboolean
+suspend_on_lid_close (GsdPowerManager *manager)
+{
+ GsdXrandrBootBehaviour val;
+
+ if (!external_monitor_is_connected (manager->priv->x11_screen))
+ return TRUE;
+
+ val = g_settings_get_enum (manager->priv->settings_xrandr, "default-monitors-setup");
+ return val == GSD_XRANDR_BOOT_BEHAVIOUR_DO_NOTHING;
+}
+
+static gboolean
inhibit_lid_switch_timer_cb (GsdPowerManager *manager)
{
- if (!external_monitor_is_connected (manager->priv->x11_screen) ||
- g_settings_get_boolean (manager->priv->settings,
- "lid-close-suspend-with-external-monitor")) {
+ if (suspend_on_lid_close (manager)) {
g_debug ("no external monitors for a while; uninhibiting lid close");
uninhibit_lid_switch (manager);
manager->priv->inhibit_lid_switch_timer_id = 0;
@@ -3736,6 +3748,11 @@ on_randr_event (GnomeRRScreen *screen, gpointer user_data)
{
GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
+ if (suspend_on_lid_close (manager)) {
+ restart_inhibit_lid_switch_timer (manager);
+ return;
+ }
+
/* when a second monitor is plugged in, we take the
* handle-lid-switch inhibitor lock of logind to prevent
* it from suspending.
@@ -3744,15 +3761,8 @@ on_randr_event (GnomeRRScreen *screen, gpointer user_data)
* 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);
- }
+ inhibit_lid_switch (manager);
+ setup_inhibit_lid_switch_timer (manager);
}
static gboolean
@@ -3933,6 +3943,7 @@ gsd_power_manager_start (GsdPowerManager *manager,
g_signal_connect (manager->priv->settings, "changed",
G_CALLBACK (engine_settings_key_changed_cb), manager);
manager->priv->settings_screensaver = g_settings_new ("org.gnome.desktop.screensaver");
+ manager->priv->settings_xrandr = g_settings_new (GSD_XRANDR_SETTINGS_SCHEMA);
manager->priv->up_client = up_client_new ();
manager->priv->lid_is_closed = up_client_get_lid_is_closed (manager->priv->up_client);
g_signal_connect (manager->priv->up_client, "device-added",
diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 7a8c2cf2..7b459c3d 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1126,6 +1126,14 @@ trim_rightmost_outputs_that_dont_fit_in_framebuffer (GnomeRRScreen *rr_screen, G
return applicable;
}
+static gboolean
+follow_laptop_lid(GsdXrandrManager *manager)
+{
+ GsdXrandrBootBehaviour val;
+ val = g_settings_get_enum (manager->priv->settings, CONF_KEY_DEFAULT_MONITORS_SETUP);
+ return val == GSD_XRANDR_BOOT_BEHAVIOUR_FOLLOW_LID || val == GSD_XRANDR_BOOT_BEHAVIOUR_CLONE;
+}
+
static GnomeRRConfig *
make_xinerama_setup (GsdXrandrManager *manager, GnomeRRScreen *screen)
{
@@ -1142,7 +1150,7 @@ make_xinerama_setup (GsdXrandrManager *manager, GnomeRRScreen *screen)
GnomeRROutputInfo *info = outputs[i];
if (is_laptop (screen, info)) {
- if (laptop_lid_is_closed (manager))
+ if (laptop_lid_is_closed (manager) && follow_laptop_lid (manager))
gnome_rr_output_info_set_active (info, FALSE);
else {
gnome_rr_output_info_set_primary (info, TRUE);
@@ -1867,6 +1875,12 @@ apply_default_boot_configuration (GsdXrandrManager *mgr, guint32 timestamp)
switch (boot) {
case GSD_XRANDR_BOOT_BEHAVIOUR_DO_NOTHING:
return;
+ case GSD_XRANDR_BOOT_BEHAVIOUR_FOLLOW_LID:
+ if (laptop_lid_is_closed (mgr))
+ config = make_other_setup (screen);
+ else
+ config = make_xinerama_setup (mgr, screen);
+ break;
case GSD_XRANDR_BOOT_BEHAVIOUR_CLONE:
config = make_clone_setup (mgr, screen);
break;
@@ -1993,6 +2007,8 @@ power_client_changed_cb (UpClient *client, gpointer data)
if (is_closed != priv->laptop_lid_is_closed) {
priv->laptop_lid_is_closed = is_closed;
+ if (!follow_laptop_lid(manager))
+ return;
/* Refresh the RANDR state. The lid just got opened/closed, so we can afford to
* probe the outputs right now. It will also help the case where we can't detect