summaryrefslogtreecommitdiff
path: root/src/login/logind.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-03-03 20:49:33 +0100
committerLennart Poettering <lennart@poettering.net>2014-03-03 20:57:09 +0100
commitf9cd6be10ece07e10488c05e270a0b5860779864 (patch)
treef236bd39b54c2b66276c7ac72a36cb565cf0b53e /src/login/logind.c
parent7e9110a29d90041b0364cb93a84aec9dd72363b6 (diff)
logind: ignore lid switch events for 30s after each suspend and 3min after startup
This is needed to give USB docking stations and suchlike time to settle, so that a display connected to an USB docking station can actually act as a lid swith inhibitor correctly. With this change we should have somewhat reliable docking station support in place.
Diffstat (limited to 'src/login/logind.c')
-rw-r--r--src/login/logind.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/login/logind.c b/src/login/logind.c
index 10f61aba38..fd113b3e79 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -144,6 +144,7 @@ void manager_free(Manager *m) {
sd_event_source_unref(m->udev_device_event_source);
sd_event_source_unref(m->udev_vcsa_event_source);
sd_event_source_unref(m->udev_button_event_source);
+ sd_event_source_unref(m->lid_switch_ignore_event_source);
if (m->console_active_fd >= 0)
close_nointr_nofail(m->console_active_fd);
@@ -959,6 +960,46 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
return 0;
}
+static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
+ Manager *m = userdata;
+
+ assert(e);
+ assert(m);
+
+ m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
+ return 0;
+}
+
+int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
+ int r;
+
+ assert(m);
+
+ if (until <= now(CLOCK_MONOTONIC))
+ return 0;
+
+ /* We want to ignore the lid switch for a while after each
+ * suspend, and after boot-up. Hence let's install a timer for
+ * this. As long as the event source exists we ignore the lid
+ * switch. */
+
+ if (m->lid_switch_ignore_event_source) {
+ usec_t u;
+
+ r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
+ if (r < 0)
+ return r;
+
+ if (until <= u)
+ return 0;
+
+ r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
+ } else
+ r = sd_event_add_monotonic(m->event, &m->lid_switch_ignore_event_source, until, 0, lid_switch_ignore_handler, m);
+
+ return r;
+}
+
int manager_startup(Manager *m) {
int r;
Seat *seat;
@@ -994,6 +1035,10 @@ int manager_startup(Manager *m) {
return r;
}
+ r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
+ if (r < 0)
+ log_warning("Failed to set up lid switch ignore event source: %s", strerror(-r));
+
/* Deserialize state */
r = manager_enumerate_devices(m);
if (r < 0)