Merge remote-tracking branch 'origin/master' into refactor/generic-tooltip

# Conflicts:
#	src/modules/wireplumber.cpp
This commit is contained in:
Alex
2026-07-04 00:29:26 +02:00
51 changed files with 1903 additions and 84 deletions
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <glibmm/markup.h>
#include <gtkmm/label.h>
#include <json/json.h>
#include <deque>
#include <vector>
#include "AModule.hpp"
namespace waybar {
enum class GraphType { LINE, BAR, GAUGE };
class AGraph : public AModule {
public:
AGraph(const Json::Value&, const std::string&, const std::string&, uint16_t interval = 0,
bool enable_click = false, bool enable_scroll = false);
virtual ~AGraph() = default;
auto update() -> void override;
protected:
Gtk::DrawingArea graph_;
std::deque<int> values_;
uint16_t datapoints_ = 20;
GraphType graph_type_ = GraphType::LINE;
void addValue(const int n);
const std::chrono::seconds interval_;
bool onDraw(const Cairo::RefPtr<Cairo::Context>& cr);
std::map<std::string, GtkMenuItem*> submenus_;
std::map<std::string, std::string> menuActionsMap_;
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
private:
void drawFilledArea(const Cairo::RefPtr<Cairo::Context>& cr,
const std::vector<std::pair<double, double>>& points, double height,
const Gdk::RGBA& bg_color);
void drawLine(const Cairo::RefPtr<Cairo::Context>& cr,
const std::vector<std::pair<double, double>>& points, const Gdk::RGBA& fg_color);
void drawPath(const Cairo::RefPtr<Cairo::Context>& cr,
const std::vector<std::pair<double, double>>& points);
void drawBars(const Cairo::RefPtr<Cairo::Context>& cr, double width, double height,
int current_value, const Gdk::RGBA& fg_color);
void drawGauge(const Cairo::RefPtr<Cairo::Context>& cr, double width, double height,
int current_value, const Gdk::RGBA& fg_color);
};
} // namespace waybar
+2
View File
@@ -12,6 +12,7 @@
struct zwp_idle_inhibitor_v1;
struct zwp_idle_inhibit_manager_v1;
struct ext_idle_notifier_v1;
namespace waybar {
@@ -27,6 +28,7 @@ class Client {
struct wl_registry* registry = nullptr;
struct zxdg_output_manager_v1* xdg_output_manager = nullptr;
struct zwp_idle_inhibit_manager_v1* idle_inhibit_manager = nullptr;
struct ext_idle_notifier_v1* idle_notifier = nullptr;
std::vector<std::unique_ptr<Bar>> bars;
Config config;
std::string bar_id;
+7
View File
@@ -41,6 +41,7 @@ class Bluetooth : public ALabel {
bool services_resolved;
// NOTE: experimental feature in bluez
std::optional<unsigned char> battery_percentage;
std::optional<unsigned char> battery_percentage_peripheral;
};
public:
@@ -59,6 +60,12 @@ class Bluetooth : public ALabel {
gpointer) -> void;
auto getDeviceBatteryPercentage(GDBusObject*) -> std::optional<unsigned char>;
auto getDeviceGattBatteryLevels(GDBusObject*, std::optional<unsigned char>&,
std::optional<unsigned char>&) -> void;
static auto processBatteryServiceCharacteristics(GList*, const std::string&, const std::string&,
const std::string&,
std::optional<unsigned char>&,
std::optional<unsigned char>&) -> void;
auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool;
auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool;
+4
View File
@@ -80,6 +80,7 @@ class Clock final : public ALabel {
void cldShift_reset();
void tz_up();
void tz_down();
void action_exec(const std::string& action);
// Module Action Map
static inline std::map<const std::string, void (waybar::modules::Clock::* const)()> actionMap_{
{"mode", &waybar::modules::Clock::cldModeSwitch},
@@ -88,6 +89,9 @@ class Clock final : public ALabel {
{"shift_reset", &waybar::modules::Clock::cldShift_reset},
{"tz_up", &waybar::modules::Clock::tz_up},
{"tz_down", &waybar::modules::Clock::tz_down}};
static inline std::map<const std::string,
void (waybar::modules::Clock::* const)(const std::string& action)>
actionWithArgsMap_{{"exec", &waybar::modules::Clock::action_exec}};
};
} // namespace waybar::modules
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <fmt/format.h>
#include <cstdint>
#include <fstream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
#include "AGraph.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class CpuGraph : public AGraph {
public:
CpuGraph(const std::string&, const Json::Value&);
virtual ~CpuGraph() = default;
auto update() -> void override;
private:
static constexpr const char* MODERATE_CLASS = "cpu-moderate";
static constexpr const char* HIGH_CLASS = "cpu-high";
static constexpr const char* INTENSIVE_CLASS = "cpu-intensive";
std::vector<std::tuple<size_t, size_t>> prev_times_;
util::SleeperThread thread_;
};
} // namespace waybar::modules
+5 -2
View File
@@ -5,14 +5,14 @@
#include <csignal>
#include <string>
#include "ALabel.hpp"
#include "AIconLabel.hpp"
#include "util/command.hpp"
#include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class Custom : public ALabel {
class Custom : public AIconLabel {
public:
Custom(const std::string&, const std::string&, const Json::Value&, const std::string&);
virtual ~Custom();
@@ -36,6 +36,9 @@ class Custom : public ALabel {
std::string alt_;
std::string tooltip_;
std::string last_tooltip_markup_;
std::string image_path_;
std::string image_name_;
unsigned app_icon_size_{24};
const bool tooltip_format_enabled_;
std::vector<std::string> class_;
int percentage_;
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include <fmt/format.h>
#include <csignal>
#include <string>
#include "AGraph.hpp"
#include "util/command.hpp"
#include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class CustomGraph : public AGraph {
public:
CustomGraph(const std::string&, const std::string&, const Json::Value&, const std::string&);
virtual ~CustomGraph();
auto update() -> void override;
void refresh(int /*signal*/) override;
private:
void delayWorker();
void continuousWorker();
void waitingWorker();
void parseOutputRaw();
void parseOutputJson();
void handleEvent();
bool handleScroll(GdkEventScroll* e) override;
bool handleToggle(GdkEventButton* const& e) override;
const std::string name_;
const std::string output_name_;
std::string text_;
std::string id_;
std::string alt_;
std::string tooltip_;
const bool tooltip_format_enabled_;
std::vector<std::string> class_;
int percentage_;
FILE* fp_;
int pid_;
util::command::res output_;
util::JsonParser parser_;
util::SleeperThread thread_;
};
} // namespace waybar::modules
+4
View File
@@ -64,6 +64,8 @@ class Workspaces : public AModule, public EventHandler {
std::string getRewrite(const std::string& window_class, const std::string& window_title);
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
auto windowRewriteGroupThreshold() const -> int { return m_windowRewriteGroupThreshold; }
auto const& getWindowRewriteGroupFormat() const { return m_windowRewriteGroupFormat; }
bool isWorkspaceIgnored(std::string const& workspace_name);
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
@@ -177,6 +179,8 @@ class Workspaces : public AModule, public EventHandler {
util::RegexCollection m_windowRewriteRules;
bool m_anyWindowRewriteRuleUsesTitle = false;
std::string m_formatWindowSeparator;
int m_windowRewriteGroupThreshold = 0;
std::string m_windowRewriteGroupFormat = "{icon}×{count}";
bool m_withIcon;
uint64_t m_monitorId;
+10
View File
@@ -6,25 +6,35 @@
#include "bar.hpp"
#include "client.hpp"
struct ext_idle_notification_v1;
namespace waybar::modules {
class IdleInhibitor : public ALabel {
sigc::connection timeout_;
ext_idle_notification_v1* idle_notification_;
uint32_t idle_timeout_ms_;
public:
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~IdleInhibitor();
auto update() -> void override;
auto refresh(int) -> void override;
static std::list<waybar::AModule*> modules;
static bool status;
private:
bool handleToggle(GdkEventButton* const& e) override;
void toggleStatus();
void setupIdleNotification();
void teardownIdleNotification();
static void handleIdled(void* data, ext_idle_notification_v1* notification);
static void handleResumed(void* data, ext_idle_notification_v1* notification);
const Bar& bar_;
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
int pid_;
bool wait_for_activity_;
};
} // namespace waybar::modules
+3
View File
@@ -28,6 +28,8 @@ class MPD : public ALabel {
unsigned timeout_;
unsigned playing_interval_;
detail::unique_connection connection_;
detail::unique_status status_;
@@ -63,6 +65,7 @@ class MPD : public ALabel {
inline bool stopped() const { return connection_ && state_ == MPD_STATE_STOP; }
inline bool playing() const { return connection_ && state_ == MPD_STATE_PLAY; }
inline bool paused() const { return connection_ && state_ == MPD_STATE_PAUSE; }
inline unsigned playing_interval() const { return playing_interval_; }
};
#if !defined(MPD_NOINLINE)
+1
View File
@@ -198,6 +198,7 @@ class Context {
bool is_paused() const;
bool is_stopped() const;
constexpr std::size_t interval() const;
unsigned playing_interval() const;
void tryConnect() const;
void checkErrors(mpd_connection*) const;
void do_update();
+1
View File
@@ -9,6 +9,7 @@ inline bool Context::is_paused() const { return mpd_module_->paused(); }
inline bool Context::is_stopped() const { return mpd_module_->stopped(); }
constexpr inline std::size_t Context::interval() const { return mpd_module_->interval_ / 1s; }
inline unsigned Context::playing_interval() const { return mpd_module_->playing_interval(); }
inline void Context::tryConnect() const { mpd_module_->tryConnect(); }
inline unique_connection& Context::connection() { return mpd_module_->connection_; }
constexpr inline mpd_state Context::state() const { return mpd_module_->state_; }
+1
View File
@@ -23,6 +23,7 @@ class Workspaces : public AModule, public EventHandler {
void sortWorkspaces(std::vector<Json::Value>& workspaces) const;
Gtk::Button& addButton(const Json::Value& ws);
std::string getIcon(const std::string& value, const Json::Value& ws);
bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_;
Gtk::Box box_;
+3 -3
View File
@@ -20,8 +20,8 @@ class Tags : public waybar::AModule {
void handle_focused_tags(uint32_t tags);
void handle_view_tags(struct wl_array* tags);
void handle_urgent_tags(uint32_t tags);
void handle_focused_output(struct wl_output *output);
void handle_unfocused_output(struct wl_output *output);
void handle_focused_output(struct wl_output* output);
void handle_unfocused_output(struct wl_output* output);
void handle_show();
void handle_primary_clicked(uint32_t tag);
@@ -33,7 +33,7 @@ class Tags : public waybar::AModule {
private:
const waybar::Bar& bar_;
struct wl_output *output_; // stores the output this module belongs to
struct wl_output* output_; // stores the output this module belongs to
Gtk::Box box_;
std::vector<Gtk::Button> buttons_;
struct zriver_output_status_v1* output_status_;
+2
View File
@@ -33,6 +33,7 @@ class Wireplumber : public ALabel {
static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self);
bool handleScroll(GdkEventScroll* e) override;
std::vector<std::string> getWPIcon();
static std::list<waybar::modules::Wireplumber*> modules;
@@ -54,6 +55,7 @@ class Wireplumber : public ALabel {
bool source_muted_;
double source_volume_;
gchar* default_source_name_;
std::string form_factor_;
};
} // namespace waybar::modules
+2
View File
@@ -57,6 +57,7 @@ class AudioBackend {
std::string default_source_name_;
std::vector<std::string> ignored_sinks_;
std::map<std::string, std::string> sink_mapping_;
std::function<void()> on_updated_cb_ = NOOP;
@@ -80,6 +81,7 @@ class AudioBackend {
PulseaudioTarget target = PulseaudioTarget::Sink);
void setIgnoredSinks(const Json::Value& config);
void setSinkMapping(const Json::Value& config);
std::string getSinkPortName() const { return port_name_; }
std::string getFormFactor() const { return form_factor_; }