diff --git a/include/bar.hpp b/include/bar.hpp index eb0d420a..d39208b2 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -18,12 +18,11 @@ struct waybar_output { std::string name; uint32_t wl_name; struct zxdg_output_v1 *xdg_output; - Json::Value config; }; class Bar { public: - Bar(struct waybar_output *w_output); + Bar(struct waybar_output *w_output, const Json::Value&); Bar(const Bar &) = delete; ~Bar() = default; @@ -31,6 +30,7 @@ class Bar { void handleSignal(int); struct waybar_output * output; + Json::Value config; Gtk::Window window; struct wl_surface * surface; struct zwlr_layer_surface_v1 *layer_surface; diff --git a/include/client.hpp b/include/client.hpp index 06fb174a..5ba251cd 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -33,6 +33,8 @@ class Client { bool isValidOutput(const Json::Value &config, std::unique_ptr &output); auto setupConfig() -> void; auto setupCss() -> void; + std::unique_ptr& getOutput(uint32_t wl_name); + std::vector getOutputConfigs(std::unique_ptr &output); static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); diff --git a/src/bar.cpp b/src/bar.cpp index 33b00433..7a48a481 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -2,8 +2,9 @@ #include "client.hpp" #include "factory.hpp" -waybar::Bar::Bar(struct waybar_output* w_output) +waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) : output(w_output), + config(w_config), window{Gtk::WindowType::WINDOW_TOPLEVEL}, surface(nullptr), layer_surface(nullptr), @@ -15,7 +16,7 @@ waybar::Bar::Bar(struct waybar_output* w_output) window.set_name("waybar"); window.set_decorated(false); - if (output->config["position"] == "right" || output->config["position"] == "left") { + if (config["position"] == "right" || config["position"] == "left") { height_ = 0; width_ = 1; } @@ -28,7 +29,7 @@ waybar::Bar::Bar(struct waybar_output* w_output) gdk_wayland_window_set_use_custom_surface(gdk_window); surface = gdk_wayland_window_get_wl_surface(gdk_window); - std::size_t layer = output->config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP + std::size_t layer = config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; auto client = waybar::Client::inst(); layer_surface = zwlr_layer_shell_v1_get_layer_surface( @@ -39,8 +40,8 @@ waybar::Bar::Bar(struct waybar_output* w_output) }; zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this); - auto height = output->config["height"].isUInt() ? output->config["height"].asUInt() : height_; - auto width = output->config["width"].isUInt() ? output->config["width"].asUInt() : width_; + auto height = config["height"].isUInt() ? config["height"].asUInt() : height_; + auto width = config["width"].isUInt() ? config["width"].asUInt() : width_; window.signal_configure_event().connect_notify([&](GdkEventConfigure* ev) { auto tmp_height = height_; @@ -50,7 +51,7 @@ waybar::Bar::Bar(struct waybar_output* w_output) if (height_ != 1) { std::cout << fmt::format(MIN_HEIGHT_MSG, height_, ev->height) << std::endl; } - if (output->config["height"].isUInt()) { + if (config["height"].isUInt()) { std::cout << fmt::format(SIZE_DEFINED, "Height") << std::endl; } else { tmp_height = ev->height; @@ -61,7 +62,7 @@ waybar::Bar::Bar(struct waybar_output* w_output) if (width_ != 1) { std::cout << fmt::format(MIN_WIDTH_MSG, width_, ev->width) << std::endl; } - if (output->config["width"].isUInt()) { + if (config["width"].isUInt()) { std::cout << fmt::format(SIZE_DEFINED, "Width") << std::endl; } else { tmp_width = ev->width; @@ -73,11 +74,11 @@ waybar::Bar::Bar(struct waybar_output* w_output) }); std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; - if (output->config["position"] == "bottom") { + if (config["position"] == "bottom") { anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - } else if (output->config["position"] == "left") { + } else if (config["position"] == "left") { anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; - } else if (output->config["position"] == "right") { + } else if (config["position"] == "right") { anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; } if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) { @@ -104,8 +105,8 @@ waybar::Bar::Bar(struct waybar_output* w_output) // Converting string to button code rn as to avoid doing it later void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) { - if (output->config.isMember(module_name)) { - Json::Value& module = output->config[module_name]; + if (config.isMember(module_name)) { + Json::Value& module = config[module_name]; if (module.isMember("format-alt")) { if (module.isMember("format-alt-click")) { Json::Value& click = module["format-alt-click"]; @@ -134,8 +135,8 @@ void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) { } void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) { - if (output->config.isMember(module_list_name)) { - Json::Value& modules = output->config[module_list_name]; + if (config.isMember(module_list_name)) { + Json::Value& modules = config[module_list_name]; for (const Json::Value& module_name : modules) { if (module_name.isString()) { setupAltFormatKeyForModule(module_name.asString()); @@ -206,8 +207,8 @@ auto waybar::Bar::toggle() -> void { } void waybar::Bar::getModules(const Factory& factory, const std::string& pos) { - if (output->config[pos].isArray()) { - for (const auto& name : output->config[pos]) { + if (config[pos].isArray()) { + for (const auto& name : config[pos]) { try { auto module = factory.makeModule(name.asString()); if (pos == "modules-left") { @@ -244,7 +245,7 @@ auto waybar::Bar::setupWidgets() -> void { setupAltFormatKeyForModuleList("modules-right"); setupAltFormatKeyForModuleList("modules-center"); - Factory factory(*this, output->config); + Factory factory(*this, config); getModules(factory, "modules-left"); getModules(factory, "modules-center"); getModules(factory, "modules-right"); diff --git a/src/client.cpp b/src/client.cpp index c4b9ce19..8713ec82 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -116,41 +116,52 @@ bool waybar::Client::isValidOutput(const Json::Value & config return found; } +std::unique_ptr &waybar::Client::getOutput(uint32_t wl_name) { + auto it = std::find_if(outputs_.begin(), outputs_.end(), [&wl_name](const auto &output) { + return output->wl_name == wl_name; + }); + if (it == outputs_.end()) { + throw std::runtime_error("Unable to find valid output"); + } + return *it; +} + +std::vector waybar::Client::getOutputConfigs( + std::unique_ptr &output) { + std::vector configs; + if (config_.isArray()) { + for (auto const &config : config_) { + if (config.isObject() && isValidOutput(config, output)) { + configs.push_back(config); + } + } + } else if (isValidOutput(config_, output)) { + configs.push_back(config_); + } + return configs; +} + void waybar::Client::handleName(void * data, struct zxdg_output_v1 * /*xdg_output*/, const char *name) { auto wl_name = *static_cast(data); auto client = waybar::Client::inst(); - auto it = std::find_if(client->outputs_.begin(), - client->outputs_.end(), - [&wl_name](const auto &output) { return output->wl_name == wl_name; }); - if (it == client->outputs_.end()) { - std::cerr << "Unable to find valid output" << std::endl; - return; - } - (*it)->name = name; - bool found = true; - if (client->config_.isArray()) { - bool in_array = false; - for (auto const &config : client->config_) { - if (config.isObject() && client->isValidOutput(config, *it)) { - in_array = true; - (*it)->config = config; - break; + try { + auto &output = client->getOutput(wl_name); + output->name = name; + auto configs = client->getOutputConfigs(output); + if (configs.empty()) { + wl_output_destroy(output->output); + zxdg_output_v1_destroy(output->xdg_output); + } else { + for (const auto &config : configs) { + client->bars.emplace_back(std::make_unique(output.get(), config)); + Glib::RefPtr screen = client->bars.back()->window.get_screen(); + client->style_context_->add_provider_for_screen( + screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER); } } - found = in_array; - } else { - (*it)->config = client->config_; - found = client->isValidOutput((*it)->config, *it); - } - if (!found) { - wl_output_destroy((*it)->output); - zxdg_output_v1_destroy((*it)->xdg_output); - } else { - client->bars.emplace_back(std::make_unique(it->get())); - Glib::RefPtr screen = client->bars.back()->window.get_screen(); - client->style_context_->add_provider_for_screen( - screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; } }