diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 00000000..5301cef1 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,5 @@ +;;; Directory Local Variables -*- no-byte-compile: t -*- +;;; For more information see (info "(emacs) Directory Variables") + +((nil . ((ff-search-directories . ("../include/*/" "../../include/*/" + "../src/*/" "../../src/*/"))))) diff --git a/include/client.hpp b/include/client.hpp index 0e68f002..77fd0733 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -5,6 +5,8 @@ #include #include +#include + #include "bar.hpp" #include "config.hpp" #include "util/css_reload_helper.hpp" @@ -17,35 +19,38 @@ 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(); + bool get_signal_state(int signum) const; + void toggle_signal_state(int signum); + Glib::RefPtr gtk_app; Glib::RefPtr 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> bars; Config config; std::string bar_id; private: Client() = default; - const std::string getStyle(const std::string &style, std::optional appearance); + const std::string getStyle(const std::string& style, std::optional appearance); void bindInterfaces(); - void handleOutput(struct waybar_output &output); - auto setupCss(const std::string &css_file) -> void; - struct waybar_output &getOutput(void *); - std::vector 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 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 monitor); void handleMonitorRemoved(Glib::RefPtr monitor); void handleDeferredMonitorRemoval(Glib::RefPtr monitor); @@ -56,6 +61,8 @@ class Client { std::list outputs_; std::unique_ptr m_cssReloadHelper; std::string m_cssFile; + + std::map signal_toggle_state; }; } // namespace waybar diff --git a/include/group.hpp b/include/group.hpp index 4376e3fa..e6d09e73 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -13,14 +13,14 @@ 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; auto refresh(int sig) -> void override; - virtual Gtk::Box &getBox(); - void addWidget(Gtk::Widget &widget); + virtual Gtk::Box& getBox(); + void addWidget(Gtk::Widget& widget); protected: Gtk::Box box; @@ -31,12 +31,19 @@ class Group : public AModule { bool click_to_reveal = false; std::optional toggle_signal; 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; void toggle(); void show_group(); void hide_group(); + void set_visible(bool v) { + if (v) { + show_group(); + } else { + hide_group(); + } + } }; } // namespace waybar diff --git a/src/client.cpp b/src/client.cpp index 946780db..0f6fa1c5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "gtkmm/icontheme.h" @@ -11,60 +12,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(data); +void waybar::Client::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, + const char* interface, uint32_t version) { + auto* client = static_cast(data); if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) { - client->xdg_output_manager = static_cast(wl_registry_bind( + client->xdg_output_manager = static_cast(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( + client->idle_inhibit_manager = static_cast( 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 waybar::Client::getOutputConfigs(struct waybar_output &output) { +std::vector 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 +81,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(&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 monitor) { - auto &output = outputs_.emplace_back(); + auto& output = outputs_.emplace_back(); output.monitor = std::move(monitor); handleOutput(output); } @@ -146,10 +147,10 @@ void waybar::Client::handleDeferredMonitorRemoval(Glib::RefPtr 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 = std::nullopt) { auto gtk_settings = Gtk::Settings::get_default(); std::optional css_file; @@ -182,7 +183,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 { css_provider_ = Gtk::CssProvider::create(); style_context_ = Gtk::StyleContext::create(); @@ -221,7 +222,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; @@ -282,7 +283,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; @@ -290,6 +291,8 @@ int waybar::Client::main(int argc, char *argv[]) { } } + signal_toggle_state.clear(); + bindInterfaces(); gtk_app->hold(); gtk_app->run(); @@ -303,3 +306,16 @@ void waybar::Client::reset() { // delete signal handler for css changes portal->signal_appearance_changed().clear(); } + +bool waybar::Client::get_signal_state(int signum) const { + try { + return signal_toggle_state.at(signum); + } catch (const std::out_of_range&) { + // default signal states to false + return false; + } +} + +void waybar::Client::toggle_signal_state(int signum) { + signal_toggle_state[signum] = !get_signal_state(signum); +} diff --git a/src/group.cpp b/src/group.cpp index e906d539..e4852964 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -4,6 +4,7 @@ #include +#include "client.hpp" #include "gtkmm/enums.h" #include "gtkmm/widget.h" @@ -134,7 +135,7 @@ auto Group::update() -> void { void Group::refresh(int sig) { if (toggle_signal.has_value() && sig == SIGRTMIN + toggle_signal.value()) { - toggle(); + set_visible(waybar::Client::inst()->get_signal_state(sig)); } } diff --git a/src/main.cpp b/src/main.cpp index 021f8e1a..fb96418d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -117,6 +117,7 @@ void handleUserSignal(int signal, bool& reload) { // `true` or `false`, respectively, into `reload`. static void handleSignalMainThread(int signum, bool& reload) { if (signum >= SIGRTMIN + 1 && signum <= SIGRTMAX) { + waybar::Client::inst()->toggle_signal_state(signum); for (auto& bar : waybar::Client::inst()->bars) { bar->handleSignal(signum); }