fix code style

This commit is contained in:
2025-12-10 17:58:01 +01:00
parent 4d61a80a7c
commit 0b3a6c4696
19 changed files with 1016 additions and 1366 deletions

View File

@@ -1,363 +1,326 @@
#include "widgets/tray.hpp"
#include <gtk/gtk.h>
#include <gdkmm/rectangle.h>
#include <gio/gmenu.h>
#include <utility>
#include <gtk/gtk.h>
#include <iostream>
#include <utility>
TrayIconWidget::TrayIconWidget(TrayService &service, std::string id)
: m_service(service), m_id(std::move(id)), m_container(Gtk::Orientation::HORIZONTAL)
{
: service(service), id(std::move(id)),
container(Gtk::Orientation::HORIZONTAL) {
set_has_frame(false);
set_focusable(false);
set_valign(Gtk::Align::CENTER);
set_halign(Gtk::Align::CENTER);
m_picture.set_halign(Gtk::Align::CENTER);
m_picture.set_valign(Gtk::Align::CENTER);
m_picture.set_can_shrink(true);
m_picture.set_size_request(20, 20);
picture.set_halign(Gtk::Align::CENTER);
picture.set_valign(Gtk::Align::CENTER);
picture.set_can_shrink(true);
picture.set_size_request(20, 20);
m_image.set_pixel_size(20);
m_image.set_halign(Gtk::Align::CENTER);
m_image.set_valign(Gtk::Align::CENTER);
image.set_pixel_size(20);
image.set_halign(Gtk::Align::CENTER);
image.set_valign(Gtk::Align::CENTER);
m_container.set_halign(Gtk::Align::CENTER);
m_container.set_valign(Gtk::Align::CENTER);
m_container.append(m_picture);
m_container.append(m_image);
container.set_halign(Gtk::Align::CENTER);
container.set_valign(Gtk::Align::CENTER);
container.append(picture);
container.append(image);
m_picture.set_visible(false);
m_image.set_visible(true);
set_child(m_container);
picture.set_visible(false);
image.set_visible(true);
set_child(container);
m_primaryGesture = Gtk::GestureClick::create();
m_primaryGesture->set_button(GDK_BUTTON_PRIMARY);
m_primaryGesture->signal_released().connect(sigc::mem_fun(*this, &TrayIconWidget::on_primary_released));
add_controller(m_primaryGesture);
primaryGesture = Gtk::GestureClick::create();
primaryGesture->set_button(GDK_BUTTON_PRIMARY);
primaryGesture->signal_released().connect(
sigc::mem_fun(*this, &TrayIconWidget::on_primary_released));
add_controller(primaryGesture);
m_secondaryGesture = Gtk::GestureClick::create();
m_secondaryGesture->set_button(GDK_BUTTON_SECONDARY);
m_secondaryGesture->signal_released().connect(sigc::mem_fun(*this, &TrayIconWidget::on_secondary_released));
add_controller(m_secondaryGesture);
secondaryGesture = Gtk::GestureClick::create();
secondaryGesture->set_button(GDK_BUTTON_SECONDARY);
secondaryGesture->signal_released().connect(
sigc::mem_fun(*this, &TrayIconWidget::on_secondary_released));
add_controller(secondaryGesture);
}
void TrayIconWidget::update(const TrayService::Item &item)
{
if (!item.menuAvailable)
{
m_menuModel.reset();
m_menuActions.reset();
m_menuPopupPending = false;
if (m_menuChangedConnection.connected())
{
m_menuChangedConnection.disconnect();
void TrayIconWidget::update(const TrayService::Item &item) {
if (!item.menuAvailable) {
menuModel.reset();
menuActions.reset();
menuPopupPending = false;
if (menuChangedConnection.connected()) {
menuChangedConnection.disconnect();
}
if (m_menuPopover)
{
m_menuPopover->insert_action_group("dbusmenu", Glib::RefPtr<Gio::ActionGroup>());
m_menuPopover->set_menu_model({});
m_menuPopover->unparent();
m_menuPopover.reset();
if (menuPopover) {
menuPopover->insert_action_group("dbusmenu",
Glib::RefPtr<Gio::ActionGroup>());
menuPopover->set_menu_model({});
menuPopover->unparent();
menuPopover.reset();
}
}
if (item.iconPaintable)
{
m_picture.set_paintable(item.iconPaintable);
m_picture.set_visible(true);
m_image.set_visible(false);
}
else if (!item.iconName.empty())
{
m_image.set_from_icon_name(item.iconName);
m_image.set_pixel_size(20);
m_image.set_visible(true);
m_picture.set_visible(false);
}
else
{
m_picture.set_paintable({});
m_image.set_visible(false);
m_picture.set_visible(false);
if (item.iconPaintable) {
picture.set_paintable(item.iconPaintable);
picture.set_visible(true);
image.set_visible(false);
} else if (!item.iconName.empty()) {
image.set_from_icon_name(item.iconName);
image.set_pixel_size(20);
image.set_visible(true);
picture.set_visible(false);
} else {
picture.set_paintable({});
image.set_visible(false);
picture.set_visible(false);
}
if (!item.title.empty())
{
if (!item.title.empty()) {
set_tooltip_text(item.title);
}
else
{
} else {
set_tooltip_text("");
}
set_sensitive(item.status != "Passive");
}
void TrayIconWidget::on_primary_released(int /*n_press*/, double x, double y)
{
m_service.activate(m_id, -1, -1);
void TrayIconWidget::on_primary_released(int /*n_press*/, double x, double y) {
service.activate(id, -1, -1);
}
void TrayIconWidget::on_secondary_released(int /*n_press*/, double x, double y)
{
m_service.contextMenu(m_id, -1, -1);
void TrayIconWidget::on_secondary_released(int /*n_press*/, double x,
double y) {
service.contextMenu(id, -1, -1);
if (!ensure_menu())
{
if (!ensure_menu()) {
return;
}
m_pendingX = x;
m_pendingY = y;
m_menuPopupPending = true;
pendingX = x;
pendingY = y;
menuPopupPending = true;
try_popup();
}
bool TrayIconWidget::ensure_menu()
{
auto layoutOpt = m_service.get_menu_layout(m_id);
if (!layoutOpt)
{
m_menuModel.reset();
m_menuActions.reset();
m_menuPopupPending = false;
if (m_menuChangedConnection.connected())
{
m_menuChangedConnection.disconnect();
bool TrayIconWidget::ensure_menu() {
auto layoutOpt = service.get_menu_layout(id);
if (!layoutOpt) {
menuModel.reset();
menuActions.reset();
menuPopupPending = false;
if (menuChangedConnection.connected()) {
menuChangedConnection.disconnect();
}
if (m_menuPopover)
{
if (menuPopover) {
remove_action_group("dbusmenu");
m_menuPopover->set_menu_model({});
m_menuPopover->unparent();
m_menuPopover.reset();
menuPopover->set_menu_model({});
menuPopover->unparent();
menuPopover.reset();
}
return false;
}
const auto &layout = *layoutOpt;
auto menu = Gio::Menu::create();
auto actions = Gio::SimpleActionGroup::create();
populate_menu_items(layout.children, menu, actions);
const auto itemCount = menu->get_n_items();
std::cout << "[TrayIconWidget] menu update for " << m_id << ", items: " << itemCount << std::endl;
if (itemCount == 0)
{
m_service.debug_dump_menu_layout(m_id);
std::cout << "[TrayIconWidget] menu update for " << id
<< ", items: " << itemCount << std::endl;
if (itemCount == 0) {
service.debug_dump_menu_layout(id);
return false;
}
m_menuModel = menu;
m_menuActions = actions;
menuModel = menu;
menuActions = actions;
if (!m_menuPopover)
{
if (!menuPopover) {
auto *rawPopover = Gtk::make_managed<Gtk::PopoverMenu>();
m_menuPopover = Glib::make_refptr_for_instance<Gtk::PopoverMenu>(rawPopover);
if (!m_menuPopover)
{
menuPopover =
Glib::make_refptr_for_instance<Gtk::PopoverMenu>(rawPopover);
if (!menuPopover) {
return false;
}
m_menuPopover->set_has_arrow(false);
m_menuPopover->set_autohide(true);
m_menuPopover->set_parent(*this);
menuPopover->set_has_arrow(false);
menuPopover->set_autohide(true);
menuPopover->set_parent(*this);
}
m_menuPopover->remove_action_group("dbusmenu");
m_menuPopover->insert_action_group("dbusmenu", m_menuActions);
menuPopover->remove_action_group("dbusmenu");
menuPopover->insert_action_group("dbusmenu", menuActions);
if (m_menuChangedConnection.connected())
{
m_menuChangedConnection.disconnect();
if (menuChangedConnection.connected()) {
menuChangedConnection.disconnect();
}
m_menuChangedConnection = m_menuModel->signal_items_changed().connect(sigc::mem_fun(*this, &TrayIconWidget::on_menu_items_changed));
menuChangedConnection = menuModel->signal_items_changed().connect(
sigc::mem_fun(*this, &TrayIconWidget::on_menu_items_changed));
m_menuPopover->set_menu_model(m_menuModel);
menuPopover->set_menu_model(menuModel);
return true;
}
void TrayIconWidget::on_menu_items_changed(guint /*position*/, guint /*removed*/, guint /*added*/)
{
if (!m_menuModel)
{
void TrayIconWidget::on_menu_items_changed(guint /*position*/,
guint /*removed*/, guint /*added*/) {
if (!menuModel) {
return;
}
const auto count = m_menuModel->get_n_items();
std::cout << "[TrayIconWidget] items changed for " << m_id << ": " << count << " entries" << std::endl;
const auto count = menuModel->get_n_items();
std::cout << "[TrayIconWidget] items changed for " << id << ": " << count
<< " entries" << std::endl;
try_popup();
}
void TrayIconWidget::try_popup()
{
if (!m_menuPopupPending || !m_menuPopover || !m_menuModel)
{
void TrayIconWidget::try_popup() {
if (!menuPopupPending || !menuPopover || !menuModel) {
return;
}
if (m_menuModel->get_n_items() == 0)
{
if (menuModel->get_n_items() == 0) {
return;
}
Gdk::Rectangle rect(static_cast<int>(m_pendingX), static_cast<int>(m_pendingY), 1, 1);
m_menuPopover->set_pointing_to(rect);
m_menuPopover->popup();
m_menuPopupPending = false;
Gdk::Rectangle rect(static_cast<int>(pendingX), static_cast<int>(pendingY),
1, 1);
menuPopover->set_pointing_to(rect);
menuPopover->popup();
menuPopupPending = false;
}
void TrayIconWidget::populate_menu_items(const std::vector<TrayService::MenuNode> &nodes,
const Glib::RefPtr<Gio::Menu> &menu,
const Glib::RefPtr<Gio::SimpleActionGroup> &actions)
{
for (const auto &node : nodes)
{
if (!node.visible)
{
void TrayIconWidget::populate_menu_items(
const std::vector<TrayService::MenuNode> &nodes,
const Glib::RefPtr<Gio::Menu> &menu,
const Glib::RefPtr<Gio::SimpleActionGroup> &actions) {
for (const auto &node : nodes) {
if (!node.visible) {
continue;
}
if (node.separator)
{
if (node.separator) {
auto section = Gio::Menu::create();
menu->append_section("", section);
continue;
}
if (!node.children.empty())
{
if (!node.children.empty()) {
auto submenu = Gio::Menu::create();
populate_menu_items(node.children, submenu, actions);
auto submenuItem = Gio::MenuItem::create(node.label, Glib::ustring());
auto submenuItem =
Gio::MenuItem::create(node.label, Glib::ustring());
submenuItem->set_submenu(submenu);
if (!node.enabled)
{
submenuItem->set_attribute_value("enabled", Glib::Variant<bool>::create(false));
if (!node.enabled) {
submenuItem->set_attribute_value(
"enabled", Glib::Variant<bool>::create(false));
}
menu->append_item(submenuItem);
continue;
}
const std::string actionName = "item" + std::to_string(node.id);
auto menuItem = Gio::MenuItem::create(node.label, "dbusmenu." + actionName);
if (!node.enabled)
{
menuItem->set_attribute_value("enabled", Glib::Variant<bool>::create(false));
auto menuItem =
Gio::MenuItem::create(node.label, "dbusmenu." + actionName);
if (!node.enabled) {
menuItem->set_attribute_value("enabled",
Glib::Variant<bool>::create(false));
}
auto action = Gio::SimpleAction::create(actionName);
action->set_enabled(node.enabled);
action->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TrayIconWidget::on_menu_action), node.id));
action->signal_activate().connect(sigc::bind(
sigc::mem_fun(*this, &TrayIconWidget::on_menu_action), node.id));
actions->add_action(action);
menu->append_item(menuItem);
}
}
void TrayIconWidget::on_menu_action(const Glib::VariantBase & /*parameter*/, int itemId)
{
m_service.activate_menu_item(m_id, itemId);
if (m_menuPopover)
{
m_menuPopover->popdown();
void TrayIconWidget::on_menu_action(const Glib::VariantBase & /*parameter*/,
int itemId) {
service.activate_menu_item(id, itemId);
if (menuPopover) {
menuPopover->popdown();
}
}
TrayWidget::TrayWidget(TrayService &service)
: Gtk::Box(Gtk::Orientation::HORIZONTAL), m_service(service)
{
: Gtk::Box(Gtk::Orientation::HORIZONTAL), service(service) {
set_valign(Gtk::Align::CENTER);
set_halign(Gtk::Align::CENTER);
set_visible(false);
m_addConnection = m_service.signal_item_added().connect(sigc::mem_fun(*this, &TrayWidget::on_item_added));
m_removeConnection = m_service.signal_item_removed().connect(sigc::mem_fun(*this, &TrayWidget::on_item_removed));
m_updateConnection = m_service.signal_item_updated().connect(sigc::mem_fun(*this, &TrayWidget::on_item_updated));
addConnection = service.signal_item_added().connect(
sigc::mem_fun(*this, &TrayWidget::on_item_added));
removeConnection = service.signal_item_removed().connect(
sigc::mem_fun(*this, &TrayWidget::on_item_removed));
updateConnection = service.signal_item_updated().connect(
sigc::mem_fun(*this, &TrayWidget::on_item_updated));
rebuild_existing();
}
TrayWidget::~TrayWidget()
{
if (m_addConnection.connected())
{
m_addConnection.disconnect();
TrayWidget::~TrayWidget() {
if (addConnection.connected()) {
addConnection.disconnect();
}
if (m_removeConnection.connected())
{
m_removeConnection.disconnect();
if (removeConnection.connected()) {
removeConnection.disconnect();
}
if (m_updateConnection.connected())
{
m_updateConnection.disconnect();
if (updateConnection.connected()) {
updateConnection.disconnect();
}
}
void TrayWidget::rebuild_existing()
{
auto items = m_service.snapshotItems();
for (const auto &item : items)
{
void TrayWidget::rebuild_existing() {
auto items = service.snapshotItems();
for (const auto &item : items) {
on_item_added(item);
}
set_visible(!m_icons.empty());
set_visible(!icons.empty());
}
void TrayWidget::on_item_added(const TrayService::Item &item)
{
auto it = m_icons.find(item.id);
if (it != m_icons.end())
{
void TrayWidget::on_item_added(const TrayService::Item &item) {
auto it = icons.find(item.id);
if (it != icons.end()) {
it->second->update(item);
return;
}
auto icon = std::make_unique<TrayIconWidget>(m_service, item.id);
auto icon = std::make_unique<TrayIconWidget>(service, item.id);
icon->update(item);
auto *raw = icon.get();
append(*raw);
m_icons.emplace(item.id, std::move(icon));
icons.emplace(item.id, std::move(icon));
set_visible(true);
}
void TrayWidget::on_item_removed(const std::string &id)
{
auto it = m_icons.find(id);
if (it == m_icons.end())
{
void TrayWidget::on_item_removed(const std::string &id) {
auto it = icons.find(id);
if (it == icons.end()) {
return;
}
remove(*it->second);
it->second->unparent();
m_icons.erase(it);
icons.erase(it);
if (m_icons.empty())
{
if (icons.empty()) {
set_visible(false);
}
}
void TrayWidget::on_item_updated(const TrayService::Item &item)
{
auto it = m_icons.find(item.id);
if (it == m_icons.end())
{
void TrayWidget::on_item_updated(const TrayService::Item &item) {
auto it = icons.find(item.id);
if (it == icons.end()) {
on_item_added(item);
return;
}