diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-11-21 14:20:37 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2012-11-21 14:20:43 +0000 |
commit | a95d9cdf0d1e69c171a17af7fbb8f75869cd54b9 (patch) | |
tree | 01c616c62c473f6ada1470abb6f84bf1c86b84b6 | |
parent | a15f3d83b0ffa7b05b7f3e571b60eab9785000e0 (diff) | |
download | gnome-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.h | 3 | ||||
-rw-r--r-- | data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in | 11 | ||||
-rw-r--r-- | data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in | 4 | ||||
-rw-r--r-- | plugins/power/gsd-power-manager.c | 35 | ||||
-rw-r--r-- | plugins/xrandr/gsd-xrandr-manager.c | 18 |
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 |