The current inhibitors for going into suspend at lid closure are based on the
presence of a docking station, multiple or no displays and a fixed timeout
after the last suspend event.
I understand the goal to prevent an immediate suspend when the system is booted
with closed lid and other inhibitors are not yet present.

But, ignoring the lid close event for a certain time, might not give the
best user experience.
I wondering wheter we couldn't set the inhibitors in a more userfriendly way.

My approach is based on the assumption that a user only wants a suspend at lid
closure, if there was a lid open before.
If the lid was not opened before, we can IMHO savely assume that there is
another display connected or there is a docking station or the user just want
to boot without display for any reason.

If so, we could record a previous lid open event e.g. in a status file.
We could then inhibit the suspend if there was no previous lid open event or
 allow it without timeout, if there was one.

I'm attaching a little example patch to visualize my approach.
Any comment is appreciated.


Regards
Thomas Blume

--
SUSE LINUX Products GmbH GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 
16746 (AG Nürnberg)
Maxfeldstr. 5 / D-90409 Nürnberg / Phone: +49-911-740 53 - 0
GPG 2048R/2CD4D3E8 9A50 048F 1C73 59AA 4D2E  424E B3C6 3FD9 2CD4 D3E8
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 2561d13..43d645d 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -32,6 +32,8 @@
 #include "util.h"
 #include "special.h"
 #include "logind-button.h"
+#include <sys/stat.h>
+#include <sys/types.h>
 
 Button* button_new(Manager *m, const char *name) {
         Button *b;
@@ -99,11 +101,21 @@ int button_set_seat(Button *b, const char *sn) {
 
 static int button_recheck(sd_event_source *e, void *userdata) {
         Button *b = userdata;
+        struct stat st;
 
         assert(b);
         assert(b->lid_closed);
 
-        manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false);
+        if (stat("/run/systemd/systemd-lid-opened", &st) == 0) {
+                int r;
+
+                if (unlink("/run/systemd/systemd-lid-opened") < 0) {
+                        log_error("Failed to remove /run/systemd/systemd-lid-opened file: %m");
+                        r = -errno;
+                }
+                manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false);
+        }
+
         return 1;
 }
 
@@ -125,7 +137,7 @@ static int button_install_check_event_source(Button *b) {
 
 static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         Button *b = userdata;
-        struct input_event ev;
+        struct input_event ev, stat st;
         ssize_t l;
 
         assert(s);
@@ -186,7 +198,17 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
                                    NULL);
 
                         b->lid_closed = true;
-                        manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
+
+                        if (stat("/run/systemd/systemd-lid-opened", &st) == 0) {
+                                int r;
+
+                                if (unlink("/run/systemd/systemd-lid-opened") < 0) {
+                                        log_error("Failed to remove /run/systemd/systemd-lid-opened file: %m");
+                                        r = -errno;
+                                }
+                                manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
+                        }
+
                         button_install_check_event_source(b);
 
                 } else if (ev.code == SW_DOCK) {
@@ -201,12 +223,21 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
         } else if (ev.type == EV_SW && ev.value == 0) {
 
                 if (ev.code == SW_LID) {
+                        _cleanup_fclose_ FILE *f = NULL;
                         log_struct(LOG_INFO,
                                    "MESSAGE=Lid opened.",
                                    MESSAGE_ID(SD_MESSAGE_LID_OPENED),
                                    NULL);
 
                         b->lid_closed = false;
+
+                        //save lid open state
+                        f = fopen("/run/systemd/systemd-lid-opened", "we");
+                        if (!f) {
+                                log_error("Failed to write Lid state file: %m");
+                                return -errno;
+                        }
+
                         b->check_event_source = sd_event_source_unref(b->check_event_source);
 
                 } else if (ev.code == SW_DOCK) {
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to