From 4f24f8eec454df1e8a5d49f7985ff12b7809a1c8 Mon Sep 17 00:00:00 2001 From: Keyu Tao Date: Sun, 14 Jan 2024 06:40:26 +0800 Subject: [PATCH] power: Remove lid switch system inhibitor logind by default has HandleLidSwitchDocked set to "ignore", which is what gsd-power lid switch inhibitor is exactly doing with external display. This commit removes this inhibitor to offload the task to logind, and allows users to adjust the configuration through logind config file. Related to #111. --- plugins/power/gsd-power-manager.c | 187 ++---------------------------- plugins/power/test.py | 61 ---------- 2 files changed, 10 insertions(+), 238 deletions(-) diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c index 268a46cc5..99ef684b9 100644 --- a/plugins/power/gsd-power-manager.c +++ b/plugins/power/gsd-power-manager.c @@ -234,9 +234,6 @@ static void gsd_power_manager_init (GsdPowerManager *power_manag static void engine_device_warning_changed_cb (UpDevice *device, GParamSpec *pspec, GsdPowerManager *manager); static void do_power_action_type (GsdPowerManager *manager, GsdPowerActionType action_type); -static void uninhibit_lid_switch (GsdPowerManager *manager); -static void stop_inhibit_lid_switch_timer (GsdPowerManager *manager); -static void sync_lid_inhibitor (GsdPowerManager *manager); static void main_battery_or_ups_low_changed (GsdPowerManager *manager, gboolean is_low); static gboolean idle_is_session_inhibited (GsdPowerManager *manager, GsmInhibitorFlag mask, gboolean *is_inhibited); static void idle_triggered_idle_cb (GnomeIdleMonitor *monitor, guint watch_id, gpointer user_data); @@ -1429,63 +1426,6 @@ upower_kbd_toggle (GsdPowerManager *manager, return -1; } -static gboolean -suspend_on_lid_close (GsdPowerManager *manager) -{ - return !external_monitor_is_connected (manager->rr_screen) || !manager->session_is_active; -} - -static gboolean -inhibit_lid_switch_timer_cb (GsdPowerManager *manager) -{ - stop_inhibit_lid_switch_timer (manager); - - if (suspend_on_lid_close (manager)) { - g_debug ("no external monitors or session inactive for a while; uninhibiting lid close"); - uninhibit_lid_switch (manager); - } - - /* This is a one shot timer. */ - return G_SOURCE_REMOVE; -} - -/* Sets up a timer to be triggered some seconds after closing the laptop lid - * when the laptop is *not* suspended for some reason. We'll check conditions - * again in the timeout handler to see if we can suspend then. - */ -static void -setup_inhibit_lid_switch_timer (GsdPowerManager *manager) -{ - if (manager->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->inhibit_lid_switch_timer_id = g_timeout_add_seconds (LID_CLOSE_SAFETY_TIMEOUT, - (GSourceFunc) inhibit_lid_switch_timer_cb, - manager); - g_source_set_name_by_id (manager->inhibit_lid_switch_timer_id, "[GsdPowerManager] lid close safety timer"); -} - -static void -stop_inhibit_lid_switch_timer (GsdPowerManager *manager) { - if (manager->inhibit_lid_switch_timer_id != 0) { - g_debug ("stopping lid close safety timer"); - g_source_remove (manager->inhibit_lid_switch_timer_id); - manager->inhibit_lid_switch_timer_id = 0; - } -} - -static void -restart_inhibit_lid_switch_timer (GsdPowerManager *manager) -{ - stop_inhibit_lid_switch_timer (manager); - g_debug ("restarting lid close safety timer"); - setup_inhibit_lid_switch_timer (manager); -} - static void do_lid_open_action (GsdPowerManager *manager) { @@ -1523,6 +1463,8 @@ lock_screensaver (GsdPowerManager *manager) static void do_lid_closed_action (GsdPowerManager *manager) { + gboolean is_inhibited; + /* play a sound, using sounds from the naming spec */ ca_context_play (ca_gtk_context_get (), 0, CA_PROP_EVENT_ID, "lid-close", @@ -1530,21 +1472,14 @@ do_lid_closed_action (GsdPowerManager *manager) CA_PROP_EVENT_DESCRIPTION, _("Lid has been closed"), NULL); - /* refresh RANDR so we get an accurate view of what monitors are plugged in when the lid is closed */ - gnome_rr_screen_refresh (manager->rr_screen, NULL); /* NULL-GError */ - - if (suspend_on_lid_close (manager)) { - gboolean is_inhibited; - - idle_is_session_inhibited (manager, - GSM_INHIBITOR_FLAG_SUSPEND, - &is_inhibited); - if (is_inhibited) { - g_debug ("Suspend is inhibited but lid is closed, locking the screen"); - /* We put the screensaver on * as we're not suspending, - * but the lid is closed */ - lock_screensaver (manager); - } + idle_is_session_inhibited (manager, + GSM_INHIBITOR_FLAG_SUSPEND, + &is_inhibited); + if (is_inhibited) { + g_debug ("Suspend is inhibited but lid is closed, locking the screen"); + /* We put the screensaver on * as we're not suspending, + * but the lid is closed */ + lock_screensaver (manager); } } @@ -2604,8 +2539,6 @@ engine_session_properties_changed_cb (GDBusProxy *session, iio_proxy_claim_light (manager, FALSE); } g_variant_unref (v); - - sync_lid_inhibitor (manager); } v = g_variant_lookup_value (changed, "InhibitedActions", G_VARIANT_TYPE_UINT32); @@ -2616,76 +2549,6 @@ engine_session_properties_changed_cb (GDBusProxy *session, } } -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->inhibit_lid_switch_fd = g_unix_fd_list_get (fd_list, idx, &error); - if (manager->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->inhibit_lid_switch_fd); - g_object_unref (fd_list); - g_variant_unref (res); - } -} - -static void -inhibit_lid_switch (GsdPowerManager *manager) -{ - GVariant *params; - - if (manager->inhibit_lid_switch_taken) { - g_debug ("already inhibited lid-switch"); - return; - } - g_debug ("Adding lid switch system inhibitor"); - manager->inhibit_lid_switch_taken = TRUE; - - params = g_variant_new ("(ssss)", - "handle-lid-switch", - g_get_user_name (), - "External monitor attached or configuration changed recently", - "block"); - g_dbus_proxy_call_with_unix_fd_list (manager->logind_proxy, - "Inhibit", - params, - 0, - G_MAXINT, - NULL, - NULL, - inhibit_lid_switch_done, - manager); -} - -static void -uninhibit_lid_switch (GsdPowerManager *manager) -{ - if (manager->inhibit_lid_switch_fd == -1) { - g_debug ("no lid-switch inhibitor"); - return; - } - g_debug ("Removing lid switch system inhibitor"); - close (manager->inhibit_lid_switch_fd); - manager->inhibit_lid_switch_fd = -1; - manager->inhibit_lid_switch_taken = FALSE; -} - static void inhibit_suspend_done (GObject *source, GAsyncResult *result, @@ -2756,29 +2619,6 @@ uninhibit_suspend (GsdPowerManager *manager) manager->inhibit_suspend_taken = FALSE; } -static void -sync_lid_inhibitor (GsdPowerManager *manager) -{ - g_debug ("Syncing lid inhibitor and grabbing it temporarily"); - - /* Uninhibiting is done in inhibit_lid_switch_timer_cb, - * since we want to give users a few seconds when unplugging - * and replugging an external monitor, not suspend right away. - */ - inhibit_lid_switch (manager); - restart_inhibit_lid_switch_timer (manager); -} - -static void -on_randr_event (GnomeRRScreen *screen, gpointer user_data) -{ - GsdPowerManager *manager = GSD_POWER_MANAGER (user_data); - - g_debug ("Screen configuration changed"); - - sync_lid_inhibitor (manager); -} - static void handle_suspend_actions (GsdPowerManager *manager) { @@ -2860,13 +2700,6 @@ on_rr_screen_acquired (GObject *object, manager, 0); manager->session_is_active = is_session_active (manager); - /* set up the screens */ - if (manager->lid_is_present) { - g_signal_connect (manager->rr_screen, "changed", G_CALLBACK (on_randr_event), manager); - watch_external_monitor (manager->rr_screen); - on_randr_event (manager->rr_screen, manager); - } - manager->screensaver_proxy = gnome_settings_bus_get_screen_saver_proxy (); g_signal_connect (manager->screensaver_proxy, "g-signal", diff --git a/plugins/power/test.py b/plugins/power/test.py index 296d62879..559941cd5 100755 --- a/plugins/power/test.py +++ b/plugins/power/test.py @@ -299,29 +299,6 @@ class PowerPluginBase(gsdtestcase.GSDTestCase): self.logind_log.check_line_re(needle, timeout, failmsg='timed out waiting for logind suspend call, methods: %s' % ', '.join(methods)) - def check_for_lid_inhibited(self, timeout=0): - '''Check that the lid inhibitor has been added. - - Fail after the given timeout. - ''' - self.check_plugin_log('Adding lid switch system inhibitor', timeout, - 'Timed out waiting for lid inhibitor') - - def check_for_lid_uninhibited(self, timeout=0): - '''Check that the lid inhibitor has been dropped. - - Fail after the given timeout. - ''' - self.check_plugin_log('uninhibiting lid close', timeout, - 'Timed out waiting for lid uninhibition') - - def check_no_lid_uninhibited(self, timeout=0): - '''Check that the lid inhibitor has been dropped. - - Fail after the given timeout. - ''' - self.plugin_log.check_no_line(b'uninhibiting lid close', wait=timeout) - def check_no_suspend(self, seconds, methods=COMMON_SUSPEND_METHODS): '''Check that no Suspend or Hibernate is requested in the given time''' @@ -621,9 +598,6 @@ class PowerPluginTest4(PowerPluginBase): dbus.UInt32(gsdpowerenums.GSM_INHIBITOR_FLAG_SUSPEND), dbus_interface='org.gnome.SessionManager') - # Wait for startup inhibition to be gone - self.check_for_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 2) - # Close the lid self.obj_upower.Set('org.freedesktop.UPower', 'LidIsClosed', True) self.obj_upower.EmitSignal('', 'Changed', '', [], dbus_interface='org.freedesktop.DBus.Mock') @@ -649,9 +623,6 @@ class PowerPluginTest4(PowerPluginBase): dbus.UInt32(gsdpowerenums.GSM_INHIBITOR_FLAG_SUSPEND), dbus_interface='org.gnome.SessionManager') - # Wait for startup inhibition to be gone - self.check_for_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 2) - # Close the lid self.obj_upower.Set('org.freedesktop.UPower', 'LidIsClosed', True) self.obj_upower.EmitSignal('', 'Changed', '', [], dbus_interface='org.freedesktop.DBus.Mock') @@ -674,9 +645,6 @@ class PowerPluginTest4(PowerPluginBase): dbus.UInt32(gsdpowerenums.GSM_INHIBITOR_FLAG_SUSPEND), dbus_interface='org.gnome.SessionManager') - # Wait for startup inhibition to be gone - self.check_for_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 2) - # Close the lid self.obj_upower.Set('org.freedesktop.UPower', 'LidIsClosed', True) self.obj_upower.EmitSignal('', 'Changed', '', [], dbus_interface='org.freedesktop.DBus.Mock') @@ -699,9 +667,6 @@ class PowerPluginTest5(PowerPluginBase): def test_dim(self): '''Check that we do go to dim''' - # Wait for startup inhibition to be gone - self.check_for_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 2) - idle_delay = math.ceil(gsdpowerconstants.MINIMUM_IDLE_DIM_DELAY / gsdpowerconstants.IDLE_DELAY_TO_IDLE_DIM_MULTIPLIER) self.reset_idle_timer() @@ -744,32 +709,6 @@ class PowerPluginTest5(PowerPluginBase): if not self.skip_sysfs_backlight: self.assertTrue(self.get_brightness() == gsdpowerconstants.GSD_MOCK_DEFAULT_BRIGHTNESS , 'incorrect unblanked brightness (%d != %d)' % (self.get_brightness(), gsdpowerconstants.GSD_MOCK_DEFAULT_BRIGHTNESS)) - def test_lid_close_inhibition(self): - '''Check that we correctly inhibit suspend with an external monitor''' - - # Wait for startup inhibition to be gone - self.check_for_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 2) - - # Add an external monitor - self.set_has_external_monitor(True) - self.check_for_lid_inhibited(1) - - # Check that we do not uninhibit with the external monitor attached - self.check_no_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT + 1) - - # Close the lid - self.obj_upower.Set('org.freedesktop.UPower', 'LidIsClosed', True) - self.obj_upower.EmitSignal('', 'Changed', '', [], dbus_interface='org.freedesktop.DBus.Mock') - time.sleep(0.5) - - # Unplug the external monitor - self.set_has_external_monitor(False) - - # Check that no action happens during the safety time minus 1 second - self.check_no_lid_uninhibited(gsdpowerconstants.LID_CLOSE_SAFETY_TIMEOUT - 1) - # Check that we're uninhibited after the safety time - self.check_for_lid_uninhibited(4) - class PowerPluginTest6(PowerPluginBase): def test_notify_critical_battery(self): '''action on critical battery''' -- GitLab