Merge remote-tracking branch 'origin/master' into pr-3573

# Conflicts:
#	src/AModule.cpp
This commit is contained in:
Alex
2026-07-04 00:51:06 +02:00
339 changed files with 18987 additions and 5469 deletions
+40 -19
View File
@@ -16,11 +16,16 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
: name_(name),
config_(config),
isTooltip{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true},
isExpand{config_["expand"].isBool() ? config_["expand"].asBool() : false},
distance_scrolled_y_(0.0),
distance_scrolled_x_(0.0) {
distance_scrolled_x_(0.0),
cursor_timeout_conn_() {
// Configure module action Map
const Json::Value actions{config_["actions"]};
disable_on_sleep_ =
config_["disable-on-sleep"].isBool() ? config_["disable-on-sleep"].asBool() : false;
for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) {
if (it.key().isString() && it->isString())
if (!eventActionMap_.contains(it.key().asString())) {
@@ -42,7 +47,7 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
std::find_if(eventMap_.cbegin(), eventMap_.cend(), [&config](const auto& eventEntry) {
// True if there is any non-release type event
return eventEntry.first.second != GdkEventType::GDK_BUTTON_RELEASE &&
config[eventEntry.second].isString();
(config[eventEntry.second].isString() || config[eventEntry.second].isBool());
}) != eventMap_.cend();
if (enable_click || hasUserEvents) {
@@ -72,10 +77,14 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
// Respect user configuration of cursor
if (config_.isMember("cursor")) {
if (config_["cursor"].isBool() && config_["cursor"].asBool()) {
setCursor(Gdk::HAND2);
} else if (config_["cursor"].isInt()) {
setCursor(Gdk::CursorType(config_["cursor"].asInt()));
if (config_["cursor"].isBool()) {
if (config_["cursor"].asBool()) {
setCursor("pointer");
} else {
setCursor("default");
}
} else if (config_["cursor"].isString()) {
setCursor(config_["cursor"].asString());
} else {
spdlog::warn("unknown cursor option configured on module {}", name_);
}
@@ -83,38 +92,45 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
}
AModule::~AModule() {
for (const auto& pid : pid_) {
if (cursor_timeout_conn_.connected()) {
cursor_timeout_conn_.disconnect();
}
for (const auto& pid : pid_children_) {
if (pid != -1) {
killpg(pid, SIGTERM);
}
}
if (menu_ != nullptr) {
g_object_unref(menu_);
menu_ = nullptr;
}
}
auto AModule::update() -> void {
// Run user-provided update handler if configured
if (config_["on-update"].isString()) {
pid_.push_back(util::command::forkExec(config_["on-update"].asString()));
pid_children_.push_back(util::command::forkExec(config_["on-update"].asString()));
}
}
// Get mapping between event name and module action name
// Then call overrided doAction in order to call appropriate module action
// Then call overridden doAction in order to call appropriate module action
auto AModule::doAction(const std::string& name) -> void {
if (!name.empty()) {
const std::map<std::string, std::string>::const_iterator& recA{eventActionMap_.find(name)};
// Call overrided action if derrived class has implemented it
// Call overridden action if derived class has implemented it
if (recA != eventActionMap_.cend() && name != recA->second) this->doAction(recA->second);
}
}
void AModule::setCursor(Gdk::CursorType const& c) {
void AModule::setCursor(std::string const& c) {
auto gdk_window = event_box_.get_window();
if (gdk_window) {
auto cursor = Gdk::Cursor::create(c);
auto cursor = Gdk::Cursor::create(gdk_window->get_display(), c);
gdk_window->set_cursor(cursor);
} else {
// window may not be accessible yet, in this case,
// schedule another call for setting the cursor in 1 sec
Glib::signal_timeout().connect_seconds(
cursor_timeout_conn_ = Glib::signal_timeout().connect_seconds(
[this, c]() {
setCursor(c);
return false;
@@ -130,7 +146,7 @@ bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
// Default behavior indicating event availability
if (hasUserEvents_ && !config_.isMember("cursor")) {
setCursor(Gdk::HAND2);
setCursor("pointer");
}
return false;
@@ -143,7 +159,7 @@ bool AModule::handleMouseLeave(GdkEventCrossing* const& e) {
// Default behavior indicating event availability
if (hasUserEvents_ && !config_.isMember("cursor")) {
setCursor(Gdk::ARROW);
setCursor("default");
}
return false;
@@ -166,12 +182,16 @@ 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));
// Manually reset prelight to make sure the module doesn't stay in a hover state
if (auto* module = event_box_.get_child(); module != nullptr) {
module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
}
}
}
// Second call user scripts
@@ -187,7 +207,7 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
const std::string cmd =
fmt::format(fmt::runtime(format), fmt::arg("x", (int)round(100. * e->x / width)),
fmt::arg("y", (int)round(100. * e->y / height)));
pid_.push_back(util::command::forkExec(cmd));
pid_children_.push_back(util::command::forkExec(cmd));
}
dp.emit();
return true;
@@ -272,13 +292,14 @@ bool AModule::handleScroll(GdkEventScroll* e) {
this->AModule::doAction(eventName);
// Second call user scripts
if (config_[eventName].isString())
pid_.push_back(util::command::forkExec(config_[eventName].asString()));
pid_children_.push_back(util::command::forkExec(config_[eventName].asString()));
dp.emit();
return true;
}
bool AModule::tooltipEnabled() const { return isTooltip; }
bool AModule::expandEnabled() const { return isExpand; }
AModule::operator Gtk::Widget&() { return event_box_; }