diff --git a/include/modules/backlight_slider.hpp b/include/modules/backlight_slider.hpp new file mode 100644 index 00000000..437c53c4 --- /dev/null +++ b/include/modules/backlight_slider.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "ASlider.hpp" +#include "util/backlight_backend.hpp" + +namespace waybar::modules { + +class BacklightSlider : public ASlider { + public: + BacklightSlider(const std::string&, const Json::Value&); + virtual ~BacklightSlider() = default; + + void update() override; + void onValueChanged() override; + + private: + std::chrono::milliseconds interval_; + std::string preferred_device_; + util::BacklightBackend backend; +}; + +} // namespace waybar::modules \ No newline at end of file diff --git a/include/util/backlight_backend.hpp b/include/util/backlight_backend.hpp index 1f7bddc8..8dcb8958 100644 --- a/include/util/backlight_backend.hpp +++ b/include/util/backlight_backend.hpp @@ -56,9 +56,11 @@ class BacklightBackend { void set_previous_best_device(const BacklightDevice *device); - void set_brightness(std::string preferred_device, int brightness); void set_brightness(std::string preferred_device, ChangeType change_type, double step); + void set_scaled_brightness(std::string preferred_device, int brightness); + int get_scaled_brightness(std::string preferred_device); + template static void upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, udev_device *dev); diff --git a/man/waybar-backlight-slider.5.scd b/man/waybar-backlight-slider.5.scd new file mode 100644 index 00000000..55004d08 --- /dev/null +++ b/man/waybar-backlight-slider.5.scd @@ -0,0 +1,88 @@ +waybar-backlight-slider(5) + +# NAME + +waybar - backlight slider module + +# DESCRIPTION + +The *backlight slider* module displays and controls the current brightness of the default or preferred device. + +The brightness can be controlled by dragging the slider accross the bar, or clicking on a specific position. + +# CONFIGURATION + +*min*: ++ + typeof: int ++ + default: 0 ++ + The minimum volume value the slider should display and set. + +*max*: ++ + typeof: int ++ + default: 100 ++ + The maximum volume value the slider should display and set. + +*orientation*: ++ + typeof: string ++ + default: horizontal ++ + The orientation of the slider. Can be either `horizontal` or `vertical`. + +*device*: ++ + typeof: string ++ + The name of the preferred device to control. If left empty, a device will be chosen automatically. + +# EXAMPLES + +``` +"modules-right": [ + "backlight-slider", +], +"backlight/slider": { + "min": 0, + "max": 100, + "orientation": "horizontal", + "device": "intel_backlight" +} +``` + +# STYLE + +The slider is a component with multiple CSS Nodes, of which the following are exposed: + +*#backlight-slider*: ++ + Controls the style of the box *around* the slider and bar. + +*#backlight-slider slider*: ++ + Controls the style of the slider handle. + +*#backlight-slider trough*: ++ + Controls the style of the part of the bar that has not been filled. + +*#backlight-slider highlight*: ++ + Controls the style of the part of the bar that has been filled. + +## STYLE EXAMPLE + +``` +#backlight-slider slider { + min-height: 0px; + min-width: 0px; + opacity: 0; + background-image: none; + border: none; + box-shadow: none; +} + +#backlight-slider trough { + min-height: 80px; + min-width: 10px; + border-radius: 5px; + background-color: black; +} + +#backlight-slider highlight { + min-width: 10px; + border-radius: 5px; + background-color: red; +} +``` diff --git a/meson.build b/meson.build index 3e8951c5..656cac98 100644 --- a/meson.build +++ b/meson.build @@ -301,6 +301,7 @@ endif if libudev.found() and (is_linux or libepoll.found()) add_project_arguments('-DHAVE_LIBUDEV', language: 'cpp') src_files += 'src/modules/backlight.cpp' + src_files += 'src/modules/backlight_slider.cpp' src_files += 'src/util/backlight_backend.cpp' endif @@ -429,6 +430,7 @@ if scdoc.found() man_files = [ main_manpage_path, 'waybar-backlight.5.scd', + 'waybar-backlight-slider.5.scd', 'waybar-battery.5.scd', 'waybar-cava.5.scd', 'waybar-clock.5.scd', diff --git a/src/factory.cpp b/src/factory.cpp index 0358b9db..6f8d7b40 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -4,6 +4,10 @@ #include "modules/pulseaudio_slider.hpp" #endif +#ifdef HAVE_LIBUDEV +#include "modules/backlight_slider.hpp" +#endif + waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) {} waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { @@ -130,6 +134,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "backlight") { return new waybar::modules::Backlight(id, config_[name]); } + if (ref == "backlight/slider") { + return new waybar::modules::BacklightSlider(id, config_[name]); + } #endif #ifdef HAVE_LIBEVDEV if (ref == "keyboard-state") { diff --git a/src/modules/backlight_slider.cpp b/src/modules/backlight_slider.cpp new file mode 100644 index 00000000..6269dddb --- /dev/null +++ b/src/modules/backlight_slider.cpp @@ -0,0 +1,23 @@ +#include "modules/backlight_slider.hpp" + +#include "ASlider.hpp" + +namespace waybar::modules { + +BacklightSlider::BacklightSlider(const std::string& id, const Json::Value& config) + : ASlider(config, "backlight-slider", id), + interval_(config_["interval"].isUInt() ? config_["interval"].asUInt() : 1000), + preferred_device_(config["device"].isString() ? config["device"].asString() : ""), + backend(interval_, [this] { this->dp.emit(); }) {} + +void BacklightSlider::update() { + uint16_t brightness = backend.get_scaled_brightness(preferred_device_); + scale_.set_value(brightness); +} + +void BacklightSlider::onValueChanged() { + auto brightness = scale_.get_value(); + backend.set_scaled_brightness(preferred_device_, brightness); +} + +} // namespace waybar::modules \ No newline at end of file diff --git a/src/util/backlight_backend.cpp b/src/util/backlight_backend.cpp index 7123ee3a..1512103c 100644 --- a/src/util/backlight_backend.cpp +++ b/src/util/backlight_backend.cpp @@ -188,11 +188,13 @@ void BacklightBackend::set_previous_best_device(const BacklightDevice *device) { } } -void BacklightBackend::set_brightness(std::string preferred_device, int brightness) { +void BacklightBackend::set_scaled_brightness(std::string preferred_device, int brightness) { GET_BEST_DEVICE(best, (*this), preferred_device); if (best != nullptr) { - set_brightness_internal(best->name(), brightness, best->get_max()); + const auto max = best->get_max(); + const auto abs_val = static_cast(round(brightness * max / 100.0f)); + set_brightness_internal(best->name(), abs_val, best->get_max()); } } @@ -221,6 +223,16 @@ void BacklightBackend::set_brightness_internal(std::string device_name, int brig login_proxy_->call_sync("SetBrightness", call_args); } +int BacklightBackend::get_scaled_brightness(std::string preferred_device) { + GET_BEST_DEVICE(best, (*this), preferred_device); + + if (best != nullptr) { + return best->get_actual() * 100 / best->get_max(); + } + + return 0; +} + template void BacklightBackend::upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, udev_device *dev) {