Merge remote-tracking branch 'origin/master' into pr-4588

This commit is contained in:
Alex
2026-07-03 23:51:30 +02:00
106 changed files with 3642 additions and 266 deletions
+6
View File
@@ -9,6 +9,7 @@
#include <poll.h>
#include <algorithm>
#include <chrono>
#include <fstream>
#include <string>
#include <vector>
@@ -51,6 +52,11 @@ class Battery : public ALabel {
bool warnFirstTime_{true};
bool weightedAverage_{true};
const Bar& bar_;
bool smoothPowerEnable_{false};
double time_constant_s_{260.0};
double smooth_power_{0.0}; // µW
std::chrono::steady_clock::time_point last_t_{std::chrono::steady_clock::now()};
std::string old_status_raw_{""};
util::SleeperThread thread_;
util::SleeperThread thread_battery_update_;
+4 -1
View File
@@ -4,6 +4,7 @@
#include <sys/statvfs.h>
#include <fstream>
#include <vector>
#include "ALabel.hpp"
#include "util/format.hpp"
@@ -19,7 +20,9 @@ class Disk : public ALabel {
private:
util::SleeperThread thread_;
std::string path_;
std::string header_;
std::vector<std::string> paths_;
std::string separator_;
std::string unit_;
float calc_specific_divisor(const std::string& divisor);
+3
View File
@@ -21,6 +21,8 @@ class Tags : public waybar::AModule {
void handle_primary_clicked(uint32_t tag);
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
void handle_active_output(zdwl_ipc_output_v2* zdwl_output_v2, uint32_t active);
struct zdwl_ipc_manager_v2* status_manager_;
struct wl_seat* seat_;
@@ -28,6 +30,7 @@ class Tags : public waybar::AModule {
const waybar::Bar& bar_;
Gtk::Box box_;
std::vector<Gtk::Button> buttons_;
bool hide_vacant_;
struct zdwl_ipc_output_v2* output_status_;
};
+4
View File
@@ -19,6 +19,7 @@ class Window : public AAppIconLabel, public sigc::trackable {
void handle_layout(const uint32_t layout);
void handle_title(const char* title);
void handle_appid(const char* ppid);
void handle_active(const uint32_t active);
void handle_layout_symbol(const char* layout_symbol);
void handle_frame();
@@ -30,6 +31,9 @@ class Window : public AAppIconLabel, public sigc::trackable {
std::string title_;
std::string appid_;
std::string layout_symbol_;
bool active_;
bool hide_inactive_;
bool hide_empty_;
uint32_t layout_;
struct zdwl_ipc_output_v2* output_status_;
+2
View File
@@ -30,6 +30,8 @@ class Language : public waybar::ALabel, public EventHandler {
std::string short_description;
};
auto removeXkbLayoutCssClass() -> void;
auto addXkbLayoutCssClass() -> void;
static auto getLayout(const std::string&) -> Layout;
std::mutex mutex_;
+1
View File
@@ -81,6 +81,7 @@ class Workspace {
int m_id;
std::string m_name;
std::string m_prevNameClass;
std::string m_output;
uint m_windows;
bool m_isActive = false;
+5
View File
@@ -39,6 +39,7 @@ class Workspaces : public AModule, public EventHandler {
auto allOutputs() const -> bool { return m_allOutputs; }
auto showSpecial() const -> bool { return m_showSpecial; }
auto activeOnly() const -> bool { return m_activeOnly; }
auto hideActive() const -> bool { return m_hideActive; }
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
auto persistentOnly() const -> bool { return m_persistentOnly; }
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
@@ -56,6 +57,7 @@ class Workspaces : public AModule, public EventHandler {
auto taskbarReverseDirection() const -> bool { return m_taskbarReverseDirection; }
auto onClickWindow() const -> std::string { return m_onClickWindow; }
auto getIgnoredWindows() const -> std::vector<std::regex> { return m_ignoreWindows; }
auto maxWindows() const -> int { return m_maxWindows; }
enum class ActiveWindowPosition { NONE, FIRST, LAST };
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
@@ -89,6 +91,7 @@ class Workspaces : public AModule, public EventHandler {
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
auto populateMaxWindowsConfig(const Json::Value& config) -> void;
auto populateWorkspaceTaskbarConfig(const Json::Value& config) -> void;
void registerIpc();
@@ -146,6 +149,7 @@ class Workspaces : public AModule, public EventHandler {
bool m_allOutputs = false;
bool m_showSpecial = false;
bool m_activeOnly = false;
bool m_hideActive = false;
bool m_specialVisibleOnly = false;
bool m_persistentOnly = false;
bool m_moveToMonitor = false;
@@ -202,6 +206,7 @@ class Workspaces : public AModule, public EventHandler {
};
std::string m_onClickWindow;
std::string m_currentActiveWindowAddress;
int m_maxWindows = 0;
std::vector<std::regex> m_ignoreWorkspaces;
std::vector<std::regex> m_ignoreWindows;
+1 -2
View File
@@ -36,8 +36,7 @@ class KeyboardState : public AModule {
std::string capslock_format_;
std::string scrolllock_format_;
const std::chrono::seconds interval_;
std::string icon_locked_;
std::string icon_unlocked_;
std::unordered_map<std::string, std::vector<std::string>> key_icon_states_;
std::string devices_path_;
struct libinput* libinput_;
+67
View File
@@ -0,0 +1,67 @@
// include/modules/mango/backend.hpp
#pragma once
#include <list>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
#include "util/json.hpp"
namespace waybar::modules::mango {
class EventHandler {
public:
virtual void onEvent(const Json::Value& ev) = 0;
virtual ~EventHandler() = default;
};
class IPC {
public:
static IPC& getInstance();
IPC(const IPC&) = delete;
IPC& operator=(const IPC&) = delete;
void registerForIPC(const std::string& ev, EventHandler* handler);
void unregisterForIPC(EventHandler* handler);
static Json::Value send(const Json::Value& request);
static void sendAsync(const Json::Value& request);
std::unique_lock<std::mutex> lockData() { return std::unique_lock<std::mutex>(data_mutex_); }
std::unordered_map<std::string, Json::Value> getMonitors() const;
Json::Value getMonitor(const std::string& name);
Json::Value getActiveClientForMonitor(const std::string& name) const;
std::string getKeyboardLayout() const;
std::string getKeymode() const;
std::string getLayoutSymbolForMonitor(const std::string& name) const;
private:
IPC();
~IPC();
void startIPC();
static int connectToSocket();
void parseIPC(const std::string& line);
void handleMonitorUpdate(const Json::Value& mon);
void updateFocusingClient(const Json::Value& client);
void updateKeyboardLayout(const std::string& layout);
static Json::Value sendCommand(const std::string& cmd);
int sockfd_ = -1;
std::thread ipc_thread_;
mutable std::mutex data_mutex_;
std::unordered_map<std::string, Json::Value> monitors_;
std::unordered_map<uint64_t, Json::Value> clients_;
uint64_t focusing_client_id_ = 0;
std::string keyboard_layout_;
std::string keymode_;
Json::Value active_client_;
std::mutex callback_mutex_;
std::list<std::pair<std::string, EventHandler*>> callbacks_;
};
} // namespace waybar::modules::mango
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <mutex>
#include <string>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/mango/backend.hpp"
namespace waybar::modules::mango {
class Keymode : public ALabel, public EventHandler {
public:
Keymode(const std::string&, const Bar&, const Json::Value&);
~Keymode() override;
void update() override;
private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
std::mutex mutex_;
const Bar& bar_;
std::string last_keymode_;
};
} // namespace waybar::modules::mango
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <xkbcommon/xkbregistry.h>
#include <string>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/mango/backend.hpp"
namespace waybar::modules::mango {
class Language : public ALabel, public EventHandler {
public:
Language(const std::string&, const Bar&, const Json::Value&);
~Language() override;
void update() override;
private:
void updateFromIPC();
void onEvent(const Json::Value& ev) override;
void doUpdate();
struct Layout {
std::string full_name;
std::string short_name;
std::string variant;
std::string short_description;
};
Layout getLayout(const std::string& fullName);
std::mutex mutex_;
const Bar& bar_;
std::vector<Layout> layouts_;
unsigned current_idx_;
std::string last_short_name_;
struct rxkb_context* rxkb_ctx_ = nullptr;
};
} // namespace waybar::modules::mango
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <mutex>
#include <string>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/mango/backend.hpp"
namespace waybar::modules::mango {
class Layout : public ALabel, public EventHandler {
public:
Layout(const std::string&, const Bar&, const Json::Value&);
~Layout() override;
void update() override;
private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
std::mutex mutex_;
const Bar& bar_;
std::string last_symbol_;
};
} // namespace waybar::modules::mango
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <gtkmm/button.h>
#include <json/value.h>
#include <mutex>
#include "AAppIconLabel.hpp"
#include "bar.hpp"
#include "modules/mango/backend.hpp"
namespace waybar::modules::mango {
class Window : public AAppIconLabel, public EventHandler {
public:
Window(const std::string&, const Bar&, const Json::Value&);
~Window() override;
void update() override;
private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
void setClass(const std::string& className, bool enable);
const Bar& bar_;
std::string oldAppId_;
std::mutex mutex_;
};
} // namespace waybar::modules::mango
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <gtkmm/button.h>
#include <json/value.h>
#include <unordered_map>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/mango/backend.hpp"
namespace waybar::modules::mango {
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string&, const Bar&, const Json::Value&);
~Workspaces() override;
void update() override;
private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
Gtk::Button& addButton(uint64_t idx);
void updateButtonState(Gtk::Button& button, const Json::Value& tag, const Json::Value& monitor);
std::string getIcon(const std::string& value, const Json::Value& tag);
bool handleButtonClick(GdkEventButton* event, uint64_t idx, bool isOverview);
const Bar& bar_;
Gtk::Box box_;
std::unordered_map<uint64_t, Gtk::Button> buttons_;
Gtk::Button* overview_button_ = nullptr;
std::string on_click_left_;
std::string on_click_middle_;
std::string on_click_right_;
};
} // namespace waybar::modules::mango
+4
View File
@@ -82,6 +82,7 @@ class Idle : public State {
class Playing : public State {
Context* const ctx_;
sigc::connection timer_connection_;
sigc::connection idle_connection_;
public:
Playing(Context* const ctx) : ctx_{ctx} {}
@@ -98,7 +99,10 @@ class Playing : public State {
Playing(Playing const&) = delete;
Playing& operator=(Playing const&) = delete;
void timer() noexcept;
void idle() noexcept;
bool on_timer();
bool on_io(Glib::IOCondition const&);
};
class Paused : public State {
+3
View File
@@ -38,6 +38,7 @@ class Mpris : public ALabel {
std::optional<std::string> artist;
std::optional<std::string> album;
std::optional<std::string> album_artist;
std::optional<std::string> title;
std::optional<std::string> length; // as HH:MM:SS
std::optional<std::string> position; // same format
@@ -76,6 +77,8 @@ class Mpris : public ALabel {
std::string player_;
std::vector<std::string> ignored_players_;
bool prefer_album_artist_;
PlayerctlPlayerManager* manager;
PlayerctlPlayer* player;
PlayerctlPlayer* last_active_player_ = nullptr;
+7
View File
@@ -3,6 +3,8 @@
#include <gtkmm/button.h>
#include <json/value.h>
#include <vector>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/niri/backend.hpp"
@@ -18,6 +20,7 @@ class Workspaces : public AModule, public EventHandler {
private:
void onEvent(const Json::Value& ev) override;
void doUpdate();
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);
@@ -25,6 +28,10 @@ class Workspaces : public AModule, public EventHandler {
Gtk::Box box_;
// Map from niri workspace id to button.
std::unordered_map<uint64_t, Gtk::Button> buttons_;
bool sort_by_id_ = false;
bool sort_by_name_ = false;
bool sort_by_coordinates_ = false;
};
} // namespace waybar::modules::niri
+10 -1
View File
@@ -9,9 +9,18 @@ namespace waybar::modules {
struct Profile {
std::string name;
// Legacy driver field, kept for backward compatibility with the
// `{driver}` format placeholder and with older power-profiles-daemon
// versions that only expose a single `Driver` DBus property.
std::string driver;
std::string cpuDriver;
std::string platformDriver;
Profile(std::string n, std::string d) : name(std::move(n)), driver(std::move(d)) {}
Profile(std::string n, std::string d, std::string cd, std::string pd)
: name(std::move(n)),
driver(std::move(d)),
cpuDriver(std::move(cd)),
platformDriver(std::move(pd)) {}
};
class PowerProfilesDaemon : public ALabel {
+1
View File
@@ -22,6 +22,7 @@ class Pulseaudio : public ALabel {
const std::vector<std::string> getPulseIcon() const;
std::shared_ptr<util::AudioBackend> backend = nullptr;
util::PulseaudioTarget target = util::PulseaudioTarget::Sink;
};
} // namespace waybar::modules
+4
View File
@@ -20,6 +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_show();
void handle_primary_clicked(uint32_t tag);
@@ -31,9 +33,11 @@ class Tags : public waybar::AModule {
private:
const waybar::Bar& bar_;
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_;
struct zriver_seat_status_v1* seat_status_;
};
} /* namespace waybar::modules::river */
+5 -1
View File
@@ -14,11 +14,14 @@ namespace waybar::modules::SNI {
class Host {
public:
Host(const std::size_t id, const Json::Value&, const Bar&,
Host(const std::size_t id, const Json::Value&, const Bar&, const std::vector<std::string>&,
const std::function<void(std::unique_ptr<Item>&)>&,
const std::function<void(std::unique_ptr<Item>&)>&, const std::function<void()>&);
~Host();
void checkIgnoreList(const std::vector<std::string>& ignore_list,
const std::function<void(std::unique_ptr<Item>&)>& on_remove);
private:
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring,
@@ -47,6 +50,7 @@ class Host {
unsigned retry_count_ = 0;
const Json::Value& config_;
const Bar& bar_;
const std::vector<std::string> ignore_list_;
const std::function<void(std::unique_ptr<Item>&)> on_add_;
const std::function<void(std::unique_ptr<Item>&)> on_remove_;
const std::function<void()> on_update_;
+3
View File
@@ -19,11 +19,14 @@ class Tray : public AModule {
private:
void onAdd(std::unique_ptr<Item>& item);
void onRemove(std::unique_ptr<Item>& item);
void checkIgnoreList(std::unique_ptr<Item>* item);
std::vector<std::string> parseIgnoreList(const Json::Value& config);
void queueUpdate();
static inline std::size_t nb_hosts_ = 0;
Gtk::Box box_;
SNI::Watcher::singleton watcher_;
std::vector<std::string> ignore_list_;
SNI::Host host_;
};
+3
View File
@@ -31,6 +31,8 @@ class Workspaces : public AModule, public sigc::trackable {
static int convertWorkspaceNameToNum(const std::string& name);
static int windowRewritePriorityFunction(std::string const& window_rule);
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
bool isWorkspaceIgnored(std::string const& name);
void onCmd(const struct Ipc::ipc_response&);
void onEvent(const struct Ipc::ipc_response&);
bool filterButtons();
@@ -50,6 +52,7 @@ class Workspaces : public AModule, public sigc::trackable {
std::vector<std::string> workspaces_order_;
Gtk::Box box_;
std::string m_formatWindowSeparator;
std::vector<std::regex> m_ignoreWorkspaces;
util::RegexCollection m_windowRewriteRules;
util::JsonParser parser_;
std::unordered_map<std::string, Gtk::Button> buttons_;
+27
View File
@@ -18,6 +18,7 @@
#include "AModule.hpp"
#include "bar.hpp"
#include "client.hpp"
#include "ext-workspace-v1-client-protocol.h"
#include "giomm/desktopappinfo.h"
#include "util/icon_loader.hpp"
#include "util/json.hpp"
@@ -80,6 +81,7 @@ class Task {
std::string title_;
std::string app_id_;
uint32_t state_ = 0;
struct ext_workspace_handle_v1* workspace_ = nullptr;
int32_t drag_start_x;
int32_t drag_start_y;
@@ -102,6 +104,9 @@ class Task {
bool minimized() const { return state_ & MINIMIZED; }
bool active() const { return state_ & ACTIVE; }
bool fullscreen() const { return state_ & FULLSCREEN; }
bool visible() const { return button_visible_; }
struct ext_workspace_handle_v1* workspace() const { return workspace_; }
void set_workspace(struct ext_workspace_handle_v1* workspace) { workspace_ = workspace; }
public:
/* Callbacks for the wlr protocol */
@@ -142,6 +147,12 @@ using TaskPtr = std::unique_ptr<Task>;
class Taskbar : public waybar::AModule {
public:
struct WorkspaceState {
Taskbar* taskbar;
struct ext_workspace_handle_v1* handle;
uint32_t state = 0;
};
Taskbar(const std::string&, const waybar::Bar&, const Json::Value&);
~Taskbar();
void update();
@@ -156,22 +167,35 @@ class Taskbar : public waybar::AModule {
std::map<std::string, std::string> app_ids_replace_map_;
struct zwlr_foreign_toplevel_manager_v1* manager_;
struct ext_workspace_manager_v1* workspace_manager_;
struct wl_seat* seat_;
std::vector<struct ext_workspace_group_handle_v1*> workspace_groups_;
std::vector<std::unique_ptr<WorkspaceState>> workspaces_;
struct ext_workspace_handle_v1* current_workspace_ = nullptr;
public:
/* Callbacks for global registration */
void register_manager(struct wl_registry*, uint32_t name, uint32_t version);
void register_workspace_manager(struct wl_registry*, uint32_t name, uint32_t version);
void register_seat(struct wl_registry*, uint32_t name, uint32_t version);
/* Callbacks for the wlr protocol */
void handle_toplevel_create(struct zwlr_foreign_toplevel_handle_v1*);
void handle_finished();
void handle_workspace_group_create(struct ext_workspace_group_handle_v1*);
void handle_workspace_group_removed(struct ext_workspace_group_handle_v1*);
void handle_workspace_create(struct ext_workspace_handle_v1*);
void handle_workspace_done();
void handle_workspace_finished();
void handle_workspace_removed(struct ext_workspace_handle_v1*);
public:
void add_button(Gtk::Button&);
void move_button(Gtk::Button&, int);
void remove_button(Gtk::Button&);
void remove_task(uint32_t);
void assign_current_workspace(Task&);
void update_bar_css_classes();
bool show_output(struct wl_output*) const;
bool all_outputs() const;
@@ -179,6 +203,9 @@ class Taskbar : public waybar::AModule {
const IconLoader& icon_loader() const;
const std::unordered_set<std::string>& ignore_list() const;
const std::map<std::string, std::string>& app_ids_replace_map() const;
private:
void set_bar_css_class(const std::string&, bool);
};
} /* namespace waybar::modules::wlr */