Files
bar/include/widgets/tray.hpp
2026-01-03 22:55:02 +01:00

80 lines
2.4 KiB
C++

#pragma once
#include <giomm/menu.h>
#include <giomm/menuitem.h>
#include <giomm/menumodel.h>
#include <giomm/simpleaction.h>
#include <giomm/simpleactiongroup.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/gestureclick.h>
#include <gtkmm/image.h>
#include <gtkmm/picture.h>
#include <gtkmm/popovermenu.h>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "services/tray.hpp"
#include "components/base/button.hpp"
class TrayIconWidget : public Button {
public:
TrayIconWidget(std::string id);
~TrayIconWidget() override;
void update(const TrayService::Item &item);
private:
TrayService &service = *TrayService::getInstance();
std::string id;
Gtk::Box container;
Gtk::Picture picture;
Gtk::Image image;
Glib::RefPtr<Gtk::GestureClick> primaryGesture;
Glib::RefPtr<Gtk::GestureClick> middleGesture;
Glib::RefPtr<Gtk::GestureClick> secondaryGesture;
Glib::RefPtr<Gtk::PopoverMenu> menuPopover;
Glib::RefPtr<Gio::SimpleActionGroup> menuActions;
Glib::RefPtr<Gio::MenuModel> menuModel;
bool menuPopupPending = false;
bool menuRequestInFlight = false;
bool hasRemoteMenu = false;
std::shared_ptr<bool> aliveFlag;
double pendingX = 0.0;
double pendingY = 0.0;
void on_primary_released(int n_press, double x, double y);
void on_middle_released(int n_press, double x, double y);
void on_secondary_released(int n_press, double x, double y);
void on_menu_layout_ready(std::optional<TrayService::MenuNode> layout);
void
populate_menu_items(const std::vector<TrayService::MenuNode> &nodes,
const Glib::RefPtr<Gio::Menu> &menu,
const Glib::RefPtr<Gio::SimpleActionGroup> &actions);
void on_menu_action(const Glib::VariantBase &parameter, int itemId);
bool try_get_pending_coords(int32_t &outX, int32_t &outY) const;
};
class TrayWidget : public Gtk::Box {
public:
explicit TrayWidget();
~TrayWidget() override;
private:
TrayService *service = TrayService::getInstance();
std::map<std::string, std::unique_ptr<TrayIconWidget>> icons;
sigc::connection addConnection;
sigc::connection removeConnection;
sigc::connection updateConnection;
void on_item_added(const TrayService::Item &item);
void on_item_removed(const std::string &id);
void on_item_updated(const TrayService::Item &item);
void rebuild_existing();
};