From a78f0124d2c483c7f34dcc521bcc55ca21a5c5ad Mon Sep 17 00:00:00 2001 From: Kuruyia <8174691+Kuruyia@users.noreply.github.com> Date: Wed, 1 Feb 2023 14:40:36 +0100 Subject: [PATCH 1/3] feat(backlight): add brightness control --- include/modules/backlight.hpp | 2 + man/waybar-backlight.5.scd | 13 ++++++- src/modules/backlight.cpp | 72 +++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index 81e2516..a2ce878 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -50,6 +50,8 @@ class Backlight : public ALabel { template static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev); + bool handleScroll(GdkEventScroll* e); + const std::string preferred_device_; static constexpr int EPOLL_MAX_EVENTS = 16; diff --git a/man/waybar-backlight.5.scd b/man/waybar-backlight.5.scd index 9c8ba79..ca3d922 100644 --- a/man/waybar-backlight.5.scd +++ b/man/waybar-backlight.5.scd @@ -58,16 +58,25 @@ The *backlight* module displays the current backlight level. *on-scroll-up*: ++ typeof: string ++ - Command to execute when performing a scroll up on the module. + Command to execute when performing a scroll up on the module. This replaces the default behaviour of brightness control. *on-scroll-down*: ++ typeof: string - Command to execute when performing a scroll down on the module. + Command to execute when performing a scroll down on the module. This replaces the default behaviour of brightness control. *smooth-scrolling-threshold*: ++ typeof: double Threshold to be used when scrolling. +*reverse-scrolling*: ++ + typeof: bool ++ + Option to reverse the scroll direction. + +*scroll-step*: ++ + typeof: float ++ + default: 1.0 ++ + The speed in which to change the brightness when scrolling. + # EXAMPLE: ``` diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index 77c1dc0..65eb11a 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -106,6 +106,10 @@ waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value & dp.emit(); } + // Set up scroll handler + event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Backlight::handleScroll)); + udev_thread_ = [this] { std::unique_ptr udev{udev_new()}; check_nn(udev.get(), "Udev new failed"); @@ -264,3 +268,71 @@ void waybar::modules::Backlight::enumerate_devices(ForwardIt first, ForwardIt la upsert_device(first, last, inserter, dev.get()); } } + +bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { + // Check if the user has set a custom command for scrolling + if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { + return AModule::handleScroll(e); + } + + // Check scroll direction + auto dir = AModule::getScrollDir(e); + if (dir == SCROLL_DIR::NONE) { + return true; + } + + if (config_["reverse-scrolling"].asBool()) { + if (dir == SCROLL_DIR::UP) { + dir = SCROLL_DIR::DOWN; + } else if (dir == SCROLL_DIR::DOWN) { + dir = SCROLL_DIR::UP; + } + } + + // Get scroll step + double step = 1; + + if (config_["scroll-step"].isDouble()) { + step = config_["scroll-step"].asDouble(); + } + + // Get the best device + decltype(devices_) devices; + { + std::scoped_lock lock(udev_thread_mutex_); + devices = devices_; + } + const auto best = best_device(devices.cbegin(), devices.cend(), preferred_device_); + + if (best == nullptr) { + return true; + } + + // Compute the absolute step + const auto abs_step = static_cast(round(step * best->get_max() / 100.0f)); + + // Compute the new value + int new_value = best->get_actual(); + + if (dir == SCROLL_DIR::UP) { + new_value += abs_step; + } else if (dir == SCROLL_DIR::DOWN) { + new_value -= abs_step; + } + + // Clamp the value + new_value = std::clamp(new_value, 0, best->get_max()); + + // Get a udev instance + std::unique_ptr udev{udev_new()}; + check_nn(udev.get(), "Udev new failed"); + + // Get the udev device + std::unique_ptr dev{udev_device_new_from_subsystem_sysname(udev.get(), "backlight", std::string(best->name()).c_str())}; + check_nn(dev.get(), "Udev device new failed"); + + // Set the new value + udev_device_set_sysattr_value(dev.get(), "brightness", std::to_string(new_value).c_str()); + + return true; +} From e8c4b85328f6fb6b8a250db6709595af6cca3bfb Mon Sep 17 00:00:00 2001 From: Kuruyia <8174691+Kuruyia@users.noreply.github.com> Date: Fri, 3 Feb 2023 12:58:52 +0100 Subject: [PATCH 2/3] feat(backlight): use dbus to set the brightness --- include/modules/backlight.hpp | 3 +++ src/modules/backlight.cpp | 21 ++++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index a2ce878..1882a83 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -6,6 +6,7 @@ #include #include "ALabel.hpp" +#include "giomm/dbusproxy.h" #include "util/json.hpp" #include "util/sleeper_thread.hpp" @@ -62,5 +63,7 @@ class Backlight : public ALabel { std::vector devices_; // thread must destruct before shared data util::SleeperThread udev_thread_; + + Glib::RefPtr login_proxy_; }; } // namespace waybar::modules diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index 65eb11a..7aa5889 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -110,6 +110,11 @@ waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value & event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Backlight::handleScroll)); + // Connect to the login interface + login_proxy_ = Gio::DBus::Proxy::create_for_bus_sync( + Gio::DBus::BusType::BUS_TYPE_SYSTEM, "org.freedesktop.login1", + "/org/freedesktop/login1/session/self", "org.freedesktop.login1.Session"); + udev_thread_ = [this] { std::unique_ptr udev{udev_new()}; check_nn(udev.get(), "Udev new failed"); @@ -275,6 +280,11 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { return AModule::handleScroll(e); } + // Fail fast if the proxy could not be initialized + if (!login_proxy_) { + return true; + } + // Check scroll direction auto dir = AModule::getScrollDir(e); if (dir == SCROLL_DIR::NONE) { @@ -323,16 +333,9 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { // Clamp the value new_value = std::clamp(new_value, 0, best->get_max()); - // Get a udev instance - std::unique_ptr udev{udev_new()}; - check_nn(udev.get(), "Udev new failed"); - - // Get the udev device - std::unique_ptr dev{udev_device_new_from_subsystem_sysname(udev.get(), "backlight", std::string(best->name()).c_str())}; - check_nn(dev.get(), "Udev device new failed"); - // Set the new value - udev_device_set_sysattr_value(dev.get(), "brightness", std::to_string(new_value).c_str()); + auto call_args = Glib::VariantContainerBase(g_variant_new("(ssu)", "backlight", std::string(best->name()).c_str(), new_value)); + login_proxy_->call_sync("SetBrightness", call_args); return true; } From 973aa09f8bfbb24f630698329a51343b5e604d36 Mon Sep 17 00:00:00 2001 From: Kuruyia <8174691+Kuruyia@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:18:44 +0100 Subject: [PATCH 3/3] refactor(backlight): fix linter --- src/modules/backlight.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index 7aa5889..a46b296 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -325,16 +325,18 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { int new_value = best->get_actual(); if (dir == SCROLL_DIR::UP) { - new_value += abs_step; + new_value += abs_step; } else if (dir == SCROLL_DIR::DOWN) { - new_value -= abs_step; + new_value -= abs_step; } // Clamp the value new_value = std::clamp(new_value, 0, best->get_max()); // Set the new value - auto call_args = Glib::VariantContainerBase(g_variant_new("(ssu)", "backlight", std::string(best->name()).c_str(), new_value)); + auto call_args = Glib::VariantContainerBase( + g_variant_new("(ssu)", "backlight", std::string(best->name()).c_str(), new_value)); + login_proxy_->call_sync("SetBrightness", call_args); return true;