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:
+36
-22
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user