diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-02-21 21:10:00 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-02-21 21:13:53 +0100 |
commit | ed4ba7e4f652150310d062ffbdfefb4521ce1054 (patch) | |
tree | efe82ddb0c91dac49e752e91fe6e500731a7cfd6 /src/login/logind.c | |
parent | 6e9feda30d6d5c4aa9908d458c92eb0daf90eb3a (diff) |
logind: when we wake up from suspend and the lid is still closed, go to sleep immediately again
This is quite useful on laptops such as the Lenovo Yoga, where the power
button is placed on the front side of the laptop and can be pressed by
accident even if the lid is closed.
This reworks a bit of the logind logic to repeatedly try to suspend the
system as long as a lid is closed. We use the new "post" event source
for this, so that we don't keep things busy.
This also adds some code to check the lid status on boot, so that a
powered-off machine that is accidentaly powered on goes into suspend
immediately.
Yay! From now on I can put my Yoga safely in my backpack without fearing
that it might turn itself on and drain the battery.
Diffstat (limited to 'src/login/logind.c')
-rw-r--r-- | src/login/logind.c | 55 |
1 files changed, 16 insertions, 39 deletions
diff --git a/src/login/logind.c b/src/login/logind.c index 28d7058fe2..9cbd9e817f 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -73,32 +73,28 @@ Manager *manager_new(void) { m->busnames = set_new(string_hash_func, string_compare_func); if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames || - !m->user_units || !m->session_units) { - manager_free(m); - return NULL; - } + !m->user_units || !m->session_units) + goto fail; m->kill_exclude_users = strv_new("root", NULL); - if (!m->kill_exclude_users) { - manager_free(m); - return NULL; - } + if (!m->kill_exclude_users) + goto fail; m->udev = udev_new(); - if (!m->udev) { - manager_free(m); - return NULL; - } + if (!m->udev) + goto fail; r = sd_event_default(&m->event); - if (r < 0) { - manager_free(m); - return NULL; - } + if (r < 0) + goto fail; sd_event_set_watchdog(m->event, true); return m; + +fail: + manager_free(m); + return NULL; } void manager_free(Manager *m) { @@ -968,6 +964,7 @@ int manager_startup(Manager *m) { Seat *seat; Session *session; User *user; + Button *button; Inhibitor *inhibitor; Iterator i; @@ -1041,31 +1038,14 @@ int manager_startup(Manager *m) { HASHMAP_FOREACH(inhibitor, m->inhibitors, i) inhibitor_start(inhibitor); + HASHMAP_FOREACH(button, m->buttons, i) + button_check_lid(button); + manager_dispatch_idle_action(NULL, 0, m); return 0; } -static int manager_recheck_buttons(Manager *m) { - Iterator i; - Button *b; - int r = 0; - - assert(m); - - HASHMAP_FOREACH(b, m->buttons, i) { - int q; - - q = button_recheck(b); - if (q > 0) - return 1; - if (q < 0) - r = q; - } - - return r; -} - int manager_run(Manager *m) { int r; @@ -1085,9 +1065,6 @@ int manager_run(Manager *m) { if (manager_dispatch_delayed(m) > 0) continue; - if (manager_recheck_buttons(m) > 0) - continue; - if (m->action_what != 0 && !m->action_job) { usec_t x, y; |