Search for device automatically if none given
This commit is contained in:
parent
6fdbc27998
commit
08e886ebc6
|
@ -24,6 +24,8 @@ class KeyboardState : public AModule {
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static auto openDevice(const std::string&) -> std::pair<int, libevdev*>;
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
Gtk::Label numlock_label_;
|
Gtk::Label numlock_label_;
|
||||||
|
@ -37,7 +39,6 @@ class KeyboardState : public AModule {
|
||||||
std::string icon_locked_;
|
std::string icon_locked_;
|
||||||
std::string icon_unlocked_;
|
std::string icon_unlocked_;
|
||||||
|
|
||||||
std::string dev_path_;
|
|
||||||
int fd_;
|
int fd_;
|
||||||
libevdev* dev_;
|
libevdev* dev_;
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,12 @@
|
||||||
// },
|
// },
|
||||||
"keyboard_state": {
|
"keyboard_state": {
|
||||||
"numlock": true,
|
"numlock": true,
|
||||||
|
"capslock": true,
|
||||||
"format": "{name} {icon}",
|
"format": "{name} {icon}",
|
||||||
"format-icons": {
|
"format-icons": {
|
||||||
"locked": "",
|
"locked": "",
|
||||||
"unlocked": ""
|
"unlocked": ""
|
||||||
},
|
}
|
||||||
"capslock": true,
|
|
||||||
"device-path": "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
|
|
||||||
},
|
},
|
||||||
"sway/mode": {
|
"sway/mode": {
|
||||||
"format": "<span style=\"italic\">{}</span>"
|
"format": "<span style=\"italic\">{}</span>"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "modules/keyboard_state.hpp"
|
#include "modules/keyboard_state.hpp"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -28,8 +29,9 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar&
|
||||||
: "locked"),
|
: "locked"),
|
||||||
icon_unlocked_(config_["format-icons"]["unlocked"].isString()
|
icon_unlocked_(config_["format-icons"]["unlocked"].isString()
|
||||||
? config_["format-icons"]["unlocked"].asString()
|
? config_["format-icons"]["unlocked"].asString()
|
||||||
: "unlocked")
|
: "unlocked"),
|
||||||
{
|
fd_(0),
|
||||||
|
dev_(nullptr) {
|
||||||
box_.set_name("keyboard_state");
|
box_.set_name("keyboard_state");
|
||||||
if (config_["numlock"].asBool()) {
|
if (config_["numlock"].asBool()) {
|
||||||
box_.pack_end(numlock_label_, false, false, 0);
|
box_.pack_end(numlock_label_, false, false, 0);
|
||||||
|
@ -46,26 +48,28 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar&
|
||||||
event_box_.add(box_);
|
event_box_.add(box_);
|
||||||
|
|
||||||
if (config_["device-path"].isString()) {
|
if (config_["device-path"].isString()) {
|
||||||
dev_path_ = config_["device-path"].asString();
|
std::string dev_path = config_["device-path"].asString();
|
||||||
|
std::tie(fd_, dev_) = openDevice(dev_path);
|
||||||
} else {
|
} else {
|
||||||
dev_path_ = "";
|
DIR* dev_dir = opendir("/dev/input");
|
||||||
|
if (dev_dir == nullptr) {
|
||||||
|
throw std::runtime_error("Failed to open /dev/input");
|
||||||
}
|
}
|
||||||
|
dirent *ep;
|
||||||
fd_ = open(dev_path_.c_str(), O_NONBLOCK | O_CLOEXEC | O_RDONLY);
|
while ((ep = readdir(dev_dir))) {
|
||||||
if (fd_ < 0) {
|
if (ep->d_type != DT_CHR) continue;
|
||||||
throw std::runtime_error("Can't open " + dev_path_);
|
std::string dev_path = std::string("/dev/input/") + ep->d_name;
|
||||||
|
try {
|
||||||
|
std::tie(fd_, dev_) = openDevice(dev_path);
|
||||||
|
spdlog::info("Found device {} at '{}'", libevdev_get_name(dev_), dev_path);
|
||||||
|
break;
|
||||||
|
} catch (const std::runtime_error& e) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
int err = libevdev_new_from_fd(fd_, &dev_);
|
|
||||||
if (err < 0) {
|
|
||||||
throw std::runtime_error("Can't create libevdev device");
|
|
||||||
}
|
}
|
||||||
if (!libevdev_has_event_type(dev_, EV_LED)) {
|
if (dev_ == nullptr) {
|
||||||
throw std::runtime_error("Device doesn't support LED events");
|
throw std::runtime_error("Failed to find keyboard device");
|
||||||
}
|
}
|
||||||
if (!libevdev_has_event_code(dev_, EV_LED, LED_NUML)
|
|
||||||
|| !libevdev_has_event_code(dev_, EV_LED, LED_CAPSL)
|
|
||||||
|| !libevdev_has_event_code(dev_, EV_LED, LED_SCROLLL)) {
|
|
||||||
throw std::runtime_error("Device doesn't support num lock, caps lock, or scroll lock events");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
|
@ -82,6 +86,29 @@ waybar::modules::KeyboardState::~KeyboardState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::KeyboardState::openDevice(const std::string& path) -> std::pair<int, libevdev*> {
|
||||||
|
int fd = open(path.c_str(), O_NONBLOCK | O_CLOEXEC | O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
throw std::runtime_error("Can't open " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
libevdev* dev;
|
||||||
|
int err = libevdev_new_from_fd(fd, &dev);
|
||||||
|
if (err < 0) {
|
||||||
|
throw std::runtime_error("Can't create libevdev device");
|
||||||
|
}
|
||||||
|
if (!libevdev_has_event_type(dev, EV_LED)) {
|
||||||
|
throw std::runtime_error("Device doesn't support LED events");
|
||||||
|
}
|
||||||
|
if (!libevdev_has_event_code(dev, EV_LED, LED_NUML)
|
||||||
|
|| !libevdev_has_event_code(dev, EV_LED, LED_CAPSL)
|
||||||
|
|| !libevdev_has_event_code(dev, EV_LED, LED_SCROLLL)) {
|
||||||
|
throw std::runtime_error("Device doesn't support num lock, caps lock, or scroll lock events");
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(fd, dev);
|
||||||
|
}
|
||||||
|
|
||||||
auto waybar::modules::KeyboardState::update() -> void {
|
auto waybar::modules::KeyboardState::update() -> void {
|
||||||
int err = LIBEVDEV_READ_STATUS_SUCCESS;
|
int err = LIBEVDEV_READ_STATUS_SUCCESS;
|
||||||
while (err == LIBEVDEV_READ_STATUS_SUCCESS) {
|
while (err == LIBEVDEV_READ_STATUS_SUCCESS) {
|
||||||
|
|
Loading…
Reference in New Issue