🥅 do not crash when unable to make the menu

When the menu cannot be built (file not existing, or wrongly formatted),
     the menu is not created and a warning with an explanaition is
     displayed.
This commit is contained in:
Benjamin Voisin 2024-05-28 19:30:06 +02:00
parent f3ed5ca5af
commit 161c8c4c47
No known key found for this signature in database
GPG Key ID: C5C8EDD125FBFD78
1 changed files with 37 additions and 12 deletions

View File

@ -2,6 +2,8 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream>
#include <iostream>
#include <util/command.hpp> #include <util/command.hpp>
namespace waybar { namespace waybar {
@ -56,18 +58,41 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
// If a GTKMenu is requested in the config // If a GTKMenu is requested in the config
if (config_["menu"].isString()) { if (config_["menu"].isString()) {
// Create the GTKMenu widget // Create the GTKMenu widget
GtkBuilder* builder = gtk_builder_new_from_file(config_["menu-file"].asString().c_str()); try {
menu_ = gtk_builder_get_object(builder, "menu"); // Check that the file exists
submenus_ = std::map<std::string, GtkMenuItem*>(); std::string menuFile = config_["menu-file"].asString();
menuActionsMap_ = std::map<std::string, std::string>(); // Read the menu descriptor file
// Linking actions to the GTKMenu based on std::ifstream file(menuFile);
for (Json::Value::const_iterator it = config_["menu-actions"].begin(); if (!file.is_open()) {
it != config_["menu-actions"].end(); ++it) { throw std::runtime_error("Failed to open file: " + menuFile);
std::string key = it.key().asString(); }
submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str())); std::stringstream fileContent;
menuActionsMap_[key] = it->asString(); fileContent << file.rdbuf();
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent), GtkBuilder* builder = gtk_builder_new();
(gpointer)menuActionsMap_[key].c_str());
// Make the GtkBuilder and check for errors in his parsing
if (!gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr)) {
throw std::runtime_error("Error found in the file " + menuFile);
}
menu_ = gtk_builder_get_object(builder, "menu");
if (!menu_) {
throw std::runtime_error("Failed to get 'menu' object from GtkBuilder");
}
submenus_ = std::map<std::string, GtkMenuItem*>();
menuActionsMap_ = std::map<std::string, std::string>();
// Linking actions to the GTKMenu based on
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()));
menuActionsMap_[key] = it->asString();
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent),
(gpointer)menuActionsMap_[key].c_str());
}
} catch (std::runtime_error& e) {
spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what());
} }
} }