add GtkMenu to the AModule class

You can configure what key launch the menu with the "menu" element in
the config, the xml file that describes the menu with the "menu-file"
element in the config, and the actions of each buttons with the
"menu-actions" field.
This commit is contained in:
Benjamin Voisin 2024-05-09 17:28:08 +02:00
parent e627879b16
commit 884b909e7d
No known key found for this signature in database
GPG Key ID: C5C8EDD125FBFD78
2 changed files with 35 additions and 0 deletions

View File

@ -4,6 +4,7 @@
#include <glibmm/markup.h> #include <glibmm/markup.h>
#include <gtkmm/eventbox.h> #include <gtkmm/eventbox.h>
#include <json/json.h> #include <json/json.h>
#include <gtkmm.h>
#include "IModule.hpp" #include "IModule.hpp"
@ -52,6 +53,10 @@ class AModule : public IModule {
std::vector<int> pid_; std::vector<int> pid_;
gdouble distance_scrolled_y_; gdouble distance_scrolled_y_;
gdouble distance_scrolled_x_; gdouble distance_scrolled_x_;
GObject* menu_;
std::map<std::string, GtkMenuItem*> submenus_;
std::map<std::string, std::string> menuActionsMap_;
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
std::map<std::string, std::string> eventActionMap_; std::map<std::string, std::string> eventActionMap_;
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{ static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
{std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"}, {std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"},

View File

@ -27,6 +27,24 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
else else
spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index()); spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index());
} }
// If a GTKMenu is requested in the config
if (config_["menu"].isString()) {
// Create the GTKMenu widget
GtkBuilder* builder = gtk_builder_new_from_file(config_["menu-file"].asString().c_str());
menu_ = gtk_builder_get_object(builder, "menu");
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());
}
// Enable click
enable_click = true;
}
event_box_.signal_enter_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter)); event_box_.signal_enter_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter));
event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave)); event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave));
@ -66,6 +84,10 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
} }
} }
void AModule::handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data) {
waybar::util::command::res res = waybar::util::command::exec((char*) data, "TLP");
}
AModule::~AModule() { AModule::~AModule() {
for (const auto& pid : pid_) { for (const auto& pid : pid_) {
if (pid != -1) { if (pid != -1) {
@ -133,6 +155,14 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
format = rec->second; format = rec->second;
} }
// Check if the event is the one specified for the "menu" option
if (rec->second == config_["menu"].asString()) {
// Popup the menu
gtk_widget_show_all(GTK_WIDGET(menu_));
gtk_menu_popup_at_pointer (GTK_MENU(menu_), reinterpret_cast<GdkEvent*>(e));
}
// Second call user scripts // Second call user scripts
if (!format.empty()) { if (!format.empty()) {
if (config_[format].isString()) if (config_[format].isString())