Autostart option added
This commit is contained in:
109
src/trayicon.h
Normal file
109
src/trayicon.h
Normal file
@@ -0,0 +1,109 @@
|
||||
// gKeyMapper - the tray icon, spoken as a StatusNotifierItem.
|
||||
#ifndef GKEYMAPPER_TRAYICON_H
|
||||
#define GKEYMAPPER_TRAYICON_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
namespace gkeymapper {
|
||||
|
||||
// The tray icon. GTK4 has no tray widget (GtkStatusIcon was GTK3 and is gone), so
|
||||
// the icon is exported on the session bus as a StatusNotifierItem plus a
|
||||
// com.canonical.dbusmenu menu - exactly the protocol libxapp and libappindicator
|
||||
// wrap, only without their GTK3 dependency (a GTK4 process must not load GTK3).
|
||||
// The panel hosts it: Cinnamon's xapp-status applet, KDE, Unity, or the GNOME
|
||||
// AppIndicator extension.
|
||||
//
|
||||
// The panel is a different process, so the icon travels as a pixmap: it cannot
|
||||
// read the icons compiled into this binary.
|
||||
class TrayIcon {
|
||||
public:
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
TrayIcon() = default;
|
||||
~TrayIcon();
|
||||
TrayIcon(const TrayIcon&) = delete;
|
||||
TrayIcon& operator=(const TrayIcon&) = delete;
|
||||
|
||||
// Owns the item's bus name, exports the item and its menu and registers with
|
||||
// the panel's watcher - and again whenever the panel restarts (the watcher
|
||||
// owns the icon list, a restart loses it). `icon` is ARGB32 in network byte
|
||||
// order, which is the layout the protocol asks for.
|
||||
void start(std::vector<unsigned char> icon, int width, int height, Callback onShow,
|
||||
Callback onQuit);
|
||||
|
||||
// True once a panel hosts the icon, i.e. the icon is really on screen. Only
|
||||
// then hiding the window is safe: without a tray there is no way back.
|
||||
bool ready() const { return registered_; }
|
||||
|
||||
// The panel mirrors the menu once, so it has to be told when the texts in it
|
||||
// changed - a language switch. Nothing else about the icon changes.
|
||||
void refresh_labels();
|
||||
private:
|
||||
static void on_bus_acquired(GDBusConnection* connection, const gchar* name, gpointer userData);
|
||||
static void on_name_lost(GDBusConnection* connection, const gchar* name, gpointer userData);
|
||||
static void on_watcher_appeared(GDBusConnection* connection, const gchar* name,
|
||||
const gchar* nameOwner, gpointer userData);
|
||||
static void on_watcher_vanished(GDBusConnection* connection, const gchar* name,
|
||||
gpointer userData);
|
||||
static void on_register_reply(GObject* source, GAsyncResult* result, gpointer userData);
|
||||
|
||||
static void on_item_method_call(GDBusConnection* connection, const gchar* sender,
|
||||
const gchar* objectPath, const gchar* interfaceName,
|
||||
const gchar* methodName, GVariant* parameters,
|
||||
GDBusMethodInvocation* invocation, gpointer userData);
|
||||
static GVariant* on_item_get_property(GDBusConnection* connection, const gchar* sender,
|
||||
const gchar* objectPath, const gchar* interfaceName,
|
||||
const gchar* propertyName, GError** error,
|
||||
gpointer userData);
|
||||
static void on_menu_method_call(GDBusConnection* connection, const gchar* sender,
|
||||
const gchar* objectPath, const gchar* interfaceName,
|
||||
const gchar* methodName, GVariant* parameters,
|
||||
GDBusMethodInvocation* invocation, gpointer userData);
|
||||
static GVariant* on_menu_get_property(GDBusConnection* connection, const gchar* sender,
|
||||
const gchar* objectPath, const gchar* interfaceName,
|
||||
const gchar* propertyName, GError** error,
|
||||
gpointer userData);
|
||||
|
||||
void export_objects(GDBusConnection* connection);
|
||||
// Runs what a click on a menu entry means ("clicked" on Show or Close).
|
||||
void handle_event(int id, const char* eventId);
|
||||
// Notes which of the two watcher names is on the bus and registers there.
|
||||
void set_watcher_available(const char* name, bool available);
|
||||
void register_with_watcher();
|
||||
GVariant* icon_pixmaps() const;
|
||||
GVariant* tooltip() const;
|
||||
GVariant* layout(int parentId, int depth) const;
|
||||
GVariant* node(int id, int depth) const;
|
||||
GVariant* group_properties(GVariant* ids) const;
|
||||
GVariant* menu_property(int id, const char* name) const;
|
||||
|
||||
GDBusConnection* connection_ = nullptr;
|
||||
guint itemRegistration_ = 0;
|
||||
guint menuRegistration_ = 0;
|
||||
guint ownerId_ = 0;
|
||||
guint watcherId_ = 0;
|
||||
guint watcherIdX_ = 0;
|
||||
std::string serviceName_;
|
||||
std::vector<unsigned char> icon_;
|
||||
int iconWidth_ = 0;
|
||||
int iconHeight_ = 0;
|
||||
bool watcher_ = false;
|
||||
bool watcherAlias_ = false;
|
||||
bool registering_ = false;
|
||||
bool registered_ = false;
|
||||
const char* registeringWith_ = nullptr;
|
||||
std::string registeredWith_;
|
||||
// Bumped whenever the menu texts change; the panel compares it to know that
|
||||
// what it mirrored is stale.
|
||||
guint menuRevision_ = 1;
|
||||
Callback onShow_;
|
||||
Callback onQuit_;
|
||||
};
|
||||
|
||||
} // namespace gkeymapper
|
||||
|
||||
#endif // GKEYMAPPER_TRAYICON_H
|
||||
Reference in New Issue
Block a user