logind: fix initial button state is not fetched when device is registered late (#39978)

If buttons that are not initialized from manager_startup() due to still
being processed by udev, the initial state is not checked. (commit
405be62f05)

This caused a problem which initial "close" state being not recognized
if lid switch of some system getting initialized later.
This commit is contained in:
Morgan
2025-12-07 09:48:49 +09:00
committed by GitHub
parent e2fbcee030
commit 97887d09a8
3 changed files with 42 additions and 25 deletions
+36 -22
View File
@@ -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;
}
+5 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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);