Alexays / Waybar

Highly customizable Wayland bar for Sway and Wlroots based compositors. :v: :tada:
MIT License
6.42k stars 696 forks source link

Exponential backlight control #3134

Open LRitzdorf opened 5 months ago

LRitzdorf commented 5 months ago

Many third-party brightness utilities (for example, brightnessctl) support exponential backlight control, which more accurately represents perceived brightness. As far as I can see from the docs, Waybar's backlight module doesn't currently support this.

I realize this can be accomplished with a custom module and one of the aforementioned CLI utilities, but it'd be far more convenient if exponential scaling were an option for the native backlight module. Is there a possibility that this could be added?

ordy commented 5 months ago

Technically yes it could be done in here:

https://github.com/Alexays/Waybar/blob/e8038ef9f3d85f41821a93fcc6de3310ececab2c/src/modules/backlight.cpp#L108-L115

Before calling the set_brightness function we'd have to calculate the scroll-step to match an exponential curve or whatever formula other tools use to represent the perceived brightness. And then add a new config entry to the backlight module.

tirsek commented 3 months ago

I've encountered this as well, although in a slightly different way. On my system, I get an error if I try to control the brightness using waybar, but that's not an issue for me ‒ I use WM keybindings for that anyway. I still have a problem with the displayed percentage not following the logarithmic or exponential curve. For the time being, I've fixed that this way:

diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp
index 110cd434..5aedf29f 100644
--- a/include/modules/backlight.hpp
+++ b/include/modules/backlight.hpp
@@ -24,6 +24,7 @@ class Backlight : public ALabel {
   bool handleScroll(GdkEventScroll *e) override;

   const std::string preferred_device_;
+  bool logarithmic_;

   std::string previous_format_;

diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp
index 4ae511eb..5366f83c 100644
--- a/src/modules/backlight.cpp
+++ b/src/modules/backlight.cpp
@@ -8,6 +8,7 @@

 #include <algorithm>
 #include <chrono>
+#include <cmath>
 #include <memory>

 #include "util/backend_common.hpp"
@@ -16,6 +17,7 @@
 waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config)
     : ALabel(config, "backlight", id, "{percent}%", 2),
       preferred_device_(config["device"].isString() ? config["device"].asString() : ""),
+      logarithmic_(config["logarithmic"].isBool() ? config["logarithmic"].asBool() : false),
       backend(interval_, [this] { dp.emit(); }) {
   dp.emit();

@@ -36,8 +38,13 @@ auto waybar::modules::Backlight::update() -> void {

     if (best->get_powered()) {
       event_box_.show();
+      const int actual = best->get_actual();
+      const int max = best->get_max();
       const uint8_t percent =
-          best->get_max() == 0 ? 100 : round(best->get_actual() * 100.0f / best->get_max());
+          max == 0 ? 100 : actual == 0 ? 0 : round(
+              logarithmic_ ? log(actual) * 100.0f / log(max)
+                           : actual * 100.0f / max
+          );
       std::string desc = fmt::format(fmt::runtime(format_), fmt::arg("percent", percent),
                                      fmt::arg("icon", getIcon(percent)));
       label_.set_markup(desc);

... and then adding a "logarithmic": true key to the backlight module of the waybar config file.

I know this in an incomplete solution, especially because it does nothing to actually solve the control problem, but perhaps it can be part of a solution. I also don't know if this is the correct curve to follow, but I believe the numbers I got out of this matches what xbacklight does in "perceived brightness" mode.

Anyway, if I can solve my control problem, perhaps I can cook up a more complete suggestion at some point ... For now I just wanted to share my "works-for-me-for-now" solution.