Implement hysteresis for setting monitor brightness

This commit is contained in:
BlackMark 2022-07-22 12:35:00 +02:00
parent 77d9a22419
commit b7895d61c6
2 changed files with 32 additions and 1 deletions

View File

@ -359,6 +359,12 @@ void MainWindow::updateState()
bool MainWindow::setMonitorBrightness(float& brightness) bool MainWindow::setMonitorBrightness(float& brightness)
{ {
constexpr auto hysteresis = [](const auto& lowThreshold, const auto& highThreshold, const auto& currentValue, const auto& newValue) {
if(newValue > highThreshold || newValue < lowThreshold)
return newValue;
return currentValue;
};
if(m_monitors.empty()) { if(m_monitors.empty()) {
return false; return false;
} }
@ -367,6 +373,28 @@ bool MainWindow::setMonitorBrightness(float& brightness)
bool allMonitorsSameBrightness = true; bool allMonitorsSameBrightness = true;
for(size_t i = 0; i < m_monitors.size(); ++i) { for(size_t i = 0; i < m_monitors.size(); ++i) {
const auto updateMonitorBrightness = [&] {
const auto brightnessRange = m_monitors[i].maxBrightness - m_monitors[i].minBrightness;
const auto hysteresisDelta = m_monitors[i].manualOverride ? 0.f : m_monitors[i].HYSTERESIS_THRESHOLD * brightnessRange;
const auto lowThreshold = std::clamp(m_monitors[i].prevBrightness - hysteresisDelta, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
const auto highThreshold = std::clamp(m_monitors[i].prevBrightness + hysteresisDelta, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
if(hysteresis(lowThreshold, highThreshold, m_monitors[i].prevBrightness, m_monitors[i].brightness) != m_monitors[i].prevBrightness) {
qDebug(ltr("Setting monitor %1 brightness from %2 to %3")
.arg(i)
.arg(m_monitors[i].prevBrightness, 0, 'f', 2)
.arg(m_monitors[i].brightness, 0, 'f', 2));
m_monitors[i].prevBrightness = m_monitors[i].brightness;
return m_monitors[i].driver.setBrightness(m_monitors[i].brightness);
}
else {
qDebug(ltr("Hysteresis prevented setting monitor %1 brightness from %2 to %3")
.arg(i)
.arg(m_monitors[i].prevBrightness, 0, 'f', 2)
.arg(m_monitors[i].brightness, 0, 'f', 2));
}
return true;
};
if(!std::isnan(brightness) && !m_monitors[i].manualOverride) { if(!std::isnan(brightness) && !m_monitors[i].manualOverride) {
m_monitors[i].brightness = brightness; m_monitors[i].brightness = brightness;
} }
@ -377,7 +405,7 @@ bool MainWindow::setMonitorBrightness(float& brightness)
allMonitorsSameBrightness = false; allMonitorsSameBrightness = false;
} }
if(!m_monitors[i].driver.setBrightness(m_monitors[i].brightness)) { if(!updateMonitorBrightness()) {
errorOccurred = true; errorOccurred = true;
} }
else if(m_ui.monitorDropdown->currentIndex() == static_cast<int>(i)) { else if(m_ui.monitorDropdown->currentIndex() == static_cast<int>(i)) {

View File

@ -75,10 +75,13 @@ class MainWindow : public QMainWindow {
}; };
struct MonitorData { struct MonitorData {
static constexpr auto HYSTERESIS_THRESHOLD = 0.05f;
Monitor driver; Monitor driver;
float minBrightness; float minBrightness;
float maxBrightness; float maxBrightness;
float brightness; float brightness;
float prevBrightness;
bool manualOverride; bool manualOverride;
}; };