diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 1d88ec9661..4962aa0308 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -244,11 +244,14 @@ int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) { int manager_add_button(Manager *m, const char *name, Button **ret_button) { Button *b; + bool is_new; assert(m); assert(name); b = hashmap_get(m->buttons, name); + is_new = !b; + if (!b) { b = button_new(m, name); if (!b) @@ -258,7 +261,7 @@ int manager_add_button(Manager *m, const char *name, Button **ret_button) { if (ret_button) *ret_button = b; - return 0; + return is_new; } int manager_process_seat_device(Manager *m, sd_device *d) { @@ -328,7 +331,7 @@ int manager_process_seat_device(Manager *m, sd_device *d) { return 0; } -int manager_process_button_device(Manager *m, sd_device *d) { +int manager_process_button_device(Manager *m, sd_device *d, Button **ret_button) { const char *sysname; Button *b; int r; @@ -340,29 +343,40 @@ int manager_process_button_device(Manager *m, sd_device *d) { return r; if (device_for_action(d, SD_DEVICE_REMOVE) || - sd_device_has_current_tag(d, "power-switch") <= 0) + sd_device_has_current_tag(d, "power-switch") <= 0) { - button_free(hashmap_get(m->buttons, sysname)); - - else { - const char *sn; - - r = manager_add_button(m, sysname, &b); - if (r < 0) - return r; - - r = device_get_seat(d, &sn); - if (r < 0) - return r; - - button_set_seat(b, sn); - - r = button_open(b); - if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error - * opening the device?) let's close the button again. */ - button_free(b); + b = hashmap_get(m->buttons, sysname); + goto unwatch; } + r = manager_add_button(m, sysname, &b); + if (r < 0) + return r; + bool is_new = r > 0; + + const char *sn; + r = device_get_seat(d, &sn); + if (r < 0) + return r; + + button_set_seat(b, sn); + + r = button_open(b); + if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error + * opening the device?) let's close the button again. */ + goto unwatch; + + if (ret_button) + *ret_button = b; + + return is_new; + +unwatch: + button_free(b); + + if (ret_button) + *ret_button = NULL; + return 0; } diff --git a/src/login/logind.c b/src/login/logind.c index 5cdfc2a00d..65bc854f4e 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -236,7 +236,7 @@ static int manager_enumerate_buttons(Manager *m) { FOREACH_DEVICE(e, d) { if (device_is_processed(d) <= 0) continue; - RET_GATHER(r, manager_process_button_device(m, d)); + RET_GATHER(r, manager_process_button_device(m, d, /* ret_button= */ NULL)); } return r; @@ -739,10 +739,13 @@ static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *dev static int manager_dispatch_button_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) { Manager *m = ASSERT_PTR(userdata); + Button *b; assert(device); - manager_process_button_device(m, device); + if (manager_process_button_device(m, device, &b) > 0) + (void) button_check_switches(b); + return 0; } diff --git a/src/login/logind.h b/src/login/logind.h index 332a59f6da..4e3c15de52 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -153,7 +153,7 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **ret_user); int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret_inhibitor); int manager_process_seat_device(Manager *m, sd_device *d); -int manager_process_button_device(Manager *m, sd_device *d); +int manager_process_button_device(Manager *m, sd_device *d, Button **ret_button); int manager_spawn_autovt(Manager *m, unsigned vtnr);