From 52ec8abc448771990ce535d6eb3ab70728b0f387 Mon Sep 17 00:00:00 2001 From: Morgan Date: Thu, 4 Dec 2025 11:20:38 +0900 Subject: [PATCH] logind: fetch initial button state when device is registered late If buttons that are not initialized from startup due to still being processed by udev, the initial state is not checked. --- src/login/logind-core.c | 56 +++++++++++++++++++++++++---------------- src/login/logind.c | 12 +++++++-- src/login/logind.h | 2 +- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 1d88ec9661..3b62eafe52 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -328,8 +328,8 @@ int manager_process_seat_device(Manager *m, sd_device *d) { return 0; } -int manager_process_button_device(Manager *m, sd_device *d) { - const char *sysname; +int manager_process_button_device(Manager *m, sd_device *d, Button **ret_button) { + const char *sysname, *sn; Button *b; int r; @@ -340,29 +340,43 @@ 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); + goto no_match; } + b = hashmap_get(m->buttons, sysname); + if (b) + goto no_match; + + 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); + goto no_match; + } + + if (ret_button) + *ret_button = b; + + return 1; + +no_match: + if (ret_button) + *ret_button = NULL; + return 0; } diff --git a/src/login/logind.c b/src/login/logind.c index 5cdfc2a00d..62757cabf0 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,18 @@ 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; + int r; assert(device); - manager_process_button_device(m, device); + r = manager_process_button_device(m, device, &b); + if (r < 0) + return 0; + + if (r > 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);