Merge branch 'Alexays:master' into encode_icon_inside_label

This commit is contained in:
Rio Sanjaya
2026-03-12 13:17:40 +07:00
committed by GitHub
170 changed files with 2894 additions and 1959 deletions
+4 -8
View File
@@ -10,13 +10,9 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# TODO: bump to clang 19 release
# - uses: DoozyX/clang-format-lint-action@v0.18.2
- uses: DoozyX/clang-format-lint-action@558090054b3f39e3d6af24f0cd73b319535da809
- uses: actions/checkout@v6
- uses: RafikFarhad/clang-format-github-action@v6
name: clang-format
with:
source: "."
extensions: "hpp,h,cpp,c"
style: "file:.clang-format"
clangFormatVersion: 19
sources: "src/**/*.hpp,src/**/*.cpp"
style: "file"
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
container:
image: alexays/waybar:debian
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: configure
run: |
meson -Dcpp_std=c++20 build # necessary to generate compile_commands.json
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Login to Docker Hub
uses: docker/login-action@v3
+2 -2
View File
@@ -12,13 +12,13 @@ jobs:
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Test in FreeBSD VM
uses: cross-platform-actions/action@v0.28.0
timeout-minutes: 180
env:
CPPFLAGS: '-isystem/usr/local/include'
LDFLAGS: '-L/usr/local/lib'
LDFLAGS: '-L/usr/local/lib'
with:
operating_system: freebsd
version: "14.2"
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
image: alexays/waybar:${{ matrix.distro }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: configure
run: meson setup -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
- name: build
+12 -9
View File
@@ -2,16 +2,19 @@ name: "Nix-Tests"
on:
pull_request:
push:
concurrency:
group: ${{ github.workflow }}-nix-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
nix-flake-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- run: nix flake show
- run: nix flake check --print-build-logs
- run: nix build --print-build-logs
- uses: actions/checkout@v6
- uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- run: nix flake show
- run: nix flake check --print-build-logs
- run: nix build --print-build-logs
+5 -5
View File
@@ -4,19 +4,19 @@ on:
schedule:
- cron: '0 0 1 * *' # Run monthly
push:
paths:
- 'flake.nix'
paths:
- 'flake.nix'
jobs:
lockfile:
runs-on: ubuntu-latest
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install Nix
uses: cachix/install-nix-action@v27
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@v21
uses: DeterminateSystems/update-flake-lock@v28
+1
View File
@@ -51,3 +51,4 @@ result
result-*
.ccls-cache
_codeql_detected_source_root
+4
View File
@@ -151,6 +151,10 @@ Contributions welcome!<br>
Have fun :)<br>
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
> [!CAUTION]
> Distributions of Waybar are only released on the [official GitHub page](https://github.com/Alexays/Waybar).<br/>
> Waybar does **not** have an official website. Do not trust any sites that claim to be official.
## License
Waybar is licensed under the MIT license. [See LICENSE for more information](https://github.com/Alexays/Waybar/blob/master/LICENSE).
+1
View File
@@ -0,0 +1 @@
.
Generated
+3 -3
View File
@@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1766902085,
"narHash": "sha256-coBu0ONtFzlwwVBzmjacUQwj3G+lybcZ1oeNSQkgC0M=",
"lastModified": 1769461804,
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c0b0e0fddf73fd517c3471e546c0df87a42d53f4",
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
"type": "github"
},
"original": {
Binary file not shown.
+4 -4
View File
@@ -9,15 +9,15 @@ namespace waybar {
class AAppIconLabel : public AIconLabel {
public:
AAppIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
AAppIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
const std::string& format, uint16_t interval = 0, bool ellipsize = false,
bool enable_click = false, bool enable_scroll = false);
virtual ~AAppIconLabel() = default;
auto update() -> void override;
protected:
void updateAppIconName(const std::string &app_identifier,
const std::string &alternative_app_identifier);
void updateAppIconName(const std::string& app_identifier,
const std::string& alternative_app_identifier);
void updateAppIcon();
unsigned app_icon_size_{24};
bool update_app_icon_{true};
+2 -2
View File
@@ -9,8 +9,8 @@ namespace waybar {
class AIconLabel : public ALabel {
public:
AIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
AIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
const std::string& format, uint16_t interval = 0, bool ellipsize = false,
bool enable_click = false, bool enable_scroll = false);
virtual ~AIconLabel() = default;
auto update() -> void override;
+6 -6
View File
@@ -10,13 +10,13 @@ namespace waybar {
class ALabel : public AModule {
public:
ALabel(const Json::Value &, const std::string &, const std::string &, const std::string &format,
ALabel(const Json::Value&, const std::string&, const std::string&, const std::string& format,
uint16_t interval = 0, bool ellipsize = false, bool enable_click = false,
bool enable_scroll = false);
virtual ~ALabel() = default;
auto update() -> void override;
virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0);
virtual std::string getIcon(uint16_t, const std::vector<std::string> &alts, uint16_t max = 0);
virtual std::string getIcon(uint16_t, const std::string& alt = "", uint16_t max = 0);
virtual std::string getIcon(uint16_t, const std::vector<std::string>& alts, uint16_t max = 0);
protected:
Gtk::Label label_;
@@ -25,12 +25,12 @@ class ALabel : public AModule {
bool alt_ = false;
std::string default_format_;
bool handleToggle(GdkEventButton *const &e) override;
bool handleToggle(GdkEventButton* const& e) override;
virtual std::string getState(uint8_t value, bool lesser = false);
std::map<std::string, GtkMenuItem *> submenus_;
std::map<std::string, GtkMenuItem*> submenus_;
std::map<std::string, std::string> menuActionsMap_;
static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data);
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
};
} // namespace waybar
+14 -14
View File
@@ -12,13 +12,13 @@ namespace waybar {
class AModule : public IModule {
public:
static constexpr const char *MODULE_CLASS = "module";
static constexpr const char* MODULE_CLASS = "module";
~AModule() override;
auto update() -> void override;
virtual auto refresh(int shouldRefresh) -> void {};
operator Gtk::Widget &() override;
auto doAction(const std::string &name) -> void override;
operator Gtk::Widget&() override;
auto doAction(const std::string& name) -> void override;
/// Emitting on this dispatcher triggers a update() call
Glib::Dispatcher dp;
@@ -28,30 +28,30 @@ class AModule : public IModule {
protected:
// Don't need to make an object directly
// Derived classes are able to use it
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
AModule(const Json::Value&, const std::string&, const std::string&, bool enable_click = false,
bool enable_scroll = false);
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
SCROLL_DIR getScrollDir(GdkEventScroll *e);
SCROLL_DIR getScrollDir(GdkEventScroll* e);
bool tooltipEnabled() const;
std::vector<int> pid_children_;
const std::string name_;
const Json::Value &config_;
const Json::Value& config_;
Gtk::EventBox event_box_;
virtual void setCursor(Gdk::CursorType const &c);
virtual void setCursor(Gdk::CursorType const& c);
virtual bool handleToggle(GdkEventButton *const &ev);
virtual bool handleMouseEnter(GdkEventCrossing *const &ev);
virtual bool handleMouseLeave(GdkEventCrossing *const &ev);
virtual bool handleScroll(GdkEventScroll *);
virtual bool handleRelease(GdkEventButton *const &ev);
GObject *menu_;
virtual bool handleToggle(GdkEventButton* const& ev);
virtual bool handleMouseEnter(GdkEventCrossing* const& ev);
virtual bool handleMouseLeave(GdkEventCrossing* const& ev);
virtual bool handleScroll(GdkEventScroll*);
virtual bool handleRelease(GdkEventButton* const& ev);
GObject* menu_ = nullptr;
private:
bool handleUserEvent(GdkEventButton *const &ev);
bool handleUserEvent(GdkEventButton* const& ev);
const bool isTooltip;
const bool isExpand;
bool hasUserEvents_;
+11 -11
View File
@@ -62,11 +62,11 @@ class Bar : public sigc::trackable {
static const std::string MODE_DEFAULT;
static const std::string MODE_INVISIBLE;
Bar(struct waybar_output *w_output, const Json::Value &);
Bar(const Bar &) = delete;
Bar(struct waybar_output* w_output, const Json::Value&);
Bar(const Bar&) = delete;
~Bar();
void setMode(const std::string &mode);
void setMode(const std::string& mode);
void setVisible(bool value);
void toggle();
void show();
@@ -75,9 +75,9 @@ class Bar : public sigc::trackable {
util::KillSignalAction getOnSigusr1Action();
util::KillSignalAction getOnSigusr2Action();
struct waybar_output *output;
struct waybar_output* output;
Json::Value config;
struct wl_surface *surface;
struct wl_surface* surface;
bool visible = true;
Gtk::Window window;
Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL;
@@ -91,15 +91,15 @@ class Bar : public sigc::trackable {
#endif
private:
void onMap(GdkEventAny *);
void onMap(GdkEventAny*);
auto setupWidgets() -> void;
void getModules(const Factory &, const std::string &, waybar::Group *);
void setupAltFormatKeyForModule(const std::string &module_name);
void setupAltFormatKeyForModuleList(const char *module_list_name);
void setMode(const bar_mode &);
void getModules(const Factory&, const std::string&, waybar::Group*);
void setupAltFormatKeyForModule(const std::string& module_name);
void setupAltFormatKeyForModuleList(const char* module_list_name);
void setMode(const bar_mode&);
void setPassThrough(bool passthrough);
void setPosition(Gtk::PositionType position);
void onConfigure(GdkEventConfigure *ev);
void onConfigure(GdkEventConfigure* ev);
void configureGlobalOffset(int width, int height);
void onOutputGeometryChanged();
+17 -17
View File
@@ -17,35 +17,35 @@ namespace waybar {
class Client {
public:
static Client *inst();
int main(int argc, char *argv[]);
static Client* inst();
int main(int argc, char* argv[]);
void reset();
Glib::RefPtr<Gtk::Application> gtk_app;
Glib::RefPtr<Gdk::Display> gdk_display;
struct wl_display *wl_display = nullptr;
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 wl_display* wl_display = nullptr;
struct wl_registry* registry = nullptr;
struct zxdg_output_manager_v1* xdg_output_manager = nullptr;
struct zwp_idle_inhibit_manager_v1* idle_inhibit_manager = nullptr;
std::vector<std::unique_ptr<Bar>> bars;
Config config;
std::string bar_id;
private:
Client() = default;
const std::string getStyle(const std::string &style, std::optional<Appearance> appearance);
const std::string getStyle(const std::string& style, std::optional<Appearance> appearance);
void bindInterfaces();
void handleOutput(struct waybar_output &output);
auto setupCss(const std::string &css_file) -> void;
struct waybar_output &getOutput(void *);
std::vector<Json::Value> getOutputConfigs(struct waybar_output &output);
void handleOutput(struct waybar_output& output);
auto setupCss(const std::string& css_file) -> void;
struct waybar_output& getOutput(void*);
std::vector<Json::Value> getOutputConfigs(struct waybar_output& output);
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version);
static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name);
static void handleOutputDone(void *, struct zxdg_output_v1 *);
static void handleOutputName(void *, struct zxdg_output_v1 *, const char *);
static void handleOutputDescription(void *, struct zxdg_output_v1 *, const char *);
static void handleGlobal(void* data, struct wl_registry* registry, uint32_t name,
const char* interface, uint32_t version);
static void handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name);
static void handleOutputDone(void*, struct zxdg_output_v1*);
static void handleOutputName(void*, struct zxdg_output_v1*, const char*);
static void handleOutputDescription(void*, struct zxdg_output_v1*, const char*);
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
void handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor);
+11 -11
View File
@@ -14,29 +14,29 @@ namespace waybar {
class Config {
public:
static const std::vector<std::string> CONFIG_DIRS;
static const char *CONFIG_PATH_ENV;
static const char* CONFIG_PATH_ENV;
/* Try to find any of provided names in the supported set of config directories */
static std::optional<std::string> findConfigPath(
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
const std::vector<std::string>& names, const std::vector<std::string>& dirs = CONFIG_DIRS);
static std::vector<std::string> tryExpandPath(const std::string &base,
const std::string &filename);
static std::vector<std::string> tryExpandPath(const std::string& base,
const std::string& filename);
Config() = default;
void load(const std::string &config);
void load(const std::string& config);
Json::Value &getConfig() { return config_; }
Json::Value& getConfig() { return config_; }
std::vector<Json::Value> getOutputConfigs(const std::string &name, const std::string &identifier);
std::vector<Json::Value> getOutputConfigs(const std::string& name, const std::string& identifier);
private:
void setupConfig(Json::Value &dst, const std::string &config_file, int depth);
void resolveConfigIncludes(Json::Value &config, int depth);
void mergeConfig(Json::Value &a_config_, Json::Value &b_config_);
void setupConfig(Json::Value& dst, const std::string& config_file, int depth);
void resolveConfigIncludes(Json::Value& config, int depth);
void mergeConfig(Json::Value& a_config_, Json::Value& b_config_);
static std::vector<std::string> findIncludePath(
const std::string &name, const std::vector<std::string> &dirs = CONFIG_DIRS);
const std::string& name, const std::vector<std::string>& dirs = CONFIG_DIRS);
std::string config_file_;
+8 -7
View File
@@ -11,13 +11,13 @@ namespace waybar {
class Group : public AModule {
public:
Group(const std::string &, const std::string &, const Json::Value &, bool);
Group(const std::string&, const std::string&, const Json::Value&, bool);
~Group() override = default;
auto update() -> void override;
operator Gtk::Widget &() override;
operator Gtk::Widget&() override;
virtual Gtk::Box &getBox();
void addWidget(Gtk::Widget &widget);
virtual Gtk::Box& getBox();
void addWidget(Gtk::Widget& widget);
protected:
Gtk::Box box;
@@ -27,9 +27,10 @@ class Group : public AModule {
bool is_drawer = false;
bool click_to_reveal = false;
std::string add_class_to_drawer_children;
bool handleMouseEnter(GdkEventCrossing *const &ev) override;
bool handleMouseLeave(GdkEventCrossing *const &ev) override;
bool handleToggle(GdkEventButton *const &ev) override;
bool handleMouseEnter(GdkEventCrossing* const& ev) override;
bool handleMouseLeave(GdkEventCrossing* const& ev) override;
bool handleToggle(GdkEventButton* const& ev) override;
bool handleScroll(GdkEventScroll* e) override;
void show_group();
void hide_group();
};
+2 -2
View File
@@ -17,11 +17,11 @@ namespace waybar::modules {
class Backlight : public ALabel {
public:
Backlight(const std::string &, const Json::Value &);
Backlight(const std::string&, const Json::Value&);
virtual ~Backlight() = default;
auto update() -> void override;
bool handleScroll(GdkEventScroll *e) override;
bool handleScroll(GdkEventScroll* e) override;
const std::string preferred_device_;
+1 -1
View File
@@ -6,7 +6,7 @@
#if defined(__linux__)
#include <sys/inotify.h>
#endif
#include <sys/poll.h>
#include <poll.h>
#include <algorithm>
#include <fstream>
+1
View File
@@ -35,6 +35,7 @@ class Custom : public ALabel {
std::string id_;
std::string alt_;
std::string tooltip_;
std::string last_tooltip_markup_;
const bool tooltip_format_enabled_;
std::vector<std::string> class_;
int percentage_;
+1 -1
View File
@@ -22,7 +22,7 @@ class Disk : public ALabel {
std::string path_;
std::string unit_;
float calc_specific_divisor(const std::string divisor);
float calc_specific_divisor(const std::string& divisor);
};
} // namespace waybar::modules
+6 -6
View File
@@ -12,23 +12,23 @@ namespace waybar::modules::dwl {
class Tags : public waybar::AModule {
public:
Tags(const std::string &, const waybar::Bar &, const Json::Value &);
Tags(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Tags();
// Handlers for wayland events
void handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused);
void handle_primary_clicked(uint32_t tag);
bool handle_button_press(GdkEventButton *event_button, uint32_t tag);
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
struct zdwl_ipc_manager_v2 *status_manager_;
struct wl_seat *seat_;
struct zdwl_ipc_manager_v2* status_manager_;
struct wl_seat* seat_;
private:
const waybar::Bar &bar_;
const waybar::Bar& bar_;
Gtk::Box box_;
std::vector<Gtk::Button> buttons_;
struct zdwl_ipc_output_v2 *output_status_;
struct zdwl_ipc_output_v2* output_status_;
};
} /* namespace waybar::modules::dwl */
+7 -7
View File
@@ -13,26 +13,26 @@ namespace waybar::modules::dwl {
class Window : public AAppIconLabel, public sigc::trackable {
public:
Window(const std::string &, const waybar::Bar &, const Json::Value &);
Window(const std::string&, const waybar::Bar&, const Json::Value&);
~Window();
void handle_layout(const uint32_t layout);
void handle_title(const char *title);
void handle_appid(const char *ppid);
void handle_layout_symbol(const char *layout_symbol);
void handle_title(const char* title);
void handle_appid(const char* ppid);
void handle_layout_symbol(const char* layout_symbol);
void handle_frame();
struct zdwl_ipc_manager_v2 *status_manager_;
struct zdwl_ipc_manager_v2* status_manager_;
private:
const Bar &bar_;
const Bar& bar_;
std::string title_;
std::string appid_;
std::string layout_symbol_;
uint32_t layout_;
struct zdwl_ipc_output_v2 *output_status_;
struct zdwl_ipc_output_v2* output_status_;
};
} // namespace waybar::modules::dwl
+31 -31
View File
@@ -20,16 +20,16 @@ class Workspace;
class WorkspaceManager final : public AModule {
public:
WorkspaceManager(const std::string &id, const waybar::Bar &bar, const Json::Value &config);
WorkspaceManager(const std::string& id, const waybar::Bar& bar, const Json::Value& config);
~WorkspaceManager() override;
void register_manager(wl_registry *registry, uint32_t name, uint32_t version);
void register_manager(wl_registry* registry, uint32_t name, uint32_t version);
void remove_workspace_group(uint32_t id);
void remove_workspace(uint32_t id);
void set_needs_sorting() { needs_sorting_ = true; }
// wl events
void handle_workspace_group(ext_workspace_group_handle_v1 *handle);
void handle_workspace(ext_workspace_handle_v1 *handle);
void handle_workspace_group(ext_workspace_group_handle_v1* handle);
void handle_workspace(ext_workspace_handle_v1* handle);
void handle_done();
void handle_finished();
@@ -38,7 +38,7 @@ class WorkspaceManager final : public AModule {
private:
void update() override;
bool has_button(const Gtk::Button *button);
bool has_button(const Gtk::Button* button);
void sort_workspaces();
void clear_buttons();
void update_buttons();
@@ -52,10 +52,10 @@ class WorkspaceManager final : public AModule {
bool sort_by_coordinates_ = false;
bool all_outputs_ = false;
const waybar::Bar &bar_;
const waybar::Bar& bar_;
Gtk::Box box_;
ext_workspace_manager_v1 *ext_manager_ = nullptr;
ext_workspace_manager_v1* ext_manager_ = nullptr;
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
@@ -64,60 +64,60 @@ class WorkspaceManager final : public AModule {
class WorkspaceGroup {
public:
WorkspaceGroup(WorkspaceManager &manager, ext_workspace_group_handle_v1 *handle, uint32_t id);
WorkspaceGroup(WorkspaceManager& manager, ext_workspace_group_handle_v1* handle, uint32_t id);
~WorkspaceGroup();
u_int32_t id() const { return id_; }
bool has_output(const wl_output *output);
bool has_workspace(const ext_workspace_handle_v1 *workspace);
bool has_output(const wl_output* output);
bool has_workspace(const ext_workspace_handle_v1* workspace);
// wl events
void handle_capabilities(uint32_t capabilities);
void handle_output_enter(wl_output *output);
void handle_output_leave(wl_output *output);
void handle_workspace_enter(ext_workspace_handle_v1 *handle);
void handle_workspace_leave(ext_workspace_handle_v1 *handle);
void handle_output_enter(wl_output* output);
void handle_output_leave(wl_output* output);
void handle_workspace_enter(ext_workspace_handle_v1* handle);
void handle_workspace_leave(ext_workspace_handle_v1* handle);
void handle_removed();
private:
WorkspaceManager &workspaces_manager_;
ext_workspace_group_handle_v1 *ext_handle_;
WorkspaceManager& workspaces_manager_;
ext_workspace_group_handle_v1* ext_handle_;
uint32_t id_;
std::vector<wl_output *> outputs_;
std::vector<ext_workspace_handle_v1 *> workspaces_;
std::vector<wl_output*> outputs_;
std::vector<ext_workspace_handle_v1*> workspaces_;
};
class Workspace {
public:
Workspace(const Json::Value &config, WorkspaceManager &manager, ext_workspace_handle_v1 *handle,
uint32_t id, const std::string &name);
Workspace(const Json::Value& config, WorkspaceManager& manager, ext_workspace_handle_v1* handle,
uint32_t id, const std::string& name);
~Workspace();
ext_workspace_handle_v1 *handle() const { return ext_handle_; }
ext_workspace_handle_v1* handle() const { return ext_handle_; }
u_int32_t id() const { return id_; }
std::string &workspace_id() { return workspace_id_; }
std::string &name() { return name_; }
std::vector<u_int32_t> &coordinates() { return coordinates_; }
Gtk::Button &button() { return button_; }
std::string& workspace_id() { return workspace_id_; }
std::string& name() { return name_; }
std::vector<u_int32_t>& coordinates() { return coordinates_; }
Gtk::Button& button() { return button_; }
void update();
// wl events
void handle_id(const std::string &id);
void handle_name(const std::string &name);
void handle_coordinates(const std::vector<uint32_t> &coordinates);
void handle_id(const std::string& id);
void handle_name(const std::string& name);
void handle_coordinates(const std::vector<uint32_t>& coordinates);
void handle_state(uint32_t state);
void handle_capabilities(uint32_t capabilities);
void handle_removed();
// gdk events
bool handle_clicked(const GdkEventButton *button) const;
bool handle_clicked(const GdkEventButton* button) const;
private:
bool has_state(uint32_t state) const { return (state_ & state) == state; }
std::string icon();
WorkspaceManager &workspace_manager_;
ext_workspace_handle_v1 *ext_handle_ = nullptr;
WorkspaceManager& workspace_manager_;
ext_workspace_handle_v1* ext_handle_ = nullptr;
uint32_t id_;
uint32_t state_ = 0;
std::string workspace_id_;
@@ -1,10 +1,10 @@
#include "ext-workspace-v1-client-protocol.h"
namespace waybar::modules::ext {
void add_registry_listener(void *data);
void add_workspace_listener(ext_workspace_handle_v1 *workspace_handle, void *data);
void add_workspace_group_listener(ext_workspace_group_handle_v1 *workspace_group_handle,
void *data);
ext_workspace_manager_v1 *workspace_manager_bind(wl_registry *registry, uint32_t name,
uint32_t version, void *data);
void add_registry_listener(void* data);
void add_workspace_listener(ext_workspace_handle_v1* workspace_handle, void* data);
void add_workspace_group_listener(ext_workspace_group_handle_v1* workspace_group_handle,
void* data);
ext_workspace_manager_v1* workspace_manager_bind(wl_registry* registry, uint32_t name,
uint32_t version, void* data);
} // namespace waybar::modules::ext
+11 -11
View File
@@ -17,7 +17,7 @@ namespace waybar::modules {
class Gamemode : public AModule {
public:
Gamemode(const std::string &, const Json::Value &);
Gamemode(const std::string&, const Json::Value&);
virtual ~Gamemode();
auto update() -> void override;
@@ -28,18 +28,18 @@ class Gamemode : public AModule {
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
const std::string DEFAULT_GLYPH = "";
void appear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name,
const Glib::ustring &name_owner);
void disappear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &arguments);
void appear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name,
const Glib::ustring& name_owner);
void disappear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection>& connection,
const Glib::ustring& sender_name, const Glib::ustring& object_path,
const Glib::ustring& interface_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& parameters);
void notify_cb(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& arguments);
void getData();
bool handleToggle(GdkEventButton *const &) override;
bool handleToggle(GdkEventButton* const&) override;
// Config
std::string format = DEFAULT_FORMAT;
+5 -3
View File
@@ -1,5 +1,6 @@
#pragma once
#include <atomic>
#include <filesystem>
#include <list>
#include <mutex>
@@ -43,10 +44,11 @@ class IPC {
std::thread ipcThread_;
std::mutex callbackMutex_;
std::mutex socketMutex_;
util::JsonParser parser_;
std::list<std::pair<std::string, EventHandler*>> callbacks_;
int socketfd_; // the hyprland socket file descriptor
pid_t socketOwnerPid_;
bool running_ = true; // the ipcThread will stop running when this is false
int socketfd_ = -1; // the hyprland socket file descriptor
pid_t socketOwnerPid_ = -1;
std::atomic<bool> running_ = true; // the ipcThread will stop running when this is false
};
}; // namespace waybar::modules::hyprland
+1
View File
@@ -26,6 +26,7 @@ class Submap : public waybar::ALabel, public EventHandler {
const Bar& bar_;
util::JsonParser parser_;
std::string submap_;
std::string prev_submap_;
bool always_on_ = false;
std::string default_submap_ = "Default";
+11 -11
View File
@@ -20,8 +20,8 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
private:
struct Workspace {
int id;
int windows;
int id = 0;
int windows = 0;
std::string last_window;
std::string last_window_title;
@@ -29,14 +29,14 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
};
struct WindowData {
bool floating;
bool floating = false;
int monitor = -1;
std::string class_name;
std::string initial_class_name;
std::string title;
std::string initial_title;
bool fullscreen;
bool grouped;
bool fullscreen = false;
bool grouped = false;
static auto parse(const Json::Value&) -> WindowData;
};
@@ -47,7 +47,7 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
void queryActiveWorkspace();
void setClass(const std::string&, bool enable);
bool separateOutputs_;
bool separateOutputs_ = false;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
@@ -55,11 +55,11 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
Workspace workspace_;
std::string soloClass_;
std::string lastSoloClass_;
bool solo_;
bool allFloating_;
bool swallowing_;
bool fullscreen_;
bool focused_;
bool solo_ = false;
bool allFloating_ = false;
bool swallowing_ = false;
bool fullscreen_ = false;
bool focused_ = false;
IPC& m_ipc;
};
@@ -40,10 +40,11 @@ struct WindowRepr {
class WindowCreationPayload {
public:
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
WindowRepr window_repr);
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
std::string window_class, std::string window_title, bool is_active);
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
const std::string& window_class, const std::string& window_title,
bool is_active);
WindowCreationPayload(Json::Value const& client_data);
int incrementTimeSpentUncreated();
+7 -1
View File
@@ -4,6 +4,7 @@
#include <gtkmm/enums.h>
#include <gtkmm/label.h>
#include <json/value.h>
#include <sigc++/connection.h>
#include <cstdint>
#include <map>
@@ -43,6 +44,7 @@ class Workspaces : public AModule, public EventHandler {
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
auto enableTaskbar() const -> bool { return m_enableTaskbar; }
auto taskbarWithIcon() const -> bool { return m_taskbarWithIcon; }
auto barScroll() const -> bool { return m_barScroll; }
auto getBarOutput() const -> std::string { return m_bar.output->name; }
auto formatBefore() const -> std::string { return m_formatBefore; }
@@ -58,7 +60,7 @@ class Workspaces : public AModule, public EventHandler {
enum class ActiveWindowPosition { NONE, FIRST, LAST };
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
std::string getRewrite(std::string window_class, std::string window_title);
std::string getRewrite(const std::string& window_class, const std::string& window_title);
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
bool isWorkspaceIgnored(std::string const& workspace_name);
@@ -122,6 +124,8 @@ class Workspaces : public AModule, public EventHandler {
static std::pair<std::string, std::string> splitDoublePayload(std::string const& payload);
static std::tuple<std::string, std::string, std::string> splitTriplePayload(
std::string const& payload);
// scroll events
bool handleScroll(GdkEventScroll* e) override;
// Update methods
void doUpdate();
@@ -145,6 +149,7 @@ class Workspaces : public AModule, public EventHandler {
bool m_specialVisibleOnly = false;
bool m_persistentOnly = false;
bool m_moveToMonitor = false;
bool m_barScroll = false;
Json::Value m_persistentWorkspaceConfig;
// Map for windows stored in workspaces not present in the current bar.
@@ -204,6 +209,7 @@ class Workspaces : public AModule, public EventHandler {
std::mutex m_mutex;
const Bar& m_bar;
Gtk::Box m_box;
sigc::connection m_scrollEventConnection_;
IPC& m_ipc;
};
+6 -6
View File
@@ -13,7 +13,7 @@ namespace waybar::modules {
class JACK : public ALabel {
public:
JACK(const std::string &, const Json::Value &);
JACK(const std::string&, const Json::Value&);
virtual ~JACK() = default;
auto update() -> void override;
@@ -25,7 +25,7 @@ class JACK : public ALabel {
private:
std::string JACKState();
jack_client_t *client_;
jack_client_t* client_;
jack_nframes_t bufsize_;
jack_nframes_t samplerate_;
unsigned int xruns_;
@@ -38,7 +38,7 @@ class JACK : public ALabel {
} // namespace waybar::modules
int bufSizeCallback(jack_nframes_t size, void *obj);
int sampleRateCallback(jack_nframes_t rate, void *obj);
int xrunCallback(void *obj);
void shutdownCallback(void *obj);
int bufSizeCallback(jack_nframes_t size, void* obj);
int sampleRateCallback(jack_nframes_t rate, void* obj);
int xrunCallback(void* obj);
void shutdownCallback(void* obj);
+2
View File
@@ -3,6 +3,7 @@
#include <fmt/chrono.h>
#include <gtkmm/label.h>
#include <mutex>
#include <set>
#include <unordered_map>
@@ -41,6 +42,7 @@ class KeyboardState : public AModule {
struct libinput* libinput_;
std::unordered_map<std::string, struct libinput_device*> libinput_devices_;
std::mutex devices_mutex_; // protects libinput_devices_
std::set<int> binding_keys;
util::SleeperThread libinput_thread_, hotplug_thread_;
+1 -1
View File
@@ -44,7 +44,7 @@ class MPD : public ALabel {
std::string getFilename() const;
void setLabel();
std::string getStateIcon() const;
std::string getOptionIcon(std::string optionName, bool activated) const;
std::string getOptionIcon(const std::string& optionName, bool activated) const;
// GUI-side methods
bool handlePlayPause(GdkEventButton* const&);
+1
View File
@@ -78,6 +78,7 @@ class Mpris : public ALabel {
PlayerctlPlayerManager* manager;
PlayerctlPlayer* player;
PlayerctlPlayer* last_active_player_ = nullptr;
std::string lastStatus;
std::string lastPlayer;
+1 -1
View File
@@ -17,7 +17,7 @@ class EventHandler {
class IPC {
public:
IPC() { startIPC(); }
IPC();
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
void unregisterForIPC(EventHandler* handler);
+4 -4
View File
@@ -10,13 +10,13 @@ namespace waybar::modules::niri {
class Language : public ALabel, public EventHandler {
public:
Language(const std::string &, const Bar &, const Json::Value &);
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 onEvent(const Json::Value& ev) override;
void doUpdate();
struct Layout {
@@ -26,10 +26,10 @@ class Language : public ALabel, public EventHandler {
std::string short_description;
};
static Layout getLayout(const std::string &fullName);
static Layout getLayout(const std::string& fullName);
std::mutex mutex_;
const Bar &bar_;
const Bar& bar_;
std::vector<Layout> layouts_;
unsigned current_idx_;
+4 -4
View File
@@ -11,16 +11,16 @@ namespace waybar::modules::niri {
class Window : public AAppIconLabel, public EventHandler {
public:
Window(const std::string &, const Bar &, const Json::Value &);
Window(const std::string&, const Bar&, const Json::Value&);
~Window() override;
void update() override;
private:
void onEvent(const Json::Value &ev) override;
void onEvent(const Json::Value& ev) override;
void doUpdate();
void setClass(const std::string &className, bool enable);
void setClass(const std::string& className, bool enable);
const Bar &bar_;
const Bar& bar_;
std::string oldAppId_;
};
+5 -5
View File
@@ -11,17 +11,17 @@ namespace waybar::modules::niri {
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string &, const Bar &, const Json::Value &);
Workspaces(const std::string&, const Bar&, const Json::Value&);
~Workspaces() override;
void update() override;
private:
void onEvent(const Json::Value &ev) override;
void onEvent(const Json::Value& ev) override;
void doUpdate();
Gtk::Button &addButton(const Json::Value &ws);
std::string getIcon(const std::string &value, const Json::Value &ws);
Gtk::Button& addButton(const Json::Value& ws);
std::string getIcon(const std::string& value, const Json::Value& ws);
const Bar &bar_;
const Bar& bar_;
Gtk::Box box_;
// Map from niri workspace id to button.
std::unordered_map<uint64_t, Gtk::Button> buttons_;
+8 -8
View File
@@ -16,15 +16,15 @@ struct Profile {
class PowerProfilesDaemon : public ALabel {
public:
PowerProfilesDaemon(const std::string &, const Json::Value &);
PowerProfilesDaemon(const std::string&, const Json::Value&);
auto update() -> void override;
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties &,
const std::vector<Glib::ustring> &);
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult> &r);
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult> &r);
void setPropCb(Glib::RefPtr<Gio::AsyncResult> &r);
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties&,
const std::vector<Glib::ustring>&);
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult>& r);
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult>& r);
void setPropCb(Glib::RefPtr<Gio::AsyncResult>& r);
void populateInitState();
bool handleToggle(GdkEventButton *const &e) override;
bool handleToggle(GdkEventButton* const& e) override;
private:
// True if we're connected to the dbug interface. False if we're
@@ -32,7 +32,7 @@ class PowerProfilesDaemon : public ALabel {
bool connected_;
// Look for a profile name in the list of available profiles and
// switch activeProfile_ to it.
void switchToProfile(std::string const &);
void switchToProfile(std::string const&);
// Used to toggle/display the profiles
std::vector<Profile> availableProfiles_;
// Points to the active profile in the profiles list
+4 -4
View File
@@ -13,15 +13,15 @@ namespace waybar::modules::privacy {
class Privacy : public AModule {
public:
Privacy(const std::string &, const Json::Value &, Gtk::Orientation, const std::string &pos);
Privacy(const std::string&, const Json::Value&, Gtk::Orientation, const std::string& pos);
auto update() -> void override;
void onPrivacyNodesChanged();
private:
std::list<PrivacyNodeInfo *> nodes_screenshare; // Screen is being shared
std::list<PrivacyNodeInfo *> nodes_audio_in; // Application is using the microphone
std::list<PrivacyNodeInfo *> nodes_audio_out; // Application is outputting audio
std::list<PrivacyNodeInfo*> nodes_screenshare; // Screen is being shared
std::list<PrivacyNodeInfo*> nodes_audio_in; // Application is using the microphone
std::list<PrivacyNodeInfo*> nodes_audio_out; // Application is outputting audio
std::mutex mutex_;
sigc::connection visibility_conn;
+4 -4
View File
@@ -16,16 +16,16 @@ namespace waybar::modules::privacy {
class PrivacyItem : public Gtk::Revealer {
public:
PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_,
std::list<PrivacyNodeInfo *> *nodes, Gtk::Orientation orientation,
const std::string &pos, const uint icon_size, const uint transition_duration);
PrivacyItem(const Json::Value& config_, enum PrivacyNodeType privacy_type_,
std::list<PrivacyNodeInfo*>* nodes, Gtk::Orientation orientation,
const std::string& pos, const uint icon_size, const uint transition_duration);
enum PrivacyNodeType privacy_type;
void set_in_use(bool in_use);
private:
std::list<PrivacyNodeInfo *> *nodes;
std::list<PrivacyNodeInfo*>* nodes;
sigc::connection signal_conn;
+11 -11
View File
@@ -10,25 +10,25 @@ namespace waybar::modules::river {
class Layout : public waybar::ALabel {
public:
Layout(const std::string &, const waybar::Bar &, const Json::Value &);
Layout(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Layout();
// Handlers for wayland events
void handle_name(const char *name);
void handle_name(const char* name);
void handle_clear();
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);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
struct zriver_status_manager_v1* status_manager_;
struct wl_seat* seat_;
private:
const waybar::Bar &bar_;
const waybar::Bar& bar_;
std::string name_;
struct wl_output *output_; // stores the output this module belongs to
struct wl_output *focused_output_; // stores the currently focused output
struct zriver_output_status_v1 *output_status_;
struct zriver_seat_status_v1 *seat_status_;
struct wl_output* output_; // stores the output this module belongs to
struct wl_output* focused_output_; // stores the currently focused output
struct zriver_output_status_v1* output_status_;
struct zriver_seat_status_v1* seat_status_;
};
} /* namespace waybar::modules::river */
+6 -6
View File
@@ -10,19 +10,19 @@ namespace waybar::modules::river {
class Mode : public waybar::ALabel {
public:
Mode(const std::string &, const waybar::Bar &, const Json::Value &);
Mode(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Mode();
// Handlers for wayland events
void handle_mode(const char *mode);
void handle_mode(const char* mode);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
struct zriver_status_manager_v1* status_manager_;
struct wl_seat* seat_;
private:
const waybar::Bar &bar_;
const waybar::Bar& bar_;
std::string mode_;
struct zriver_seat_status_v1 *seat_status_;
struct zriver_seat_status_v1* seat_status_;
};
} /* namespace waybar::modules::river */
+8 -8
View File
@@ -13,27 +13,27 @@ namespace waybar::modules::river {
class Tags : public waybar::AModule {
public:
Tags(const std::string &, const waybar::Bar &, const Json::Value &);
Tags(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Tags();
// Handlers for wayland events
void handle_focused_tags(uint32_t tags);
void handle_view_tags(struct wl_array *tags);
void handle_view_tags(struct wl_array* tags);
void handle_urgent_tags(uint32_t tags);
void handle_show();
void handle_primary_clicked(uint32_t tag);
bool handle_button_press(GdkEventButton *event_button, uint32_t tag);
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
struct zriver_status_manager_v1 *status_manager_;
struct zriver_control_v1 *control_;
struct wl_seat *seat_;
struct zriver_status_manager_v1* status_manager_;
struct zriver_control_v1* control_;
struct wl_seat* seat_;
private:
const waybar::Bar &bar_;
const waybar::Bar& bar_;
Gtk::Box box_;
std::vector<Gtk::Button> buttons_;
struct zriver_output_status_v1 *output_status_;
struct zriver_output_status_v1* output_status_;
};
} /* namespace waybar::modules::river */
+10 -10
View File
@@ -12,22 +12,22 @@ namespace waybar::modules::river {
class Window : public waybar::ALabel {
public:
Window(const std::string &, const waybar::Bar &, const Json::Value &);
Window(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Window();
// Handlers for wayland events
void handle_focused_view(const char *title);
void handle_focused_output(struct wl_output *output);
void handle_unfocused_output(struct wl_output *output);
void handle_focused_view(const char* title);
void handle_focused_output(struct wl_output* output);
void handle_unfocused_output(struct wl_output* output);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
struct zriver_status_manager_v1* status_manager_;
struct wl_seat* seat_;
private:
const waybar::Bar &bar_;
struct wl_output *output_; // stores the output this module belongs to
struct wl_output *focused_output_; // stores the currently focused output
struct zriver_seat_status_v1 *seat_status_;
const waybar::Bar& bar_;
struct wl_output* output_; // stores the output this module belongs to
struct wl_output* focused_output_; // stores the currently focused output
struct zriver_seat_status_v1* seat_status_;
};
} /* namespace waybar::modules::river */
+5 -5
View File
@@ -11,18 +11,18 @@ namespace waybar::modules {
class Sndio : public ALabel {
public:
Sndio(const std::string &, const Json::Value &);
Sndio(const std::string&, const Json::Value&);
virtual ~Sndio();
auto update() -> void override;
auto set_desc(struct sioctl_desc *, unsigned int) -> void;
auto set_desc(struct sioctl_desc*, unsigned int) -> void;
auto put_val(unsigned int, unsigned int) -> void;
bool handleScroll(GdkEventScroll *) override;
bool handleToggle(GdkEventButton *const &) override;
bool handleScroll(GdkEventScroll*) override;
bool handleToggle(GdkEventButton* const&) override;
private:
auto connect_to_sndio() -> void;
util::SleeperThread thread_;
struct sioctl_hdl *hdl_;
struct sioctl_hdl* hdl_;
std::vector<struct pollfd> pfds_;
unsigned int addr_;
unsigned int volume_, old_volume_, maxval_;
+7 -2
View File
@@ -16,7 +16,7 @@ class Host {
public:
Host(const std::size_t id, const Json::Value&, const Bar&,
const std::function<void(std::unique_ptr<Item>&)>&,
const std::function<void(std::unique_ptr<Item>&)>&);
const std::function<void(std::unique_ptr<Item>&)>&, const std::function<void()>&);
~Host();
private:
@@ -28,9 +28,13 @@ class Host {
static void registerHost(GObject*, GAsyncResult*, gpointer);
static void itemRegistered(SnWatcher*, const gchar*, gpointer);
static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
void itemReady(Item&);
void itemInvalidated(Item&);
void removeItem(std::vector<std::unique_ptr<Item>>::iterator);
void clearItems();
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
void addRegisteredItem(std::string service);
void addRegisteredItem(const std::string& service);
std::vector<std::unique_ptr<Item>> items_;
const std::string bus_name_;
@@ -43,6 +47,7 @@ class Host {
const Bar& bar_;
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_;
};
} // namespace waybar::modules::SNI
+21 -2
View File
@@ -11,6 +11,7 @@
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
#include <sigc++/trackable.h>
#include <functional>
#include <set>
#include <string_view>
@@ -25,9 +26,13 @@ struct ToolTip {
class Item : public sigc::trackable {
public:
Item(const std::string&, const std::string&, const Json::Value&, const Bar&);
Item(const std::string&, const std::string&, const Json::Value&, const Bar&,
const std::function<void(Item&)>&, const std::function<void(Item&)>&,
const std::function<void()>&);
~Item();
bool isReady() const;
std::string bus_name;
std::string object_path;
@@ -43,7 +48,9 @@ class Item : public sigc::trackable {
Glib::RefPtr<Gdk::Pixbuf> icon_pixmap;
Glib::RefPtr<Gtk::IconTheme> icon_theme;
std::string overlay_icon_name;
Glib::RefPtr<Gdk::Pixbuf> overlay_icon_pixmap;
std::string attention_icon_name;
Glib::RefPtr<Gdk::Pixbuf> attention_icon_pixmap;
std::string attention_movie_name;
std::string icon_theme_path;
std::string menu;
@@ -62,6 +69,8 @@ class Item : public sigc::trackable {
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
void setStatus(const Glib::ustring& value);
void setReady();
void invalidate();
void setCustomIcon(const std::string& id);
void getUpdatedProperties();
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
@@ -69,8 +78,13 @@ class Item : public sigc::trackable {
const Glib::VariantContainerBase& arguments);
void updateImage();
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
static Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
Glib::RefPtr<Gdk::Pixbuf> getAttentionIconPixbuf();
Glib::RefPtr<Gdk::Pixbuf> getOverlayIconPixbuf();
Glib::RefPtr<Gdk::Pixbuf> loadIconFromNameOrFile(const std::string& name, bool log_failure);
static Glib::RefPtr<Gdk::Pixbuf> overlayPixbufs(const Glib::RefPtr<Gdk::Pixbuf>&,
const Glib::RefPtr<Gdk::Pixbuf>&);
Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size);
double getScaledIconSize();
static void onMenuDestroyed(Item* self, GObject* old_menu_pointer);
@@ -86,8 +100,13 @@ class Item : public sigc::trackable {
gdouble distance_scrolled_y_ = 0;
// visibility of items with Status == Passive
bool show_passive_ = false;
bool ready_ = false;
Glib::ustring status_ = "active";
const Bar& bar_;
const std::function<void(Item&)> on_ready_;
const std::function<void(Item&)> on_invalidate_;
const std::function<void()> on_updated_;
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
Glib::RefPtr<Gio::Cancellable> cancellable_;
+1
View File
@@ -19,6 +19,7 @@ class Tray : public AModule {
private:
void onAdd(std::unique_ptr<Item>& item);
void onRemove(std::unique_ptr<Item>& item);
void queueUpdate();
static inline std::size_t nb_hosts_ = 0;
bool show_passive_ = false;
+14 -14
View File
@@ -30,27 +30,27 @@ class Watcher {
typedef struct {
GfWatchType type;
Watcher *watcher;
gchar *service;
gchar *bus_name;
gchar *object_path;
Watcher* watcher;
gchar* service;
gchar* bus_name;
gchar* object_path;
guint watch_id;
} GfWatch;
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection> &, Glib::ustring);
static gboolean handleRegisterHost(Watcher *, GDBusMethodInvocation *, const gchar *);
static gboolean handleRegisterItem(Watcher *, GDBusMethodInvocation *, const gchar *);
static GfWatch *gfWatchFind(GSList *list, const gchar *bus_name, const gchar *object_path);
static GfWatch *gfWatchNew(GfWatchType, const gchar *, const gchar *, const gchar *, Watcher *);
static void nameVanished(GDBusConnection *connection, const char *name, gpointer data);
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
static gboolean handleRegisterHost(Watcher*, GDBusMethodInvocation*, const gchar*);
static gboolean handleRegisterItem(Watcher*, GDBusMethodInvocation*, const gchar*);
static GfWatch* gfWatchFind(GSList* list, const gchar* bus_name, const gchar* object_path);
static GfWatch* gfWatchNew(GfWatchType, const gchar*, const gchar*, const gchar*, Watcher*);
static void nameVanished(GDBusConnection* connection, const char* name, gpointer data);
static void gfWatchFree(gpointer data);
void updateRegisteredItems(SnWatcher *obj);
void updateRegisteredItems(SnWatcher* obj);
uint32_t bus_name_id_;
GSList *hosts_ = nullptr;
GSList *items_ = nullptr;
SnWatcher *watcher_ = nullptr;
GSList* hosts_ = nullptr;
GSList* items_ = nullptr;
SnWatcher* watcher_ = nullptr;
};
} // namespace waybar::modules::SNI
+1 -1
View File
@@ -37,7 +37,7 @@ class BarIpcClient {
void onModeUpdate(bool visible_by_modifier);
void onUrgencyUpdate(bool visible_by_urgency);
void update();
bool isModuleEnabled(std::string name);
bool isModuleEnabled(const std::string& name);
Bar& bar_;
util::JsonParser parser_;
+11 -9
View File
@@ -12,6 +12,8 @@
#include <string>
#include "ipc.hpp"
#include "util/SafeSignal.hpp"
#include "util/scoped_fd.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::sway {
@@ -27,25 +29,25 @@ class Ipc {
std::string payload;
};
sigc::signal<void, const struct ipc_response &> signal_event;
sigc::signal<void, const struct ipc_response &> signal_cmd;
::waybar::SafeSignal<const struct ipc_response&> signal_event;
::waybar::SafeSignal<const struct ipc_response&> signal_cmd;
void sendCmd(uint32_t type, const std::string &payload = "");
void subscribe(const std::string &payload);
void sendCmd(uint32_t type, const std::string& payload = "");
void subscribe(const std::string& payload);
void handleEvent();
void setWorker(std::function<void()> &&func);
void setWorker(std::function<void()>&& func);
protected:
static inline const std::string ipc_magic_ = "i3-ipc";
static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8;
const std::string getSocketPath() const;
int open(const std::string &) const;
struct ipc_response send(int fd, uint32_t type, const std::string &payload = "");
int open(const std::string&) const;
struct ipc_response send(int fd, uint32_t type, const std::string& payload = "");
struct ipc_response recv(int fd);
int fd_;
int fd_event_;
util::ScopedFd fd_;
util::ScopedFd fd_event_;
std::mutex mutex_;
util::SleeperThread thread_;
};
+1 -1
View File
@@ -47,7 +47,7 @@ class Language : public ALabel, public sigc::trackable {
void onEvent(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&);
auto set_current_layout(std::string current_layout) -> void;
auto set_current_layout(const std::string& current_layout) -> void;
auto init_layouts_map(const std::vector<std::string>& used_layouts) -> void;
const static std::string XKB_LAYOUT_NAMES_KEY;
+2 -2
View File
@@ -27,7 +27,7 @@ class Workspaces : public AModule, public sigc::trackable {
static constexpr std::string_view persistent_workspace_switch_cmd_ =
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
static int convertWorkspaceNameToNum(std::string name);
static int convertWorkspaceNameToNum(const std::string& name);
static int windowRewritePriorityFunction(std::string const& window_rule);
void onCmd(const struct Ipc::ipc_response&);
@@ -40,7 +40,7 @@ class Workspaces : public AModule, public sigc::trackable {
std::string getIcon(const std::string&, const Json::Value&);
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
uint16_t getWorkspaceIndex(const std::string& name) const;
static std::string trimWorkspaceName(std::string);
static std::string trimWorkspaceName(const std::string&);
bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_;
+3 -3
View File
@@ -10,7 +10,7 @@ namespace waybar::modules {
class SystemdFailedUnits : public ALabel {
public:
SystemdFailedUnits(const std::string &, const Json::Value &);
SystemdFailedUnits(const std::string&, const Json::Value&);
virtual ~SystemdFailedUnits();
auto update() -> void override;
@@ -24,8 +24,8 @@ class SystemdFailedUnits : public ALabel {
std::string last_status;
Glib::RefPtr<Gio::DBus::Proxy> system_proxy, user_proxy;
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &arguments);
void notify_cb(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& arguments);
void RequestFailedUnits();
void RequestSystemState();
void updateData();
+22 -22
View File
@@ -12,7 +12,7 @@ namespace waybar::modules {
class UPower final : public AIconLabel {
public:
UPower(const std::string &, const Json::Value &);
UPower(const std::string&, const Json::Value&);
virtual ~UPower();
auto update() -> void override;
@@ -30,17 +30,17 @@ class UPower final : public AIconLabel {
// UPower device info
struct upDevice_output {
UpDevice *upDevice{NULL};
UpDevice* upDevice{NULL};
double percentage{0.0};
double temperature{0.0};
guint64 time_full{0u};
guint64 time_empty{0u};
gchar *icon_name{(char *)'\0'};
gchar* icon_name{(char*)'\0'};
bool upDeviceValid{false};
UpDeviceState state;
UpDeviceKind kind;
char *nativePath{(char *)'\0'};
char *model{(char *)'\0'};
char* nativePath{(char*)'\0'};
char* model{(char*)'\0'};
};
// Technical variables
@@ -53,13 +53,13 @@ class UPower final : public AIconLabel {
bool sleeping_;
// Technical functions
void addDevice(UpDevice *);
void removeDevice(const gchar *);
void addDevice(UpDevice*);
void removeDevice(const gchar*);
void removeDevices();
void resetDevices();
void setDisplayDevice();
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
const Glib::ustring getText(const upDevice_output& upDevice_, const std::string& format);
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&);
// DBUS variables
guint watcherID_;
@@ -67,28 +67,28 @@ class UPower final : public AIconLabel {
guint subscrID_{0u};
// UPower variables
UpClient *upClient_;
UpClient* upClient_;
upDevice_output upDevice_; // Device to display
typedef std::unordered_map<std::string, upDevice_output> Devices;
Devices devices_;
bool upRunning_{true};
// DBus callbacks
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
const Glib::ustring &);
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);
void getConn_cb(Glib::RefPtr<Gio::AsyncResult>& result);
void onAppear(const Glib::RefPtr<Gio::DBus::Connection>&, const Glib::ustring&,
const Glib::ustring&);
void onVanished(const Glib::RefPtr<Gio::DBus::Connection>&, const Glib::ustring&);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection>& connection,
const Glib::ustring& sender_name, const Glib::ustring& object_path,
const Glib::ustring& interface_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& parameters);
// UPower callbacks
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
static void deviceAdded_cb(UpClient* client, UpDevice* device, gpointer data);
static void deviceRemoved_cb(UpClient* client, const gchar* objectPath, gpointer data);
static void deviceNotify_cb(UpDevice* device, GParamSpec* pspec, gpointer user_data);
// UPower secondary functions
void getUpDeviceInfo(upDevice_output &upDevice_);
void getUpDeviceInfo(upDevice_output& upDevice_);
};
} // namespace waybar::modules
+5 -19
View File
@@ -12,6 +12,8 @@
#include <unordered_map>
#include <utility>
#include "util/scoped_fd.hpp"
namespace waybar::modules::wayfire {
using EventHandler = std::function<void(const std::string& event)>;
@@ -71,25 +73,9 @@ struct State {
auto update_view(const Json::Value& view) -> void;
};
struct Sock {
int fd;
using Sock = util::ScopedFd;
Sock(int fd) : fd{fd} {}
~Sock() { close(fd); }
Sock(const Sock&) = delete;
auto operator=(const Sock&) = delete;
Sock(Sock&& rhs) noexcept {
fd = rhs.fd;
rhs.fd = -1;
}
auto& operator=(Sock&& rhs) noexcept {
fd = rhs.fd;
rhs.fd = -1;
return *this;
}
};
class IPC {
class IPC : public std::enable_shared_from_this<IPC> {
static std::weak_ptr<IPC> instance;
Json::CharReaderBuilder reader_builder;
Json::StreamWriterBuilder writer_builder;
@@ -98,7 +84,7 @@ class IPC {
State state;
std::mutex state_mutex;
IPC() { start(); }
IPC() = default;
static auto connect() -> Sock;
auto receive(Sock& sock) -> Json::Value;
+35 -35
View File
@@ -33,8 +33,8 @@ class Taskbar;
class Task {
public:
Task(const waybar::Bar &, const Json::Value &, Taskbar *,
struct zwlr_foreign_toplevel_handle_v1 *, struct wl_seat *);
Task(const waybar::Bar&, const Json::Value&, Taskbar*, struct zwlr_foreign_toplevel_handle_v1*,
struct wl_seat*);
~Task();
public:
@@ -53,11 +53,11 @@ class Task {
static uint32_t global_id;
private:
const waybar::Bar &bar_;
const Json::Value &config_;
Taskbar *tbar_;
struct zwlr_foreign_toplevel_handle_v1 *handle_;
struct wl_seat *seat_;
const waybar::Bar& bar_;
const Json::Value& config_;
Taskbar* tbar_;
struct zwlr_foreign_toplevel_handle_v1* handle_;
struct wl_seat* seat_;
uint32_t id_;
@@ -89,7 +89,7 @@ class Task {
std::string repr() const;
std::string state_string(bool = false) const;
void set_minimize_hint();
void on_button_size_allocated(Gtk::Allocation &alloc);
void on_button_size_allocated(Gtk::Allocation& alloc);
void hide_if_ignored();
public:
@@ -105,26 +105,26 @@ class Task {
public:
/* Callbacks for the wlr protocol */
void handle_title(const char *);
void handle_app_id(const char *);
void handle_output_enter(struct wl_output *);
void handle_output_leave(struct wl_output *);
void handle_state(struct wl_array *);
void handle_title(const char*);
void handle_app_id(const char*);
void handle_output_enter(struct wl_output*);
void handle_output_leave(struct wl_output*);
void handle_state(struct wl_array*);
void handle_done();
void handle_closed();
/* Callbacks for Gtk events */
bool handle_clicked(GdkEventButton *);
bool handle_button_release(GdkEventButton *);
bool handle_motion_notify(GdkEventMotion *);
void handle_drag_data_get(const Glib::RefPtr<Gdk::DragContext> &context,
Gtk::SelectionData &selection_data, guint info, guint time);
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &context, int x, int y,
bool handle_clicked(GdkEventButton*);
bool handle_button_release(GdkEventButton*);
bool handle_motion_notify(GdkEventMotion*);
void handle_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context,
Gtk::SelectionData& selection_data, guint info, guint time);
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
Gtk::SelectionData selection_data, guint info, guint time);
public:
bool operator==(const Task &) const;
bool operator!=(const Task &) const;
bool operator==(const Task&) const;
bool operator!=(const Task&) const;
public:
void update();
@@ -142,12 +142,12 @@ using TaskPtr = std::unique_ptr<Task>;
class Taskbar : public waybar::AModule {
public:
Taskbar(const std::string &, const waybar::Bar &, const Json::Value &);
Taskbar(const std::string&, const waybar::Bar&, const Json::Value&);
~Taskbar();
void update();
private:
const waybar::Bar &bar_;
const waybar::Bar& bar_;
Gtk::Box box_;
std::vector<TaskPtr> tasks_;
@@ -155,30 +155,30 @@ class Taskbar : public waybar::AModule {
std::unordered_set<std::string> ignore_list_;
std::map<std::string, std::string> app_ids_replace_map_;
struct zwlr_foreign_toplevel_manager_v1 *manager_;
struct wl_seat *seat_;
struct zwlr_foreign_toplevel_manager_v1* manager_;
struct wl_seat* seat_;
public:
/* Callbacks for global registration */
void register_manager(struct wl_registry *, uint32_t name, uint32_t version);
void register_seat(struct wl_registry *, uint32_t name, uint32_t version);
void register_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_toplevel_create(struct zwlr_foreign_toplevel_handle_v1*);
void handle_finished();
public:
void add_button(Gtk::Button &);
void move_button(Gtk::Button &, int);
void remove_button(Gtk::Button &);
void add_button(Gtk::Button&);
void move_button(Gtk::Button&, int);
void remove_button(Gtk::Button&);
void remove_task(uint32_t);
bool show_output(struct wl_output *) const;
bool show_output(struct wl_output*) const;
bool all_outputs() const;
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;
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;
};
} /* namespace waybar::modules::wlr */
+20
View File
@@ -3,6 +3,7 @@
#include <glibmm/dispatcher.h>
#include <sigc++/signal.h>
#include <cstddef>
#include <functional>
#include <mutex>
#include <queue>
@@ -27,6 +28,12 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
public:
SafeSignal() { dp_.connect(sigc::mem_fun(*this, &SafeSignal::handle_event)); }
void set_max_queued_events(std::size_t max_queued_events) {
std::unique_lock lock(mutex_);
max_queued_events_ = max_queued_events;
trim_queue_locked();
}
template <typename... EmitArgs>
void emit(EmitArgs&&... args) {
if (main_tid_ == std::this_thread::get_id()) {
@@ -41,6 +48,9 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
} else {
{
std::unique_lock lock(mutex_);
if (max_queued_events_ != 0 && queue_.size() >= max_queued_events_) {
queue_.pop();
}
queue_.emplace(std::forward<EmitArgs>(args)...);
}
dp_.emit();
@@ -60,6 +70,15 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
using signal_t::emit_reverse;
using signal_t::make_slot;
void trim_queue_locked() {
if (max_queued_events_ == 0) {
return;
}
while (queue_.size() > max_queued_events_) {
queue_.pop();
}
}
void handle_event() {
for (std::unique_lock lock(mutex_); !queue_.empty(); lock.lock()) {
auto args = queue_.front();
@@ -72,6 +91,7 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
Glib::Dispatcher dp_;
std::mutex mutex_;
std::queue<arg_tuple_t> queue_;
std::size_t max_queued_events_ = 4096;
const std::thread::id main_tid_ = std::this_thread::get_id();
// cache functor for signal emission to avoid recreating it on each event
const slot_t cached_fn_ = make_slot();
+8 -8
View File
@@ -36,7 +36,7 @@ class BacklightDevice {
void set_max(int max);
bool get_powered() const;
void set_powered(bool powered);
friend inline bool operator==(const BacklightDevice &lhs, const BacklightDevice &rhs) {
friend inline bool operator==(const BacklightDevice& lhs, const BacklightDevice& rhs) {
return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && lhs.max_ == rhs.max_;
}
@@ -52,25 +52,25 @@ class BacklightBackend {
BacklightBackend(std::chrono::milliseconds interval, std::function<void()> on_updated_cb = NOOP);
// const inline BacklightDevice *get_best_device(std::string_view preferred_device);
const BacklightDevice *get_previous_best_device();
const BacklightDevice* get_previous_best_device();
void set_previous_best_device(const BacklightDevice *device);
void set_previous_best_device(const BacklightDevice* device);
void set_brightness(const std::string &preferred_device, ChangeType change_type, double step);
void set_brightness(const std::string& preferred_device, ChangeType change_type, double step);
void set_scaled_brightness(const std::string &preferred_device, int brightness);
int get_scaled_brightness(const std::string &preferred_device);
void set_scaled_brightness(const std::string& preferred_device, int brightness);
int get_scaled_brightness(const std::string& preferred_device);
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
static const BacklightDevice *best_device(const std::vector<BacklightDevice> &devices,
static const BacklightDevice* best_device(const std::vector<BacklightDevice>& devices,
std::string_view);
std::vector<BacklightDevice> devices_;
std::mutex udev_thread_mutex_;
private:
void set_brightness_internal(const std::string &device_name, int brightness, int max_brightness);
void set_brightness_internal(const std::string& device_name, int brightness, int max_brightness);
std::function<void()> on_updated_cb_;
std::chrono::milliseconds polling_interval_;
+128 -128
View File
@@ -78,7 +78,7 @@ class Column {
class iterator {
friend Column;
Column const &m_column;
Column const& m_column;
size_t m_stringIndex = 0;
size_t m_pos = 0;
@@ -86,10 +86,10 @@ class Column {
size_t m_end = 0;
bool m_suffix = false;
iterator(Column const &column, size_t stringIndex)
iterator(Column const& column, size_t stringIndex)
: m_column(column), m_stringIndex(stringIndex) {}
auto line() const -> std::string const & { return m_column.m_strings[m_stringIndex]; }
auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
auto isBoundary(size_t at) const -> bool {
assert(at > 0);
@@ -129,18 +129,18 @@ class Column {
return initial == std::string::npos ? m_column.m_indent : initial;
}
auto addIndentAndSuffix(std::string const &plain) const -> std::string {
auto addIndentAndSuffix(std::string const& plain) const -> std::string {
return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type *;
using reference = value_type &;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::forward_iterator_tag;
explicit iterator(Column const &column) : m_column(column) {
explicit iterator(Column const& column) : m_column(column) {
assert(m_column.m_width > m_column.m_indent);
assert(m_column.m_initialIndent == std::string::npos ||
m_column.m_width > m_column.m_initialIndent);
@@ -154,7 +154,7 @@ class Column {
return addIndentAndSuffix(line().substr(m_pos, m_len));
}
auto operator++() -> iterator & {
auto operator++() -> iterator& {
m_pos += m_len;
if (m_pos < line().size() && line()[m_pos] == '\n')
m_pos += 1;
@@ -174,26 +174,26 @@ class Column {
return prev;
}
auto operator==(iterator const &other) const -> bool {
auto operator==(iterator const& other) const -> bool {
return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex &&
&m_column == &other.m_column;
}
auto operator!=(iterator const &other) const -> bool { return !operator==(other); }
auto operator!=(iterator const& other) const -> bool { return !operator==(other); }
};
using const_iterator = iterator;
explicit Column(std::string const &text) { m_strings.push_back(text); }
explicit Column(std::string const& text) { m_strings.push_back(text); }
auto width(size_t newWidth) -> Column & {
auto width(size_t newWidth) -> Column& {
assert(newWidth > 0);
m_width = newWidth;
return *this;
}
auto indent(size_t newIndent) -> Column & {
auto indent(size_t newIndent) -> Column& {
m_indent = newIndent;
return *this;
}
auto initialIndent(size_t newIndent) -> Column & {
auto initialIndent(size_t newIndent) -> Column& {
m_initialIndent = newIndent;
return *this;
}
@@ -202,7 +202,7 @@ class Column {
auto begin() const -> iterator { return iterator(*this); }
auto end() const -> iterator { return {*this, m_strings.size()}; }
inline friend std::ostream &operator<<(std::ostream &os, Column const &col) {
inline friend std::ostream& operator<<(std::ostream& os, Column const& col) {
bool first = true;
for (auto line : col) {
if (first)
@@ -214,7 +214,7 @@ class Column {
return os;
}
auto operator+(Column const &other) -> Columns;
auto operator+(Column const& other) -> Columns;
auto toString() const -> std::string {
std::ostringstream oss;
@@ -236,34 +236,34 @@ class Columns {
friend Columns;
struct EndTag {};
std::vector<Column> const &m_columns;
std::vector<Column> const& m_columns;
std::vector<Column::iterator> m_iterators;
size_t m_activeIterators;
iterator(Columns const &columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0) {
iterator(Columns const& columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0) {
m_iterators.reserve(m_columns.size());
for (auto const &col : m_columns) m_iterators.push_back(col.end());
for (auto const& col : m_columns) m_iterators.push_back(col.end());
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type *;
using reference = value_type &;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::forward_iterator_tag;
explicit iterator(Columns const &columns)
explicit iterator(Columns const& columns)
: m_columns(columns.m_columns), m_activeIterators(m_columns.size()) {
m_iterators.reserve(m_columns.size());
for (auto const &col : m_columns) m_iterators.push_back(col.begin());
for (auto const& col : m_columns) m_iterators.push_back(col.begin());
}
auto operator==(iterator const &other) const -> bool {
auto operator==(iterator const& other) const -> bool {
return m_iterators == other.m_iterators;
}
auto operator!=(iterator const &other) const -> bool {
auto operator!=(iterator const& other) const -> bool {
return m_iterators != other.m_iterators;
}
auto operator*() const -> std::string {
@@ -284,7 +284,7 @@ class Columns {
}
return row;
}
auto operator++() -> iterator & {
auto operator++() -> iterator& {
for (size_t i = 0; i < m_columns.size(); ++i) {
if (m_iterators[i] != m_columns[i].end()) ++m_iterators[i];
}
@@ -301,17 +301,17 @@ class Columns {
auto begin() const -> iterator { return iterator(*this); }
auto end() const -> iterator { return {*this, iterator::EndTag()}; }
auto operator+=(Column const &col) -> Columns & {
auto operator+=(Column const& col) -> Columns& {
m_columns.push_back(col);
return *this;
}
auto operator+(Column const &col) -> Columns {
auto operator+(Column const& col) -> Columns {
Columns combined = *this;
combined += col;
return combined;
}
inline friend std::ostream &operator<<(std::ostream &os, Columns const &cols) {
inline friend std::ostream& operator<<(std::ostream& os, Columns const& cols) {
bool first = true;
for (auto line : cols) {
if (first)
@@ -330,7 +330,7 @@ class Columns {
}
};
inline auto Column::operator+(Column const &other) -> Columns {
inline auto Column::operator+(Column const& other) -> Columns {
Columns cols;
cols += *this;
cols += other;
@@ -381,7 +381,7 @@ class Args {
std::vector<std::string> m_args;
public:
Args(int argc, char const *const *argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
Args(int argc, char const* const* argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
Args(std::initializer_list<std::string> args)
: m_exeName(*args.begin()), m_args(args.begin() + 1, args.end()) {}
@@ -419,7 +419,7 @@ class TokenStream {
while (it != itEnd && it->empty()) ++it;
if (it != itEnd) {
auto const &next = *it;
auto const& next = *it;
if (isOptPrefix(next[0])) {
auto delimiterPos = next.find_first_of(" :=");
if (delimiterPos != std::string::npos) {
@@ -443,7 +443,7 @@ class TokenStream {
}
public:
explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
explicit TokenStream(Args const& args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) { loadBuffer(); }
@@ -456,12 +456,12 @@ class TokenStream {
return m_tokenBuffer.front();
}
auto operator->() const -> Token const * {
auto operator->() const -> Token const* {
assert(!m_tokenBuffer.empty());
return &m_tokenBuffer.front();
}
auto operator++() -> TokenStream & {
auto operator++() -> TokenStream& {
if (m_tokenBuffer.size() >= 2) {
m_tokenBuffer.erase(m_tokenBuffer.begin());
} else {
@@ -488,7 +488,7 @@ class ResultBase {
template <typename T>
class ResultValueBase : public ResultBase {
public:
auto value() const -> T const & {
auto value() const -> T const& {
enforceOk();
return m_value;
}
@@ -496,13 +496,13 @@ class ResultValueBase : public ResultBase {
protected:
ResultValueBase(Type type) : ResultBase(type) {}
ResultValueBase(ResultValueBase const &other) : ResultBase(other) {
ResultValueBase(ResultValueBase const& other) : ResultBase(other) {
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
}
ResultValueBase(Type, T const &value) : ResultBase(Ok) { new (&m_value) T(value); }
ResultValueBase(Type, T const& value) : ResultBase(Ok) { new (&m_value) T(value); }
auto operator=(ResultValueBase const &other) -> ResultValueBase & {
auto operator=(ResultValueBase const& other) -> ResultValueBase& {
if (m_type == ResultBase::Ok) m_value.~T();
ResultBase::operator=(other);
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
@@ -528,20 +528,20 @@ template <typename T = void>
class BasicResult : public ResultValueBase<T> {
public:
template <typename U>
explicit BasicResult(BasicResult<U> const &other)
explicit BasicResult(BasicResult<U> const& other)
: ResultValueBase<T>(other.type()), m_errorMessage(other.errorMessage()) {
assert(type() != ResultBase::Ok);
}
template <typename U>
static auto ok(U const &value) -> BasicResult {
static auto ok(U const& value) -> BasicResult {
return {ResultBase::Ok, value};
}
static auto ok() -> BasicResult { return {ResultBase::Ok}; }
static auto logicError(std::string const &message) -> BasicResult {
static auto logicError(std::string const& message) -> BasicResult {
return {ResultBase::LogicError, message};
}
static auto runtimeError(std::string const &message) -> BasicResult {
static auto runtimeError(std::string const& message) -> BasicResult {
return {ResultBase::RuntimeError, message};
}
@@ -560,7 +560,7 @@ class BasicResult : public ResultValueBase<T> {
std::string m_errorMessage; // Only populated if resultType is an error
BasicResult(ResultBase::Type type, std::string const &message)
BasicResult(ResultBase::Type type, std::string const& message)
: ResultValueBase<T>(type), m_errorMessage(message) {
assert(m_type != ResultBase::Ok);
}
@@ -573,7 +573,7 @@ enum class ParseResultType { Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
class ParseState {
public:
ParseState(ParseResultType type, TokenStream const &remainingTokens)
ParseState(ParseResultType type, TokenStream const& remainingTokens)
: m_type(type), m_remainingTokens(remainingTokens) {}
auto type() const -> ParseResultType { return m_type; }
@@ -594,7 +594,7 @@ struct HelpColumns {
};
template <typename T>
inline auto convertInto(std::string const &source, T &target) -> ParserResult {
inline auto convertInto(std::string const& source, T& target) -> ParserResult {
std::stringstream ss;
ss << source;
ss >> target;
@@ -603,11 +603,11 @@ inline auto convertInto(std::string const &source, T &target) -> ParserResult {
else
return ParserResult::ok(ParseResultType::Matched);
}
inline auto convertInto(std::string const &source, std::string &target) -> ParserResult {
inline auto convertInto(std::string const& source, std::string& target) -> ParserResult {
target = source;
return ParserResult::ok(ParseResultType::Matched);
}
inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
inline auto convertInto(std::string const& source, bool& target) -> ParserResult {
std::string srcLC = source;
std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(),
[](char c) { return static_cast<char>(::tolower(c)); });
@@ -622,7 +622,7 @@ inline auto convertInto(std::string const &source, bool &target) -> ParserResult
}
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
template <typename T>
inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target)
inline auto convertInto(std::string const& source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target)
-> ParserResult {
T temp;
auto result = convertInto(source, temp);
@@ -633,10 +633,10 @@ inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>
struct NonCopyable {
NonCopyable() = default;
NonCopyable(NonCopyable const &) = delete;
NonCopyable(NonCopyable &&) = delete;
NonCopyable &operator=(NonCopyable const &) = delete;
NonCopyable &operator=(NonCopyable &&) = delete;
NonCopyable(NonCopyable const&) = delete;
NonCopyable(NonCopyable&&) = delete;
NonCopyable& operator=(NonCopyable const&) = delete;
NonCopyable& operator=(NonCopyable&&) = delete;
};
struct BoundRef : NonCopyable {
@@ -645,7 +645,7 @@ struct BoundRef : NonCopyable {
virtual auto isFlag() const -> bool { return false; }
};
struct BoundValueRefBase : BoundRef {
virtual auto setValue(std::string const &arg) -> ParserResult = 0;
virtual auto setValue(std::string const& arg) -> ParserResult = 0;
};
struct BoundFlagRefBase : BoundRef {
virtual auto setFlag(bool flag) -> ParserResult = 0;
@@ -654,22 +654,22 @@ struct BoundFlagRefBase : BoundRef {
template <typename T>
struct BoundValueRef : BoundValueRefBase {
T &m_ref;
T& m_ref;
explicit BoundValueRef(T &ref) : m_ref(ref) {}
explicit BoundValueRef(T& ref) : m_ref(ref) {}
auto setValue(std::string const &arg) -> ParserResult override { return convertInto(arg, m_ref); }
auto setValue(std::string const& arg) -> ParserResult override { return convertInto(arg, m_ref); }
};
template <typename T>
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
std::vector<T> &m_ref;
std::vector<T>& m_ref;
explicit BoundValueRef(std::vector<T> &ref) : m_ref(ref) {}
explicit BoundValueRef(std::vector<T>& ref) : m_ref(ref) {}
auto isContainer() const -> bool override { return true; }
auto setValue(std::string const &arg) -> ParserResult override {
auto setValue(std::string const& arg) -> ParserResult override {
T temp;
auto result = convertInto(arg, temp);
if (result) m_ref.push_back(temp);
@@ -678,9 +678,9 @@ struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
};
struct BoundFlagRef : BoundFlagRefBase {
bool &m_ref;
bool& m_ref;
explicit BoundFlagRef(bool &ref) : m_ref(ref) {}
explicit BoundFlagRef(bool& ref) : m_ref(ref) {}
auto setFlag(bool flag) -> ParserResult override {
m_ref = flag;
@@ -694,7 +694,7 @@ struct LambdaInvoker {
"Lambda must return void or clara::ParserResult");
template <typename L, typename ArgType>
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult {
return lambda(arg);
}
};
@@ -702,14 +702,14 @@ struct LambdaInvoker {
template <>
struct LambdaInvoker<void> {
template <typename L, typename ArgType>
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult {
lambda(arg);
return ParserResult::ok(ParseResultType::Matched);
}
};
template <typename ArgType, typename L>
inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
inline auto invokeLambda(L const& lambda, std::string const& arg) -> ParserResult {
ArgType temp{};
auto result = convertInto(arg, temp);
return !result ? result
@@ -721,9 +721,9 @@ struct BoundLambda : BoundValueRefBase {
L m_lambda;
static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
explicit BoundLambda(L const &lambda) : m_lambda(lambda) {}
explicit BoundLambda(L const& lambda) : m_lambda(lambda) {}
auto setValue(std::string const &arg) -> ParserResult override {
auto setValue(std::string const& arg) -> ParserResult override {
return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
}
};
@@ -736,7 +736,7 @@ struct BoundFlagLambda : BoundFlagRefBase {
static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value,
"flags must be boolean");
explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) {}
explicit BoundFlagLambda(L const& lambda) : m_lambda(lambda) {}
auto setFlag(bool flag) -> ParserResult override {
return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
@@ -751,11 +751,11 @@ class ParserBase {
public:
virtual ~ParserBase() = default;
virtual auto validate() const -> Result { return Result::ok(); }
virtual auto parse(std::string const &exeName, TokenStream const &tokens) const
virtual auto parse(std::string const& exeName, TokenStream const& tokens) const
-> InternalParseResult = 0;
virtual auto cardinality() const -> size_t { return 1; }
auto parse(Args const &args) const -> InternalParseResult {
auto parse(Args const& args) const -> InternalParseResult {
return parse(args.exeName(), TokenStream(args));
}
};
@@ -764,10 +764,10 @@ template <typename DerivedT>
class ComposableParserImpl : public ParserBase {
public:
template <typename T>
auto operator|(T const &other) const -> Parser;
auto operator|(T const& other) const -> Parser;
template <typename T>
auto operator+(T const &other) const -> Parser;
auto operator+(T const& other) const -> Parser;
};
// Common code and state for Args and Opts
@@ -779,30 +779,30 @@ class ParserRefImpl : public ComposableParserImpl<DerivedT> {
std::string m_hint;
std::string m_description;
explicit ParserRefImpl(std::shared_ptr<BoundRef> const &ref) : m_ref(ref) {}
explicit ParserRefImpl(std::shared_ptr<BoundRef> const& ref) : m_ref(ref) {}
public:
template <typename T>
ParserRefImpl(T &ref, std::string const &hint)
ParserRefImpl(T& ref, std::string const& hint)
: m_ref(std::make_shared<BoundValueRef<T>>(ref)), m_hint(hint) {}
template <typename LambdaT>
ParserRefImpl(LambdaT const &ref, std::string const &hint)
ParserRefImpl(LambdaT const& ref, std::string const& hint)
: m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)), m_hint(hint) {}
auto operator()(std::string const &description) -> DerivedT & {
auto operator()(std::string const& description) -> DerivedT& {
m_description = description;
return static_cast<DerivedT &>(*this);
return static_cast<DerivedT&>(*this);
}
auto optional() -> DerivedT & {
auto optional() -> DerivedT& {
m_optionality = Optionality::Optional;
return static_cast<DerivedT &>(*this);
return static_cast<DerivedT&>(*this);
};
auto required() -> DerivedT & {
auto required() -> DerivedT& {
m_optionality = Optionality::Required;
return static_cast<DerivedT &>(*this);
return static_cast<DerivedT&>(*this);
};
auto isOptional() const -> bool { return m_optionality == Optionality::Optional; }
@@ -822,29 +822,29 @@ class ExeName : public ComposableParserImpl<ExeName> {
std::shared_ptr<BoundValueRefBase> m_ref;
template <typename LambdaT>
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
static auto makeRef(LambdaT const& lambda) -> std::shared_ptr<BoundValueRefBase> {
return std::make_shared<BoundLambda<LambdaT>>(lambda);
}
public:
ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
explicit ExeName(std::string &ref) : ExeName() {
explicit ExeName(std::string& ref) : ExeName() {
m_ref = std::make_shared<BoundValueRef<std::string>>(ref);
}
template <typename LambdaT>
explicit ExeName(LambdaT const &lambda) : ExeName() {
explicit ExeName(LambdaT const& lambda) : ExeName() {
m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
}
// The exe name is not parsed out of the normal tokens, but is handled specially
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
}
auto name() const -> std::string { return *m_name; }
auto set(std::string const &newName) -> ParserResult {
auto set(std::string const& newName) -> ParserResult {
auto lastSlash = newName.find_last_of("\\/");
auto filename = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1);
@@ -860,17 +860,17 @@ class Arg : public ParserRefImpl<Arg> {
public:
using ParserRefImpl::ParserRefImpl;
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
auto validationResult = validate();
if (!validationResult) return InternalParseResult(validationResult);
auto remainingTokens = tokens;
auto const &token = *remainingTokens;
auto const& token = *remainingTokens;
if (token.type != TokenType::Argument)
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
assert(!m_ref->isFlag());
auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
auto result = valueRef->setValue(remainingTokens->token);
if (!result)
@@ -880,7 +880,7 @@ class Arg : public ParserRefImpl<Arg> {
}
};
inline auto normaliseOpt(std::string const &optName) -> std::string {
inline auto normaliseOpt(std::string const& optName) -> std::string {
#ifdef CLARA_PLATFORM_WINDOWS
if (optName[0] == '/')
return "-" + optName.substr(1);
@@ -895,18 +895,18 @@ class Opt : public ParserRefImpl<Opt> {
public:
template <typename LambdaT>
explicit Opt(LambdaT const &ref)
explicit Opt(LambdaT const& ref)
: ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
explicit Opt(bool &ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
explicit Opt(bool& ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
template <typename LambdaT>
Opt(LambdaT const &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
Opt(LambdaT const& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
template <typename T>
Opt(T &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
Opt(T& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
auto operator[](std::string const &optName) -> Opt & {
auto operator[](std::string const& optName) -> Opt& {
m_optNames.push_back(optName);
return *this;
}
@@ -914,7 +914,7 @@ class Opt : public ParserRefImpl<Opt> {
auto getHelpColumns() const -> std::vector<HelpColumns> {
std::ostringstream oss;
bool first = true;
for (auto const &opt : m_optNames) {
for (auto const& opt : m_optNames) {
if (first)
first = false;
else
@@ -925,9 +925,9 @@ class Opt : public ParserRefImpl<Opt> {
return {{oss.str(), m_description}};
}
auto isMatch(std::string const &optToken) const -> bool {
auto isMatch(std::string const& optToken) const -> bool {
auto normalisedToken = normaliseOpt(optToken);
for (auto const &name : m_optNames) {
for (auto const& name : m_optNames) {
if (normaliseOpt(name) == normalisedToken) return true;
}
return false;
@@ -935,26 +935,26 @@ class Opt : public ParserRefImpl<Opt> {
using ParserBase::parse;
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
auto validationResult = validate();
if (!validationResult) return InternalParseResult(validationResult);
auto remainingTokens = tokens;
if (remainingTokens && remainingTokens->type == TokenType::Option) {
auto const &token = *remainingTokens;
auto const& token = *remainingTokens;
if (isMatch(token.token)) {
if (m_ref->isFlag()) {
auto flagRef = static_cast<detail::BoundFlagRefBase *>(m_ref.get());
auto flagRef = static_cast<detail::BoundFlagRefBase*>(m_ref.get());
auto result = flagRef->setFlag(true);
if (!result) return InternalParseResult(result);
if (result.value() == ParseResultType::ShortCircuitAll)
return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
} else {
auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
++remainingTokens;
if (!remainingTokens)
return InternalParseResult::runtimeError("Expected argument following " + token.token);
auto const &argToken = *remainingTokens;
auto const& argToken = *remainingTokens;
if (argToken.type != TokenType::Argument)
return InternalParseResult::runtimeError("Expected argument following " + token.token);
auto result = valueRef->setValue(argToken.token);
@@ -970,7 +970,7 @@ class Opt : public ParserRefImpl<Opt> {
auto validate() const -> Result override {
if (m_optNames.empty()) return Result::logicError("No options supplied to Opt");
for (auto const &name : m_optNames) {
for (auto const& name : m_optNames) {
if (name.empty()) return Result::logicError("Option name cannot be empty");
#ifdef CLARA_PLATFORM_WINDOWS
if (name[0] != '-' && name[0] != '/')
@@ -984,12 +984,12 @@ class Opt : public ParserRefImpl<Opt> {
};
struct Help : Opt {
Help(bool &showHelpFlag)
Help(bool& showHelpFlag)
: Opt([&](bool flag) {
showHelpFlag = flag;
return ParserResult::ok(ParseResultType::ShortCircuitAll);
}) {
static_cast<Opt &>(*this)("display usage information")["-?"]["-h"]["--help"].optional();
static_cast<Opt&>(*this)("display usage information")["-?"]["-h"]["--help"].optional();
}
};
@@ -998,57 +998,57 @@ struct Parser : ParserBase {
std::vector<Opt> m_options;
std::vector<Arg> m_args;
auto operator|=(ExeName const &exeName) -> Parser & {
auto operator|=(ExeName const& exeName) -> Parser& {
m_exeName = exeName;
return *this;
}
auto operator|=(Arg const &arg) -> Parser & {
auto operator|=(Arg const& arg) -> Parser& {
m_args.push_back(arg);
return *this;
}
auto operator|=(Opt const &opt) -> Parser & {
auto operator|=(Opt const& opt) -> Parser& {
m_options.push_back(opt);
return *this;
}
auto operator|=(Parser const &other) -> Parser & {
auto operator|=(Parser const& other) -> Parser& {
m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
return *this;
}
template <typename T>
auto operator|(T const &other) const -> Parser {
auto operator|(T const& other) const -> Parser {
return Parser(*this) |= other;
}
// Forward deprecated interface with '+' instead of '|'
template <typename T>
auto operator+=(T const &other) -> Parser & {
auto operator+=(T const& other) -> Parser& {
return operator|=(other);
}
template <typename T>
auto operator+(T const &other) const -> Parser {
auto operator+(T const& other) const -> Parser {
return operator|(other);
}
auto getHelpColumns() const -> std::vector<HelpColumns> {
std::vector<HelpColumns> cols;
for (auto const &o : m_options) {
for (auto const& o : m_options) {
auto childCols = o.getHelpColumns();
cols.insert(cols.end(), childCols.begin(), childCols.end());
}
return cols;
}
void writeToStream(std::ostream &os) const {
void writeToStream(std::ostream& os) const {
if (!m_exeName.name().empty()) {
os << "usage:\n"
<< " " << m_exeName.name() << " ";
bool required = true, first = true;
for (auto const &arg : m_args) {
for (auto const& arg : m_args) {
if (first)
first = false;
else
@@ -1068,28 +1068,28 @@ struct Parser : ParserBase {
auto rows = getHelpColumns();
size_t consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
size_t optWidth = 0;
for (auto const &cols : rows) optWidth = (std::max)(optWidth, cols.left.size() + 2);
for (auto const& cols : rows) optWidth = (std::max)(optWidth, cols.left.size() + 2);
optWidth = (std::min)(optWidth, consoleWidth / 2);
for (auto const &cols : rows) {
for (auto const& cols : rows) {
auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4) +
TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
os << row << std::endl;
}
}
friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream & {
friend auto operator<<(std::ostream& os, Parser const& parser) -> std::ostream& {
parser.writeToStream(os);
return os;
}
auto validate() const -> Result override {
for (auto const &opt : m_options) {
for (auto const& opt : m_options) {
auto result = opt.validate();
if (!result) return result;
}
for (auto const &arg : m_args) {
for (auto const& arg : m_args) {
auto result = arg.validate();
if (!result) return result;
}
@@ -1098,10 +1098,10 @@ struct Parser : ParserBase {
using ParserBase::parse;
auto parse(std::string const &exeName, TokenStream const &tokens) const
auto parse(std::string const& exeName, TokenStream const& tokens) const
-> InternalParseResult override {
struct ParserInfo {
ParserBase const *parser = nullptr;
ParserBase const* parser = nullptr;
size_t count = 0;
};
const size_t totalParsers = m_options.size() + m_args.size();
@@ -1111,8 +1111,8 @@ struct Parser : ParserBase {
{
size_t i = 0;
for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
for (auto const& opt : m_options) parseInfos[i++].parser = &opt;
for (auto const& arg : m_args) parseInfos[i++].parser = &arg;
}
m_exeName.set(exeName);
@@ -1122,7 +1122,7 @@ struct Parser : ParserBase {
bool tokenParsed = false;
for (size_t i = 0; i < totalParsers; ++i) {
auto &parseInfo = parseInfos[i];
auto& parseInfo = parseInfos[i];
if (parseInfo.parser->cardinality() == 0 ||
parseInfo.count < parseInfo.parser->cardinality()) {
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
@@ -1147,8 +1147,8 @@ struct Parser : ParserBase {
template <typename DerivedT>
template <typename T>
auto ComposableParserImpl<DerivedT>::operator|(T const &other) const -> Parser {
return Parser() | static_cast<DerivedT const &>(*this) | other;
auto ComposableParserImpl<DerivedT>::operator|(T const& other) const -> Parser {
return Parser() | static_cast<DerivedT const&>(*this) | other;
}
} // namespace detail
+16 -4
View File
@@ -20,6 +20,8 @@ extern std::list<pid_t> reap;
namespace waybar::util::command {
constexpr int kExecFailureExitCode = 127;
struct res {
int exit_code;
std::string out;
@@ -59,6 +61,7 @@ inline int close(FILE* fp, pid_t pid) {
spdlog::debug("Cmd continued");
} else if (ret == -1) {
spdlog::debug("waitpid failed: {}", strerror(errno));
break;
} else {
break;
}
@@ -109,11 +112,13 @@ inline FILE* open(const std::string& cmd, int& pid, const std::string& output_na
::close(fd[0]);
dup2(fd[1], 1);
setpgid(child_pid, child_pid);
if (output_name != "") {
if (!output_name.empty()) {
setenv("WAYBAR_OUTPUT_NAME", output_name.c_str(), 1);
}
execlp("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
exit(0);
const int saved_errno = errno;
spdlog::error("execlp(/bin/sh) failed in open: {}", strerror(saved_errno));
_exit(kExecFailureExitCode);
} else {
::close(fd[1]);
}
@@ -138,7 +143,7 @@ inline struct res execNoRead(const std::string& cmd) {
return {WEXITSTATUS(stat), ""};
}
inline int32_t forkExec(const std::string& cmd) {
inline int32_t forkExec(const std::string& cmd, const std::string& output_name) {
if (cmd == "") return -1;
pid_t pid = fork();
@@ -157,8 +162,13 @@ inline int32_t forkExec(const std::string& cmd) {
err = pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
if (err != 0) spdlog::error("pthread_sigmask in forkExec failed: {}", strerror(err));
setpgid(pid, pid);
if (!output_name.empty()) {
setenv("WAYBAR_OUTPUT_NAME", output_name.c_str(), 1);
}
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
exit(0);
const int saved_errno = errno;
spdlog::error("execl(/bin/sh) failed in forkExec: {}", strerror(saved_errno));
_exit(kExecFailureExitCode);
} else {
reap_mtx.lock();
reap.push_back(pid);
@@ -169,4 +179,6 @@ inline int32_t forkExec(const std::string& cmd) {
return pid;
}
inline int32_t forkExec(const std::string& cmd) { return forkExec(cmd, ""); }
} // namespace waybar::util::command
+9 -9
View File
@@ -17,18 +17,18 @@ class IconLoader {
std::vector<Glib::RefPtr<Gtk::IconTheme>> custom_icon_themes_;
Glib::RefPtr<Gtk::IconTheme> default_icon_theme_ = Gtk::IconTheme::get_default();
static std::vector<std::string> search_prefix();
static Glib::RefPtr<Gio::DesktopAppInfo> get_app_info_by_name(const std::string &app_id);
static Glib::RefPtr<Gio::DesktopAppInfo> get_desktop_app_info(const std::string &app_id);
static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string const &icon_path, int size);
static std::string get_icon_name_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
const std::string &app_id);
static bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
static Glib::RefPtr<Gio::DesktopAppInfo> get_app_info_by_name(const std::string& app_id);
static Glib::RefPtr<Gio::DesktopAppInfo> get_desktop_app_info(const std::string& app_id);
static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string const& icon_path, int size);
static std::string get_icon_name_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
const std::string& app_id);
static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);
public:
void add_custom_icon_theme(const std::string &theme_name);
bool image_load_icon(Gtk::Image &image, Glib::RefPtr<Gio::DesktopAppInfo> app_info,
void add_custom_icon_theme(const std::string& theme_name);
bool image_load_icon(Gtk::Image& image, Glib::RefPtr<Gio::DesktopAppInfo> app_info,
int size) const;
static Glib::RefPtr<Gio::DesktopAppInfo> get_app_info_from_app_id_list(
const std::string &app_id_list);
const std::string& app_id_list);
};
+4 -3
View File
@@ -30,15 +30,16 @@ class JsonParser {
std::istringstream jsonStream(modifiedJsonStr);
std::string errs;
if (!Json::parseFromStream(m_readerBuilder, jsonStream, &root, &errs)) {
// Use local CharReaderBuilder for thread safety - the IPC singleton's
// parser can be called concurrently from multiple module threads
Json::CharReaderBuilder readerBuilder;
if (!Json::parseFromStream(readerBuilder, jsonStream, &root, &errs)) {
throw std::runtime_error("Error parsing JSON: " + errs);
}
return root;
}
private:
Json::CharReaderBuilder m_readerBuilder;
static std::string replaceHexadecimalEscape(const std::string& str) {
static std::regex re("\\\\x");
return std::regex_replace(str, re, "\\u00");
+2 -2
View File
@@ -33,14 +33,14 @@ class PrivacyNodeInfo {
struct spa_hook object_listener;
struct spa_hook proxy_listener;
void *data;
void* data;
std::string getName();
std::string getIconName();
// Handlers for PipeWire events
void handleProxyEventDestroy();
void handleNodeEventInfo(const struct pw_node_info *info);
void handleNodeEventInfo(const struct pw_node_info* info);
};
} // namespace waybar::util::PipewireBackend
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include <unistd.h>
namespace waybar::util {
class ScopedFd {
public:
explicit ScopedFd(int fd = -1) : fd_(fd) {}
~ScopedFd() {
if (fd_ != -1) {
close(fd_);
}
}
// ScopedFd is non-copyable
ScopedFd(const ScopedFd&) = delete;
ScopedFd& operator=(const ScopedFd&) = delete;
// ScopedFd is moveable
ScopedFd(ScopedFd&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
ScopedFd& operator=(ScopedFd&& other) noexcept {
if (this != &other) {
if (fd_ != -1) {
close(fd_);
}
fd_ = other.fd_;
other.fd_ = -1;
}
return *this;
}
int get() const { return fd_; }
operator int() const { return fd_; }
void reset(int fd = -1) {
if (fd_ != -1) {
close(fd_);
}
fd_ = fd;
}
int release() {
int fd = fd_;
fd_ = -1;
return fd;
}
private:
int fd_;
};
} // namespace waybar::util
+30 -14
View File
@@ -1,5 +1,6 @@
#pragma once
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <ctime>
@@ -31,8 +32,8 @@ class SleeperThread {
SleeperThread(std::function<void()> func)
: thread_{[this, func] {
while (do_run_) {
signal_ = false;
while (do_run_.load(std::memory_order_relaxed)) {
signal_.store(false, std::memory_order_relaxed);
func();
}
}} {
@@ -42,9 +43,18 @@ class SleeperThread {
}
SleeperThread& operator=(std::function<void()> func) {
if (thread_.joinable()) {
stop();
thread_.join();
}
{
std::lock_guard<std::mutex> lck(mutex_);
do_run_.store(true, std::memory_order_relaxed);
signal_.store(false, std::memory_order_relaxed);
}
thread_ = std::thread([this, func] {
while (do_run_) {
signal_ = false;
while (do_run_.load(std::memory_order_relaxed)) {
signal_.store(false, std::memory_order_relaxed);
func();
}
});
@@ -56,12 +66,14 @@ class SleeperThread {
return *this;
}
bool isRunning() const { return do_run_; }
bool isRunning() const { return do_run_.load(std::memory_order_relaxed); }
auto sleep() {
std::unique_lock lk(mutex_);
CancellationGuard cancel_lock;
return condvar_.wait(lk, [this] { return signal_ || !do_run_; });
return condvar_.wait(lk, [this] {
return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
});
}
auto sleep_for(std::chrono::system_clock::duration dur) {
@@ -73,7 +85,9 @@ class SleeperThread {
if (now < max_time_point - dur) {
wait_end = now + dur;
}
return condvar_.wait_until(lk, wait_end, [this] { return signal_ || !do_run_; });
return condvar_.wait_until(lk, wait_end, [this] {
return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
});
}
auto sleep_until(
@@ -81,22 +95,24 @@ class SleeperThread {
time_point) {
std::unique_lock lk(mutex_);
CancellationGuard cancel_lock;
return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; });
return condvar_.wait_until(lk, time_point, [this] {
return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
});
}
void wake_up() {
{
std::lock_guard<std::mutex> lck(mutex_);
signal_ = true;
signal_.store(true, std::memory_order_relaxed);
}
condvar_.notify_all();
}
auto stop() {
void stop() {
{
std::lock_guard<std::mutex> lck(mutex_);
signal_ = true;
do_run_ = false;
signal_.store(true, std::memory_order_relaxed);
do_run_.store(false, std::memory_order_relaxed);
}
condvar_.notify_all();
auto handle = thread_.native_handle();
@@ -118,8 +134,8 @@ class SleeperThread {
std::thread thread_;
std::condition_variable condvar_;
std::mutex mutex_;
bool do_run_ = true;
bool signal_ = false;
std::atomic<bool> do_run_ = true;
std::atomic<bool> signal_ = false;
sigc::connection connection_;
};
+4 -4
View File
@@ -4,18 +4,18 @@
namespace waybar::util {
struct UdevDeleter {
void operator()(udev *ptr) const { udev_unref(ptr); }
void operator()(udev* ptr) const { udev_unref(ptr); }
};
struct UdevDeviceDeleter {
void operator()(udev_device *ptr) const { udev_device_unref(ptr); }
void operator()(udev_device* ptr) const { udev_device_unref(ptr); }
};
struct UdevEnumerateDeleter {
void operator()(udev_enumerate *ptr) const { udev_enumerate_unref(ptr); }
void operator()(udev_enumerate* ptr) const { udev_enumerate_unref(ptr); }
};
struct UdevMonitorDeleter {
void operator()(udev_monitor *ptr) const { udev_monitor_unref(ptr); }
void operator()(udev_monitor* ptr) const { udev_monitor_unref(ptr); }
};
} // namespace waybar::util
+1 -1
View File
@@ -2,4 +2,4 @@
#include <glibmm/ustring.h>
// calculate column width of ustring
int ustring_clen(const Glib::ustring &str);
int ustring_clen(const Glib::ustring& str);
+4 -1
View File
@@ -182,6 +182,7 @@ Every entry in the *events* object consists of a *<event-name>* (typeof: *string
- *on-<status>-<state>*
- *on-<status>-<capacity>*
- *on-<status>*
Where:
@@ -203,7 +204,9 @@ Where:
"events": {
"on-discharging-warning": "notify-send -u normal 'Low Battery'",
"on-discharging-critical": "notify-send -u critical 'Very Low Battery'",
"on-charging-100": "notify-send -u normal 'Battery Full!'"
"on-charging-100": "notify-send -u normal 'Battery Full!'",
"on-discharging": "notify-send -u normal 'Power Switch' Discharging",
"on-charging": "notify-send -u normal 'Power Switch' Charging'"
},
"format": "{capacity}% {icon}",
"format-icons": ["", "", "", "", ""],
+5
View File
@@ -130,6 +130,11 @@ This setting is ignored if *workspace-taskbar.enable* is set to true.
Otherwise, the workspace will open on the monitor where it was previously assigned.
Analog to using `focusworkspaceoncurrentmonitor` dispatcher instead of `workspace` in Hyprland.
*enable-bar-scroll*: ++
typeof: bool ++
default: false ++
If set to false, you can't scroll to cycle throughout workspaces from the entire bar. If set to true this behaviour is enabled.
*ignore-workspaces*: ++
typeof: array ++
default: [] ++
+2 -1
View File
@@ -26,7 +26,8 @@ The *image* module displays an image from a path.
*interval*: ++
typeof: integer or float ++
The interval (in seconds) to re-render the image. ++
Minimum value is 0.001 (1ms). Values smaller than 1ms will be set to 1ms. ++
If set to a positive value, the minimum is 0.001 (1ms). Values smaller than 1ms will be set to 1ms. ++
Zero or negative values are treated as "once". ++
This is useful if the contents of *path* changes. ++
If no *interval* is defined, the image will only be rendered once.
+1 -1
View File
@@ -36,7 +36,7 @@ The visual display elements for waybar use a CSS stylesheet, see *waybar-styles(
*expand-right* ++
typeof: bool ++
default: false ++
Enables the modules-left to consume all left over space dynamically.
Enables the modules-right to consume all left over space dynamically.
*layer* ++
typeof: string ++
+1 -1
View File
@@ -1,6 +1,6 @@
project(
'waybar', 'cpp', 'c',
version: '0.14.0',
version: '0.15.0',
license: 'MIT',
meson_version: '>= 0.59.0',
default_options : [
+13 -8
View File
@@ -151,19 +151,24 @@ void AAppIconLabel::updateAppIconName(const std::string& app_identifier,
}
void AAppIconLabel::updateAppIcon() {
if (update_app_icon_) {
if (update_app_icon_ || (!iconEnabled() && image_.get_visible())) {
update_app_icon_ = false;
if (app_icon_name_.empty()) {
image_.set_visible(false);
} else if (app_icon_name_.front() == '/') {
auto pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_);
int scaled_icon_size = app_icon_size_ * image_.get_scale_factor();
pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_, scaled_icon_size, scaled_icon_size);
try {
int scaled_icon_size = app_icon_size_ * image_.get_scale_factor();
auto pixbuf =
Gdk::Pixbuf::create_from_file(app_icon_name_, scaled_icon_size, scaled_icon_size);
auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(),
image_.get_window());
image_.set(surface);
image_.set_visible(true);
auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(),
image_.get_window());
image_.set(surface);
image_.set_visible(true);
} catch (const Glib::Exception& e) {
spdlog::warn("Failed to load app icon {}: {}", app_icon_name_, std::string(e.what()));
image_.set_visible(false);
}
} else {
image_.set_from_icon_name(app_icon_name_, Gtk::ICON_SIZE_INVALID);
image_.set_visible(true);
+2 -2
View File
@@ -7,8 +7,8 @@
namespace waybar {
AIconLabel::AIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
const std::string &format, uint16_t interval, bool ellipsize,
AIconLabel::AIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
const std::string& format, uint16_t interval, bool ellipsize,
bool enable_click, bool enable_scroll)
: ALabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) {
if (config["icon-size"].isUInt()) {
+17 -5
View File
@@ -26,7 +26,7 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
: std::chrono::milliseconds(
(config_["interval"].isNumeric()
? std::max(1L, // Minimum 1ms due to millisecond precision
static_cast<long>(config_["interval"].asDouble()) * 1000)
static_cast<long>(config_["interval"].asDouble() * 1000))
: 1000 * (long)interval))),
default_format_(format_) {
label_.set_name(name);
@@ -91,13 +91,17 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
// Make the GtkBuilder and check for errors in his parsing
if (gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr) == 0U) {
g_object_unref(builder);
throw std::runtime_error("Error found in the file " + menuFile);
}
menu_ = gtk_builder_get_object(builder, "menu");
if (menu_ == nullptr) {
g_object_unref(builder);
throw std::runtime_error("Failed to get 'menu' object from GtkBuilder");
}
// Keep the menu alive after dropping the transient GtkBuilder.
g_object_ref(menu_);
submenus_ = std::map<std::string, GtkMenuItem*>();
menuActionsMap_ = std::map<std::string, std::string>();
@@ -105,11 +109,17 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
for (Json::Value::const_iterator it = config_["menu-actions"].begin();
it != config_["menu-actions"].end(); ++it) {
std::string key = it.key().asString();
submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str()));
auto* item = gtk_builder_get_object(builder, key.c_str());
if (item == nullptr) {
spdlog::warn("Menu item '{}' not found in builder file", key);
continue;
}
submenus_[key] = GTK_MENU_ITEM(item);
menuActionsMap_[key] = it->asString();
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent),
(gpointer)menuActionsMap_[key].c_str());
}
g_object_unref(builder);
} catch (std::runtime_error& e) {
spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what());
}
@@ -141,7 +151,8 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_
if (format_icons.isArray()) {
auto size = format_icons.size();
if (size != 0U) {
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
auto divisor = std::max(1U, (max == 0 ? 100U : static_cast<unsigned>(max)) / size);
auto idx = std::clamp(percentage / divisor, 0U, size - 1);
format_icons = format_icons[idx];
}
}
@@ -167,7 +178,8 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector<std::string>&
if (format_icons.isArray()) {
auto size = format_icons.size();
if (size != 0U) {
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
auto divisor = std::max(1U, (max == 0 ? 100U : static_cast<unsigned>(max)) / size);
auto idx = std::clamp(percentage / divisor, 0U, size - 1);
format_icons = format_icons[idx];
}
}
@@ -190,7 +202,7 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
}
void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) {
waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu");
waybar::util::command::forkExec((char*)data, "GtkMenu");
}
std::string ALabel::getState(uint8_t value, bool lesser) {
+6 -2
View File
@@ -88,6 +88,10 @@ AModule::~AModule() {
killpg(pid, SIGTERM);
}
}
if (menu_ != nullptr) {
g_object_unref(menu_);
menu_ = nullptr;
}
}
auto AModule::update() -> void {
@@ -166,9 +170,9 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
}
// Check that a menu has been configured
if (config_["menu"].isString()) {
if (rec != eventMap_.cend() && config_["menu"].isString()) {
// Check if the event is the one specified for the "menu" option
if (rec->second == config_["menu"].asString()) {
if (rec->second == config_["menu"].asString() && menu_ != nullptr) {
// Popup the menu
gtk_widget_show_all(GTK_WIDGET(menu_));
gtk_menu_popup_at_pointer(GTK_MENU(menu_), reinterpret_cast<GdkEvent*>(e));
+2 -1
View File
@@ -229,7 +229,8 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
gtk_layer_init_for_window(gtk_window);
gtk_layer_set_keyboard_mode(gtk_window, GTK_LAYER_SHELL_KEYBOARD_MODE_NONE);
gtk_layer_set_monitor(gtk_window, output->monitor->gobj());
gtk_layer_set_namespace(gtk_window, "waybar");
gtk_layer_set_namespace(gtk_window,
config["name"].isString() ? config["name"].asCString() : "waybar");
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, margins_.left);
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right);
+36 -36
View File
@@ -11,60 +11,60 @@
#include "util/clara.hpp"
#include "util/format.hpp"
waybar::Client *waybar::Client::inst() {
static auto *c = new Client();
waybar::Client* waybar::Client::inst() {
static auto* c = new Client();
return c;
}
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) {
auto *client = static_cast<Client *>(data);
void waybar::Client::handleGlobal(void* data, struct wl_registry* registry, uint32_t name,
const char* interface, uint32_t version) {
auto* client = static_cast<Client*>(data);
if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1*>(wl_registry_bind(
registry, name, &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION));
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
client->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1 *>(
client->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1*>(
wl_registry_bind(registry, name, &zwp_idle_inhibit_manager_v1_interface, 1));
}
}
void waybar::Client::handleGlobalRemove(void *data, struct wl_registry * /*registry*/,
void waybar::Client::handleGlobalRemove(void* data, struct wl_registry* /*registry*/,
uint32_t name) {
// Nothing here
}
void waybar::Client::handleOutput(struct waybar_output &output) {
void waybar::Client::handleOutput(struct waybar_output& output) {
static const struct zxdg_output_v1_listener xdgOutputListener = {
.logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
.logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
.logical_position = [](void*, struct zxdg_output_v1*, int32_t, int32_t) {},
.logical_size = [](void*, struct zxdg_output_v1*, int32_t, int32_t) {},
.done = &handleOutputDone,
.name = &handleOutputName,
.description = &handleOutputDescription,
};
// owned by output->monitor; no need to destroy
auto *wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
auto* wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
}
struct waybar::waybar_output &waybar::Client::getOutput(void *addr) {
struct waybar::waybar_output& waybar::Client::getOutput(void* addr) {
auto it = std::find_if(outputs_.begin(), outputs_.end(),
[&addr](const auto &output) { return &output == addr; });
[&addr](const auto& output) { return &output == addr; });
if (it == outputs_.end()) {
throw std::runtime_error("Unable to find valid output");
}
return *it;
}
std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &output) {
std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output& output) {
return config.getOutputConfigs(output.name, output.identifier);
}
void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_output*/) {
auto *client = waybar::Client::inst();
void waybar::Client::handleOutputDone(void* data, struct zxdg_output_v1* /*xdg_output*/) {
auto* client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
auto& output = client->getOutput(data);
/**
* Multiple .done events may arrive in batch. In this case libwayland would queue
* xdg_output.destroy and dispatch all pending events, triggering this callback several times
@@ -80,44 +80,44 @@ void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_
auto configs = client->getOutputConfigs(output);
if (!configs.empty()) {
for (const auto &config : configs) {
for (const auto& config : configs) {
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
}
}
}
} catch (const std::exception &e) {
} catch (const std::exception& e) {
spdlog::warn("caught exception in zxdg_output_v1_listener::done: {}", e.what());
}
}
void waybar::Client::handleOutputName(void *data, struct zxdg_output_v1 * /*xdg_output*/,
const char *name) {
auto *client = waybar::Client::inst();
void waybar::Client::handleOutputName(void* data, struct zxdg_output_v1* /*xdg_output*/,
const char* name) {
auto* client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
auto& output = client->getOutput(data);
output.name = name;
} catch (const std::exception &e) {
} catch (const std::exception& e) {
spdlog::warn("caught exception in zxdg_output_v1_listener::name: {}", e.what());
}
}
void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 * /*xdg_output*/,
const char *description) {
auto *client = waybar::Client::inst();
void waybar::Client::handleOutputDescription(void* data, struct zxdg_output_v1* /*xdg_output*/,
const char* description) {
auto* client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
auto& output = client->getOutput(data);
// Description format: "identifier (name)"
auto s = std::string(description);
auto pos = s.find(" (");
output.identifier = pos != std::string::npos ? s.substr(0, pos) : s;
} catch (const std::exception &e) {
} catch (const std::exception& e) {
spdlog::warn("caught exception in zxdg_output_v1_listener::description: {}", e.what());
}
}
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
auto &output = outputs_.emplace_back();
auto& output = outputs_.emplace_back();
output.monitor = std::move(monitor);
handleOutput(output);
}
@@ -146,10 +146,10 @@ void waybar::Client::handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> mon
++it;
}
}
outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; });
outputs_.remove_if([&monitor](const auto& output) { return output.monitor == monitor; });
}
const std::string waybar::Client::getStyle(const std::string &style,
const std::string waybar::Client::getStyle(const std::string& style,
std::optional<Appearance> appearance = std::nullopt) {
auto gtk_settings = Gtk::Settings::get_default();
std::optional<std::string> css_file;
@@ -182,7 +182,7 @@ const std::string waybar::Client::getStyle(const std::string &style,
return css_file.value();
};
auto waybar::Client::setupCss(const std::string &css_file) -> void {
auto waybar::Client::setupCss(const std::string& css_file) -> void {
auto screen = Gdk::Screen::get_default();
if (!screen) {
throw std::runtime_error("No default screen");
@@ -238,7 +238,7 @@ void waybar::Client::bindInterfaces() {
sigc::mem_fun(*this, &Client::handleMonitorRemoved));
}
int waybar::Client::main(int argc, char *argv[]) {
int waybar::Client::main(int argc, char* argv[]) {
bool show_help = false;
bool show_version = false;
std::string config_opt;
@@ -299,7 +299,7 @@ int waybar::Client::main(int argc, char *argv[]) {
if (m_config.isObject() && m_config["reload_style_on_change"].asBool()) {
m_cssReloadHelper->monitorChanges();
} else if (m_config.isArray()) {
for (const auto &conf : m_config) {
for (const auto& conf : m_config) {
if (conf["reload_style_on_change"].asBool()) {
m_cssReloadHelper->monitorChanges();
break;
+28 -28
View File
@@ -23,10 +23,10 @@ const std::vector<std::string> Config::CONFIG_DIRS = {
"/etc/xdg/waybar/", SYSCONFDIR "/xdg/waybar/", "./resources/",
};
const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
const char* Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
std::vector<std::string> Config::tryExpandPath(const std::string &base,
const std::string &filename) {
std::vector<std::string> Config::tryExpandPath(const std::string& base,
const std::string& filename) {
fs::path path;
if (!filename.empty()) {
@@ -65,18 +65,18 @@ std::vector<std::string> Config::tryExpandPath(const std::string &base,
return results;
}
std::optional<std::string> Config::findConfigPath(const std::vector<std::string> &names,
const std::vector<std::string> &dirs) {
if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) {
for (const auto &name : names) {
std::optional<std::string> Config::findConfigPath(const std::vector<std::string>& names,
const std::vector<std::string>& dirs) {
if (const char* dir = std::getenv(Config::CONFIG_PATH_ENV)) {
for (const auto& name : names) {
if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res.front();
}
}
}
for (const auto &dir : dirs) {
for (const auto &name : names) {
for (const auto& dir : dirs) {
for (const auto& name : names) {
if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res.front();
}
@@ -85,7 +85,7 @@ std::optional<std::string> Config::findConfigPath(const std::vector<std::string>
return std::nullopt;
}
void Config::setupConfig(Json::Value &dst, const std::string &config_file, int depth) {
void Config::setupConfig(Json::Value& dst, const std::string& config_file, int depth) {
if (depth > 100) {
throw std::runtime_error("Aborting due to likely recursive include in config files");
}
@@ -97,7 +97,7 @@ void Config::setupConfig(Json::Value &dst, const std::string &config_file, int d
util::JsonParser parser;
Json::Value tmp_config = parser.parse(str);
if (tmp_config.isArray()) {
for (auto &config_part : tmp_config) {
for (auto& config_part : tmp_config) {
resolveConfigIncludes(config_part, depth);
}
} else {
@@ -106,18 +106,18 @@ void Config::setupConfig(Json::Value &dst, const std::string &config_file, int d
mergeConfig(dst, tmp_config);
}
std::vector<std::string> Config::findIncludePath(const std::string &name,
const std::vector<std::string> &dirs) {
std::vector<std::string> Config::findIncludePath(const std::string& name,
const std::vector<std::string>& dirs) {
auto match1 = tryExpandPath(name, "");
if (!match1.empty()) {
return match1;
}
if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) {
if (const char* dir = std::getenv(Config::CONFIG_PATH_ENV)) {
if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res;
}
}
for (const auto &dir : dirs) {
for (const auto& dir : dirs) {
if (auto res = tryExpandPath(dir, name); !res.empty()) {
return res;
}
@@ -126,14 +126,14 @@ std::vector<std::string> Config::findIncludePath(const std::string &name,
return {};
}
void Config::resolveConfigIncludes(Json::Value &config, int depth) {
void Config::resolveConfigIncludes(Json::Value& config, int depth) {
Json::Value includes = config["include"];
if (includes.isArray()) {
for (const auto &include : includes) {
for (const auto& include : includes) {
spdlog::info("Including resource file: {}", include.asString());
auto matches = findIncludePath(include.asString());
if (!matches.empty()) {
for (const auto &match : matches) {
for (const auto& match : matches) {
setupConfig(config, match, depth + 1);
}
} else {
@@ -144,7 +144,7 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) {
spdlog::info("Including resource file: {}", includes.asString());
auto matches = findIncludePath(includes.asString());
if (!matches.empty()) {
for (const auto &match : matches) {
for (const auto& match : matches) {
setupConfig(config, match, depth + 1);
}
} else {
@@ -153,12 +153,12 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) {
}
}
void Config::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) {
void Config::mergeConfig(Json::Value& a_config_, Json::Value& b_config_) {
if (!a_config_) {
// For the first config
a_config_ = b_config_;
} else if (a_config_.isObject() && b_config_.isObject()) {
for (const auto &key : b_config_.getMemberNames()) {
for (const auto& key : b_config_.getMemberNames()) {
// [] creates key with default value. Use `get` to avoid that.
if (a_config_.get(key, Json::Value::nullSingleton()).isObject() &&
b_config_[key].isObject()) {
@@ -174,10 +174,10 @@ void Config::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) {
spdlog::error("Cannot merge config, conflicting or invalid JSON types");
}
}
bool isValidOutput(const Json::Value &config, const std::string &name,
const std::string &identifier) {
bool isValidOutput(const Json::Value& config, const std::string& name,
const std::string& identifier) {
if (config["output"].isArray()) {
for (auto const &output_conf : config["output"]) {
for (auto const& output_conf : config["output"]) {
if (output_conf.isString()) {
auto config_output = output_conf.asString();
if (config_output.substr(0, 1) == "!") {
@@ -211,7 +211,7 @@ bool isValidOutput(const Json::Value &config, const std::string &name,
return true;
}
void Config::load(const std::string &config) {
void Config::load(const std::string& config) {
auto file = config.empty() ? findConfigPath({"config", "config.jsonc"}) : config;
if (!file) {
throw std::runtime_error("Missing required resource files");
@@ -222,11 +222,11 @@ void Config::load(const std::string &config) {
setupConfig(config_, config_file_, 0);
}
std::vector<Json::Value> Config::getOutputConfigs(const std::string &name,
const std::string &identifier) {
std::vector<Json::Value> Config::getOutputConfigs(const std::string& name,
const std::string& identifier) {
std::vector<Json::Value> configs;
if (config_.isArray()) {
for (auto const &config : config_) {
for (auto const& config : config_) {
if (config.isObject() && isValidOutput(config, name, identifier)) {
configs.push_back(config);
}
+5
View File
@@ -124,6 +124,11 @@ auto Group::update() -> void {
// noop
}
bool Group::handleScroll(GdkEventScroll* e) {
// no scroll.
return true;
}
Gtk::Box& Group::getBox() { return is_drawer ? (is_first_widget ? box : revealer_box) : box; }
void Group::addWidget(Gtk::Widget& widget) {
+9 -5
View File
@@ -33,7 +33,10 @@ static void writeSignalToPipe(int signum) {
// to `signal_handler`.
static void catchSignals(waybar::SafeSignal<int>& signal_handler) {
int fd[2];
pipe(fd);
if (pipe(fd) != 0) {
spdlog::error("Failed to create signal pipe: {}", strerror(errno));
return;
}
int signal_pipe_read_fd = fd[0];
signal_pipe_write_fd = fd[1];
@@ -137,15 +140,16 @@ static void handleSignalMainThread(int signum, bool& reload) {
break;
case SIGCHLD:
spdlog::debug("Received SIGCHLD in signalThread");
if (!reap.empty()) {
reap_mtx.lock();
for (auto it = reap.begin(); it != reap.end(); ++it) {
{
std::lock_guard<std::mutex> lock(reap_mtx);
for (auto it = reap.begin(); it != reap.end();) {
if (waitpid(*it, nullptr, WNOHANG) == *it) {
spdlog::debug("Reaped child with PID: {}", *it);
it = reap.erase(it);
} else {
++it;
}
}
reap_mtx.unlock();
}
break;
default:
+6 -6
View File
@@ -13,7 +13,7 @@
#include "util/backend_common.hpp"
#include "util/backlight_backend.hpp"
waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config)
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() : ""),
backend(interval_, [this] { dp.emit(); }) {
@@ -58,11 +58,11 @@ auto waybar::modules::Backlight::update() -> void {
tooltip_format = config_["tooltip-format"].asString();
}
if (!tooltip_format.empty()) {
label_.set_tooltip_text(fmt::format(fmt::runtime(tooltip_format),
fmt::arg("percent", percent),
fmt::arg("icon", getIcon(percent))));
label_.set_tooltip_markup(fmt::format(fmt::runtime(tooltip_format),
fmt::arg("percent", percent),
fmt::arg("icon", getIcon(percent))));
} else {
label_.set_tooltip_text(desc);
label_.set_tooltip_markup(desc);
}
}
} else {
@@ -79,7 +79,7 @@ auto waybar::modules::Backlight::update() -> void {
ALabel::update();
}
bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) {
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);
+15 -10
View File
@@ -139,7 +139,9 @@ void waybar::modules::Battery::refreshBatteries() {
auto event_path = (node.path() / "uevent");
auto wd = inotify_add_watch(battery_watch_fd_, event_path.c_str(), IN_ACCESS);
if (wd < 0) {
throw std::runtime_error("Could not watch events for " + node.path().string());
spdlog::warn("Could not watch events for {} (device may have been removed)",
node.path().string());
continue;
}
batteries_[node.path()] = wd;
}
@@ -686,7 +688,7 @@ auto waybar::modules::Battery::update() -> void {
status = getAdapterStatus(capacity);
}
auto status_pretty = status;
puts(status.c_str());
// Transform to lowercase and replace space with dash
std::ranges::transform(status.begin(), status.end(), status.begin(),
[](char ch) { return ch == ' ' ? '-' : std::tolower(ch); });
@@ -790,16 +792,19 @@ void waybar::modules::Battery::processEvents(std::string& state, std::string& st
if (!events.isObject() || events.empty()) {
return;
}
std::string event_name = fmt::format("on-{}-{}", status == "discharging" ? status : "charging",
state.empty() ? std::to_string(capacity) : state);
auto exec = [](Json::Value const& event) {
if (!event.isString()) return;
if (auto command = event.asString(); !command.empty()) {
util::command::exec(command, "");
}
};
std::string status_name = status == "discharging" ? "on-discharging" : "on-charging";
std::string event_name = status_name + '-' + (state.empty() ? std::to_string(capacity) : state);
if (last_event_ != event_name) {
spdlog::debug("battery: triggering event {}", event_name);
if (events[event_name].isString()) {
std::string exec = events[event_name].asString();
// Execute the command if it is not empty
if (!exec.empty()) {
util::command::exec(exec, "");
}
exec(events[event_name]);
if (!last_event_.empty() && last_event_[3] != event_name[3]) {
exec(events[status_name]);
}
last_event_ = event_name;
}
+18 -8
View File
@@ -111,13 +111,16 @@ waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value&
findConnectedDevices(cur_controller_->path, connected_devices_);
}
g_signal_connect(manager_.get(), "object-added", G_CALLBACK(onObjectAdded), this);
g_signal_connect(manager_.get(), "object-removed", G_CALLBACK(onObjectRemoved), this);
g_signal_connect(manager_.get(), "interface-proxy-properties-changed",
G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved), this);
g_signal_connect(manager_.get(), "interface-removed", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
if (manager_) {
g_signal_connect(manager_.get(), "object-added", G_CALLBACK(onObjectAdded), this);
g_signal_connect(manager_.get(), "object-removed", G_CALLBACK(onObjectRemoved), this);
g_signal_connect(manager_.get(), "interface-proxy-properties-changed",
G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
g_signal_connect(manager_.get(), "interface-removed", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
}
#ifdef WANT_RFKILL
rfkill_.on_update.connect(sigc::hide(sigc::mem_fun(*this, &Bluetooth::update)));
@@ -264,7 +267,7 @@ auto waybar::modules::Bluetooth::update() -> void {
device_enumerate_.erase(0, 1);
}
}
label_.set_tooltip_text(fmt::format(
label_.set_tooltip_markup(fmt::format(
fmt::runtime(tooltip_format), fmt::arg("status", state_),
fmt::arg("num_connections", connected_devices_.size()),
fmt::arg("controller_address", cur_controller_ ? cur_controller_->address : "null"),
@@ -446,6 +449,10 @@ auto waybar::modules::Bluetooth::getControllerProperties(GDBusObject* object,
auto waybar::modules::Bluetooth::findCurController() -> std::optional<ControllerInfo> {
std::optional<ControllerInfo> controller_info;
if (!manager_) {
return controller_info;
}
GList* objects = g_dbus_object_manager_get_objects(manager_.get());
for (GList* l = objects; l != NULL; l = l->next) {
GDBusObject* object = G_DBUS_OBJECT(l->data);
@@ -465,6 +472,9 @@ auto waybar::modules::Bluetooth::findCurController() -> std::optional<Controller
auto waybar::modules::Bluetooth::findConnectedDevices(const std::string& cur_controller_path,
std::vector<DeviceInfo>& connected_devices)
-> void {
if (!manager_) {
return;
}
GList* objects = g_dbus_object_manager_get_objects(manager_.get());
for (GList* l = objects; l != NULL; l = l->next) {
GDBusObject* object = G_DBUS_OBJECT(l->data);
+5 -3
View File
@@ -26,6 +26,7 @@ void waybar::modules::cava::Cava::pause_resume() { backend_->doPauseResume(); }
auto waybar::modules::cava::Cava::onUpdate(const std::string& input) -> void {
Glib::signal_idle().connect_once([this, input]() {
if (silence_) {
silence_ = false;
label_.get_style_context()->remove_class("silent");
if (!label_.get_style_context()->has_class("updated"))
label_.get_style_context()->add_class("updated");
@@ -38,7 +39,6 @@ auto waybar::modules::cava::Cava::onUpdate(const std::string& input) -> void {
label_.show();
ALabel::update();
});
silence_ = false;
}
auto waybar::modules::cava::Cava::onSilence() -> void {
@@ -47,9 +47,11 @@ auto waybar::modules::cava::Cava::onSilence() -> void {
if (label_.get_style_context()->has_class("updated"))
label_.get_style_context()->remove_class("updated");
if (hide_on_silence_)
if (hide_on_silence_) {
// Clear the label markup before hiding to prevent GTK from rendering a NULL Pango layout
label_.set_markup("");
label_.hide();
else if (config_["format_silent"].isString())
} else if (config_["format_silent"].isString())
label_.set_markup(format_silent_);
silence_ = true;
label_.get_style_context()->add_class("silent");
+5 -5
View File
@@ -183,10 +183,10 @@ void waybar::modules::cava::CavaBackend::loadConfig() {
prm_.inAtty = 0;
auto const output{prm_.output};
// prm_.output = ::cava::output_method::OUTPUT_RAW;
if (config_["data_format"].isString()) {
if (prm_.data_format) free(prm_.data_format);
prm_.data_format = strdup(config_["data_format"].asString().c_str());
}
if (prm_.data_format) free(prm_.data_format);
// Default to ascii for format-icons output; allow user override
prm_.data_format = strdup(
config_["data_format"].isString() ? config_["data_format"].asString().c_str() : "ascii");
if (config_["raw_target"].isString()) {
if (prm_.raw_target) free(prm_.raw_target);
prm_.raw_target = strdup(config_["raw_target"].asString().c_str());
@@ -218,7 +218,7 @@ void waybar::modules::cava::CavaBackend::loadConfig() {
prm_.input = ::cava::input_method_by_name(config_["method"].asString().c_str());
if (config_["source"].isString()) {
if (prm_.audio_source) free(prm_.audio_source);
prm_.audio_source = config_["source"].asString().data();
prm_.audio_source = strdup(config_["source"].asString().c_str());
}
if (config_["sample_rate"].isNumeric()) prm_.samplerate = config_["sample_rate"].asLargestInt();
if (config_["sample_bits"].isInt()) prm_.samplebits = config_["sample_bits"].asInt();
+2 -1
View File
@@ -35,7 +35,7 @@ CFFI::CFFI(const std::string& name, const std::string& id, const Json::Value& co
throw std::runtime_error{std::string{"Missing wbcffi_init function: "} + dlerror()};
}
hooks_.deinit = reinterpret_cast<DenitFn*>(dlsym(handle, "wbcffi_deinit"));
if (!hooks_.init) {
if (!hooks_.deinit) {
throw std::runtime_error{std::string{"Missing wbcffi_deinit function: "} + dlerror()};
}
// Optional functions
@@ -71,6 +71,7 @@ CFFI::CFFI(const std::string& name, const std::string& id, const Json::Value& co
// Prepare config_entries array
std::vector<ffi::wbcffi_config_entry> config_entries;
config_entries.reserve(keys.size());
for (size_t i = 0; i < keys.size(); i++) {
config_entries.push_back({keys[i].c_str(), config_entries_stringstor[i].c_str()});
}
+16 -7
View File
@@ -26,9 +26,7 @@ auto waybar::modules::Cpu::update() -> void {
auto [load1, load5, load15] = Load::getLoad();
auto [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_);
auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency();
if (tooltipEnabled()) {
label_.set_tooltip_text(tooltip);
}
auto format = format_;
auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0];
auto state = getState(total_usage);
@@ -48,14 +46,25 @@ auto waybar::modules::Cpu::update() -> void {
store.push_back(fmt::arg("max_frequency", max_frequency));
store.push_back(fmt::arg("min_frequency", min_frequency));
store.push_back(fmt::arg("avg_frequency", avg_frequency));
std::vector<std::string> arg_names;
arg_names.reserve(cpu_usage.size() * 2);
for (size_t i = 1; i < cpu_usage.size(); ++i) {
auto core_i = i - 1;
auto core_format = fmt::format("usage{}", core_i);
store.push_back(fmt::arg(core_format.c_str(), cpu_usage[i]));
auto icon_format = fmt::format("icon{}", core_i);
store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons)));
arg_names.push_back(fmt::format("usage{}", core_i));
store.push_back(fmt::arg(arg_names.back().c_str(), cpu_usage[i]));
arg_names.push_back(fmt::format("icon{}", core_i));
store.push_back(fmt::arg(arg_names.back().c_str(), getIcon(cpu_usage[i], icons)));
}
label_.set_markup(fmt::vformat(format, store));
if (tooltipEnabled()) {
if (config_["tooltip-format"].isString()) {
tooltip = config_["tooltip-format"].asString();
label_.set_tooltip_markup(fmt::vformat(tooltip, store));
} else {
label_.set_tooltip_markup(tooltip);
}
}
}
// Call parent update
+13 -6
View File
@@ -20,12 +20,7 @@ waybar::modules::CpuFrequency::CpuFrequency(const std::string& id, const Json::V
auto waybar::modules::CpuFrequency::update() -> void {
// TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both
auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency();
if (tooltipEnabled()) {
auto tooltip =
fmt::format("Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n",
min_frequency, avg_frequency, max_frequency);
label_.set_tooltip_text(tooltip);
}
auto format = format_;
auto state = getState(avg_frequency);
if (!state.empty() && config_["format-" + state].isString()) {
@@ -43,6 +38,18 @@ auto waybar::modules::CpuFrequency::update() -> void {
store.push_back(fmt::arg("min_frequency", min_frequency));
store.push_back(fmt::arg("avg_frequency", avg_frequency));
label_.set_markup(fmt::vformat(format, store));
if (tooltipEnabled()) {
std::string tooltip;
if (config_["tooltip-format"].isString()) {
tooltip = config_["tooltip-format"].asString();
label_.set_tooltip_markup(fmt::vformat(tooltip, store));
} else {
tooltip = "Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n";
label_.set_tooltip_markup(
fmt::format(fmt::runtime(tooltip), min_frequency, avg_frequency, max_frequency));
}
}
}
// Call parent update
+1 -1
View File
@@ -26,7 +26,7 @@ std::vector<float> waybar::modules::CpuFrequency::parseCpuFrequencies() {
if (std::filesystem::exists(cpufreq_dir)) {
std::vector<std::string> frequency_files = {"/cpuinfo_min_freq", "/cpuinfo_max_freq"};
for (auto& p : std::filesystem::directory_iterator(cpufreq_dir)) {
for (auto freq_file : frequency_files) {
for (const auto& freq_file : frequency_files) {
std::string freq_file_path = p.path().string() + freq_file;
if (std::filesystem::exists(freq_file_path)) {
std::string freq_value;
+1 -1
View File
@@ -33,7 +33,7 @@ std::vector<std::tuple<size_t, size_t>> waybar::modules::CpuUsage::parseCpuinfo(
size_t sum_sz = sizeof(sum_cp_time);
int ncpu = sysconf(_SC_NPROCESSORS_CONF);
size_t sz = CPUSTATES * (ncpu + 1) * sizeof(pcp_time_t);
pcp_time_t *cp_time = static_cast<pcp_time_t *>(malloc(sz)), *pcp_time = cp_time;
pcp_time_t *cp_time = static_cast<pcp_time_t*>(malloc(sz)), *pcp_time = cp_time;
waybar::util::ScopeGuard cp_time_deleter([cp_time]() {
if (cp_time) {
free(cp_time);
+20 -9
View File
@@ -20,9 +20,7 @@ waybar::modules::CpuUsage::CpuUsage(const std::string& id, const Json::Value& co
auto waybar::modules::CpuUsage::update() -> void {
// TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both
auto [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_);
if (tooltipEnabled()) {
label_.set_tooltip_text(tooltip);
}
auto format = format_;
auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0];
auto state = getState(total_usage);
@@ -38,14 +36,25 @@ auto waybar::modules::CpuUsage::update() -> void {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(fmt::arg("usage", total_usage));
store.push_back(fmt::arg("icon", getIcon(total_usage, icons)));
std::vector<std::string> arg_names;
arg_names.reserve(cpu_usage.size() * 2);
for (size_t i = 1; i < cpu_usage.size(); ++i) {
auto core_i = i - 1;
auto core_format = fmt::format("usage{}", core_i);
store.push_back(fmt::arg(core_format.c_str(), cpu_usage[i]));
auto icon_format = fmt::format("icon{}", core_i);
store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons)));
arg_names.push_back(fmt::format("usage{}", core_i));
store.push_back(fmt::arg(arg_names.back().c_str(), cpu_usage[i]));
arg_names.push_back(fmt::format("icon{}", core_i));
store.push_back(fmt::arg(arg_names.back().c_str(), getIcon(cpu_usage[i], icons)));
}
label_.set_markup(fmt::vformat(format, store));
if (tooltipEnabled()) {
if (config_["tooltip-format"].isString()) {
tooltip = config_["tooltip-format"].asString();
label_.set_tooltip_markup(fmt::vformat(tooltip, store));
} else {
label_.set_tooltip_markup(tooltip);
}
}
}
// Call parent update
@@ -71,7 +80,8 @@ std::tuple<std::vector<uint16_t>, std::string> waybar::modules::CpuUsage::getCpu
auto [prev_idle, prev_total] = prev_times[0];
const float delta_idle = curr_idle - prev_idle;
const float delta_total = curr_total - prev_total;
uint16_t tmp = 100 * (1 - delta_idle / delta_total);
uint16_t tmp =
(delta_total > 0) ? static_cast<uint16_t>(100 * (1 - delta_idle / delta_total)) : 0;
tooltip = fmt::format("Total: {}%\nCores: (pending)", tmp);
usage.push_back(tmp);
} else {
@@ -93,7 +103,8 @@ std::tuple<std::vector<uint16_t>, std::string> waybar::modules::CpuUsage::getCpu
}
const float delta_idle = curr_idle - prev_idle;
const float delta_total = curr_total - prev_total;
uint16_t tmp = 100 * (1 - delta_idle / delta_total);
uint16_t tmp =
(delta_total > 0) ? static_cast<uint16_t>(100 * (1 - delta_idle / delta_total)) : 0;
if (i == 0) {
tooltip = fmt::format("Total: {}%", tmp);
} else {
+15 -11
View File
@@ -2,6 +2,8 @@
#include <spdlog/spdlog.h>
#include <utility>
#include "util/scope_guard.hpp"
waybar::modules::Custom::Custom(const std::string& name, const std::string& id,
@@ -136,7 +138,7 @@ void waybar::modules::Custom::waitingWorker() {
}
void waybar::modules::Custom::refresh(int sig) {
if (sig == SIGRTMIN + config_["signal"].asInt()) {
if (config_["signal"].isInt() && sig == SIGRTMIN + config_["signal"].asInt()) {
thread_.wake_up();
}
}
@@ -180,20 +182,22 @@ auto waybar::modules::Custom::update() -> void {
} else {
label_.set_markup(str);
if (tooltipEnabled()) {
std::string tooltip_markup;
if (tooltip_format_enabled_) {
auto tooltip = config_["tooltip-format"].asString();
tooltip = fmt::format(
fmt::runtime(tooltip), fmt::arg("text", text_), fmt::arg("alt", alt_),
fmt::arg("icon", getIcon(percentage_, alt_)), fmt::arg("percentage", percentage_));
label_.set_tooltip_markup(tooltip);
tooltip_markup = fmt::format(fmt::runtime(tooltip), fmt::arg("text", text_),
fmt::arg("tooltip", tooltip_), fmt::arg("alt", alt_),
fmt::arg("icon", getIcon(percentage_, alt_)),
fmt::arg("percentage", percentage_));
} else if (text_ == tooltip_) {
if (label_.get_tooltip_markup() != str) {
label_.set_tooltip_markup(str);
}
tooltip_markup = str;
} else {
if (label_.get_tooltip_markup() != tooltip_) {
label_.set_tooltip_markup(tooltip_);
}
tooltip_markup = tooltip_;
}
if (last_tooltip_markup_ != tooltip_markup) {
label_.set_tooltip_markup(tooltip_markup);
last_tooltip_markup_ = std::move(tooltip_markup);
}
}
auto style = label_.get_style_context();
+3 -3
View File
@@ -41,7 +41,7 @@ auto waybar::modules::Disk::update() -> void {
fs_used - File system used space
*/
if (err != 0) {
if (err != 0 || stats.f_blocks == 0) {
event_box_.hide();
return;
}
@@ -81,7 +81,7 @@ auto waybar::modules::Disk::update() -> void {
if (config_["tooltip-format"].isString()) {
tooltip_format = config_["tooltip-format"].asString();
}
label_.set_tooltip_text(fmt::format(
label_.set_tooltip_markup(fmt::format(
fmt::runtime(tooltip_format), stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks), fmt::arg("used", used),
fmt::arg("percentage_used", percentage_used), fmt::arg("total", total),
@@ -92,7 +92,7 @@ auto waybar::modules::Disk::update() -> void {
ALabel::update();
}
float waybar::modules::Disk::calc_specific_divisor(std::string divisor) {
float waybar::modules::Disk::calc_specific_divisor(const std::string& divisor) {
if (divisor == "kB") {
return 1000.0;
} else if (divisor == "kiB") {

Some files were not shown because too many files have changed in this diff Show More