Merge pull request #5163 from Alexays/fix-2215

fix(keyboard-state): read lock LEDs from all devices, not just the first
This commit is contained in:
Alexis Rouillard
2026-07-04 12:53:02 +02:00
committed by GitHub
+32 -23
View File
@@ -297,31 +297,40 @@ auto waybar::modules::KeyboardState::update() -> void {
sleep(0); // Wait for keyboard status change sleep(0); // Wait for keyboard status change
int numl = 0, capsl = 0, scrolll = 0; int numl = 0, capsl = 0, scrolll = 0;
try { std::vector<std::string> dev_paths;
std::string dev_path; {
{ std::lock_guard<std::mutex> lock(devices_mutex_);
std::lock_guard<std::mutex> lock(devices_mutex_); if (libinput_devices_.empty()) {
if (libinput_devices_.empty()) { return;
return; }
} if (config_["device-path"].isString() &&
if (config_["device-path"].isString() && libinput_devices_.find(config_["device-path"].asString()) != libinput_devices_.end()) {
libinput_devices_.find(config_["device-path"].asString()) != libinput_devices_.end()) { // An explicit device was configured: read lock state from just that device.
dev_path = config_["device-path"].asString(); dev_paths.push_back(config_["device-path"].asString());
} else { } else {
dev_path = libinput_devices_.begin()->first; // No explicit device: a multi-node keyboard may expose several event
// devices where only one of them actually toggles the lock LEDs. OR the
// LED values across all devices so a lock is reported on if any device
// reports it on.
for (const auto& [dev_path, _] : libinput_devices_) {
dev_paths.push_back(dev_path);
} }
} }
int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY); }
auto dev = openDevice(fd); for (const auto& dev_path : dev_paths) {
numl = libevdev_get_event_value(dev, EV_LED, LED_NUML); try {
capsl = libevdev_get_event_value(dev, EV_LED, LED_CAPSL); int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
scrolll = libevdev_get_event_value(dev, EV_LED, LED_SCROLLL); auto dev = openDevice(fd);
libevdev_free(dev); numl |= libevdev_get_event_value(dev, EV_LED, LED_NUML);
closeFile(fd); capsl |= libevdev_get_event_value(dev, EV_LED, LED_CAPSL);
} catch (const errno_error& e) { scrolll |= libevdev_get_event_value(dev, EV_LED, LED_SCROLLL);
// ENOTTY just means the device isn't an evdev device, skip it libevdev_free(dev);
if (e.code != ENOTTY) { closeFile(fd);
spdlog::warn(e.what()); } catch (const errno_error& e) {
// ENOTTY just means the device isn't an evdev device, skip it
if (e.code != ENOTTY) {
spdlog::warn(e.what());
}
} }
} }