fix(backlight): Poll if necessary

The `backlight` file seems to not receive modification events for
inotify (it does receive other events though).
These other events still trigger an update, but the value read is still
the old value because the events arrive just slightly before the file is
updated.

The new `poll-interval` setting will inject an event every X seconds to
force an update.
If the actual_brightness file is used, the interval is set to 0 and thus
turned off.

This does not add any more wakeups to the module, the inotify modules
wake up every second anyway and during that time, the interval is
checked.

Fixes #2835
This commit is contained in:
patrick96
2023-10-21 19:12:00 +02:00
committed by Patrick Ziegler
parent 278584fa27
commit aebdb5328a
3 changed files with 57 additions and 11 deletions

View File

@ -72,6 +72,9 @@ namespace modules {
m_use_actual_brightness = m_conf.get(name(), "use-actual-brightness", m_use_actual_brightness);
m_interval = m_conf.get<decltype(m_interval)>(name(), "poll-interval", m_use_actual_brightness? 0s : 5s);
m_lastpoll = chrono::steady_clock::now();
std::string brightness_type = (m_use_actual_brightness ? "actual_brightness" : "brightness");
auto path_backlight_val = m_path_backlight + "/" + brightness_type;
@ -83,23 +86,48 @@ namespace modules {
}
void backlight_module::idle() {
sleep(75ms);
if (m_interval.count() > 0) {
/*
* Update module after interval (if any).
* We don't always receive inotify events for the backlight files.
* Mainly, the `backlight` file never receive an event on modification.
* In that case, updating at an interval is the only way to get the new value.
*/
auto now = chrono::steady_clock::now();
if (chrono::duration_cast<decltype(m_interval)>(now - m_lastpoll) > m_interval) {
m_lastpoll = now;
if (on_event({})) {
broadcast();
}
}
}
this->inotify_module::idle();
}
bool backlight_module::on_event(const inotify_event& event) {
if (event.is_valid) {
m_log.trace("%s: %s", name(), event.filename);
m_log.trace("%s: on_event{filename: %s, is_dir: %s, wd: %d, cookie: %d, mask: 0x%x}", name(), event.filename,
event.is_dir? "true" : "false", event.wd, event.cookie, event.mask);
}
m_max_brightness = m_max.read();
m_percentage = static_cast<int>(m_val.read() / m_max_brightness * 100.0f + 0.5f);
float val = m_val.read();
int percentage = math_util::percentage(val, m_max_brightness);
if (m_label) {
m_label->reset_tokens();
m_label->replace_token("%percentage%", to_string(m_percentage));
if (m_percentage != percentage) {
m_log.trace("%s: %d%% -> %d%% (val: %f, max: %f)", name(), m_percentage, percentage, val, m_max_brightness);
m_percentage = percentage;
if (m_label) {
m_label->reset_tokens();
m_label->replace_token("%percentage%", to_string(m_percentage));
}
return true;
}
return true;
return false;
}
string backlight_module::get_output() {