mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge branch 'gtktrayicon'
This commit is contained in:
commit
5dce927292
24
qtox.pro
24
qtox.pro
|
@ -237,6 +237,30 @@ contains(ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND, NO) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# The systray GTK backend implements a system tray icon compatible with many systems
|
||||||
|
unix:!macx:!android {
|
||||||
|
contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
|
||||||
|
} else {
|
||||||
|
DEFINES += ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
|
||||||
|
INCLUDEPATH += "/usr/include/gtk-2.0"
|
||||||
|
INCLUDEPATH += "/usr/include/glib-2.0"
|
||||||
|
INCLUDEPATH += "/usr/lib/glib-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/glib-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/lib/i386-linux-gnu/glib-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/lib/gtk-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/lib/i386-linux-gnu/gtk-2.0/include"
|
||||||
|
INCLUDEPATH += "/usr/include/atk-1.0"
|
||||||
|
INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0"
|
||||||
|
INCLUDEPATH += "/usr/include/cairo"
|
||||||
|
INCLUDEPATH += "/usr/include/pango-1.0"
|
||||||
|
|
||||||
|
|
||||||
|
LIBS += -lglib-2.0 -lgdk_pixbuf-2.0 -lgio-2.0 -lcairo -lgtk-x11-2.0 -lgdk-x11-2.0 -lgobject-2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
!android {
|
!android {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/friend.h \
|
src/friend.h \
|
||||||
|
|
|
@ -37,6 +37,42 @@ SystemTrayIcon::SystemTrayIcon()
|
||||||
app_indicator_set_menu(unityIndicator, GTK_MENU(unityMenu));
|
app_indicator_set_menu(unityIndicator, GTK_MENU(unityMenu));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
else if (desktop == "xfce" || (desktop == "kde"
|
||||||
|
&& getenv("KDE_SESSION_VERSION") == QString("4")))
|
||||||
|
{
|
||||||
|
qDebug() << "SystemTrayIcon: Using GTK backend";
|
||||||
|
backendType = SystrayBackendType::GTK;
|
||||||
|
gtk_init(nullptr, nullptr);
|
||||||
|
void (*callbackFreeImage)(guchar*, gpointer) =
|
||||||
|
[](guchar*, gpointer image)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<QImage*>(image);
|
||||||
|
};
|
||||||
|
QImage* image = new QImage(":/img/icon.png");
|
||||||
|
if (image->format() != QImage::Format_RGBA8888_Premultiplied)
|
||||||
|
*image = image->convertToFormat(QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image->bits(), GDK_COLORSPACE_RGB, image->hasAlphaChannel(),
|
||||||
|
8, image->width(), image->height(),
|
||||||
|
image->bytesPerLine(), callbackFreeImage, image);
|
||||||
|
gtkIcon = gtk_status_icon_new_from_pixbuf(pixbuf);
|
||||||
|
gtkMenu = gtk_menu_new();
|
||||||
|
|
||||||
|
void (*callbackTrigger)(GtkStatusIcon*, gpointer) =
|
||||||
|
[](GtkStatusIcon*, gpointer data)
|
||||||
|
{
|
||||||
|
((SystemTrayIcon*)data)->activated(QSystemTrayIcon::Trigger);
|
||||||
|
};
|
||||||
|
g_signal_connect(gtkIcon, "activate", G_CALLBACK(callbackTrigger), this);
|
||||||
|
void (*callbackButtonClick)(GtkStatusIcon*, GdkEvent*, gpointer) =
|
||||||
|
[](GtkStatusIcon*, GdkEvent* event, gpointer data)
|
||||||
|
{
|
||||||
|
if (event->button.button == 2)
|
||||||
|
((SystemTrayIcon*)data)->activated(QSystemTrayIcon::MiddleClick);
|
||||||
|
};
|
||||||
|
g_signal_connect(gtkIcon, "button-release-event", G_CALLBACK(callbackButtonClick), this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND
|
#ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND
|
||||||
else if (desktop == "kde"
|
else if (desktop == "kde"
|
||||||
&& getenv("KDE_SESSION_VERSION") == QString("5"))
|
&& getenv("KDE_SESSION_VERSION") == QString("5"))
|
||||||
|
@ -156,6 +192,51 @@ void SystemTrayIcon::setContextMenu(QMenu* menu)
|
||||||
g_signal_connect(statusNotifier, "context-menu", G_CALLBACK(callbackMenu), this);
|
g_signal_connect(statusNotifier, "context-menu", G_CALLBACK(callbackMenu), this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
else if (backendType == SystrayBackendType::GTK)
|
||||||
|
{
|
||||||
|
for (QAction* a : menu->actions())
|
||||||
|
{
|
||||||
|
QString aText = a->text().replace('&',"");
|
||||||
|
GtkWidget* item;
|
||||||
|
if (a->isSeparator())
|
||||||
|
item = gtk_menu_item_new();
|
||||||
|
else if (a->icon().isNull())
|
||||||
|
item = gtk_menu_item_new_with_label(aText.toStdString().c_str());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void (*callbackFreeImage)(guchar*, gpointer) =
|
||||||
|
[](guchar*, gpointer image)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<QImage*>(image);
|
||||||
|
};
|
||||||
|
QImage* image = new QImage(a->icon().pixmap(64, 64).toImage());
|
||||||
|
if (image->format() != QImage::Format_RGBA8888_Premultiplied)
|
||||||
|
*image = image->convertToFormat(QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image->bits(), GDK_COLORSPACE_RGB, image->hasAlphaChannel(),
|
||||||
|
8, image->width(), image->height(),
|
||||||
|
image->bytesPerLine(), callbackFreeImage, image);
|
||||||
|
item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str());
|
||||||
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf(pixbuf));
|
||||||
|
gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE);
|
||||||
|
}
|
||||||
|
gtk_menu_shell_append(GTK_MENU_SHELL(gtkMenu), item);
|
||||||
|
void (*callback)(GtkMenu*, gpointer data) = [](GtkMenu*, gpointer a)
|
||||||
|
{
|
||||||
|
((QAction*)a)->activate(QAction::Trigger);
|
||||||
|
};
|
||||||
|
g_signal_connect(item, "activate", G_CALLBACK(callback), a);
|
||||||
|
gtk_widget_show(item);
|
||||||
|
}
|
||||||
|
void (*callbackMenu)(StatusNotifier*, gint, gint, gpointer) =
|
||||||
|
[](StatusNotifier*, gint, gint, gpointer data)
|
||||||
|
{
|
||||||
|
gtk_widget_show_all(((SystemTrayIcon*)data)->gtkMenu);
|
||||||
|
gtk_menu_popup(GTK_MENU(((SystemTrayIcon*)data)->gtkMenu), 0, 0, 0, 0, 3, gtk_get_current_event_time());
|
||||||
|
};
|
||||||
|
g_signal_connect(gtkIcon, "popup-menu", G_CALLBACK(callbackMenu), this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
|
@ -224,6 +305,15 @@ void SystemTrayIcon::setVisible(bool newState)
|
||||||
status_notifier_set_status(statusNotifier, STATUS_NOTIFIER_STATUS_PASSIVE);
|
status_notifier_set_status(statusNotifier, STATUS_NOTIFIER_STATUS_PASSIVE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
else if (backendType == SystrayBackendType::GTK)
|
||||||
|
{
|
||||||
|
if (newState)
|
||||||
|
gtk_status_icon_set_visible(gtkIcon, true);
|
||||||
|
else
|
||||||
|
gtk_status_icon_set_visible(gtkIcon, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
|
@ -262,6 +352,23 @@ void SystemTrayIcon::setIcon(QIcon &&icon)
|
||||||
status_notifier_set_from_pixbuf(statusNotifier, STATUS_NOTIFIER_ICON, pixbuf);
|
status_notifier_set_from_pixbuf(statusNotifier, STATUS_NOTIFIER_ICON, pixbuf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
else if (backendType == SystrayBackendType::GTK)
|
||||||
|
{
|
||||||
|
void (*callbackFreeImage)(guchar*, gpointer) =
|
||||||
|
[](guchar*, gpointer image)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<QImage*>(image);
|
||||||
|
};
|
||||||
|
QImage* image = new QImage(icon.pixmap(64, 64).toImage());
|
||||||
|
if (image->format() != QImage::Format_RGBA8888_Premultiplied)
|
||||||
|
*image = image->convertToFormat(QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image->bits(), GDK_COLORSPACE_RGB, image->hasAlphaChannel(),
|
||||||
|
8, image->width(), image->height(),
|
||||||
|
image->bytesPerLine(), callbackFreeImage, image);
|
||||||
|
gtk_status_icon_set_from_pixbuf(gtkIcon, pixbuf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,10 @@ private:
|
||||||
StatusNotifier* statusNotifier;
|
StatusNotifier* statusNotifier;
|
||||||
GtkWidget* snMenu;
|
GtkWidget* snMenu;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
GtkStatusIcon* gtkIcon;
|
||||||
|
GtkWidget* gtkMenu;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SYSTEMTRAYICON_H
|
#endif // SYSTEMTRAYICON_H
|
||||||
|
|
|
@ -30,6 +30,17 @@ extern "C" {
|
||||||
#define signals public
|
#define signals public
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
#ifdef signals
|
||||||
|
#undef signals
|
||||||
|
#endif
|
||||||
|
extern "C" {
|
||||||
|
#include <libappindicator/app-indicator.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
}
|
||||||
|
#define signals public
|
||||||
|
#endif
|
||||||
|
|
||||||
enum class SystrayBackendType
|
enum class SystrayBackendType
|
||||||
{
|
{
|
||||||
Qt,
|
Qt,
|
||||||
|
@ -40,15 +51,9 @@ enum class SystrayBackendType
|
||||||
#ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND
|
#ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND
|
||||||
StatusNotifier,
|
StatusNotifier,
|
||||||
#endif
|
#endif
|
||||||
};
|
#ifdef ENABLE_SYSTRAY_GTK_BACKEND
|
||||||
|
GTK,
|
||||||
union SystrayBackend
|
|
||||||
{
|
|
||||||
QSystemTrayIcon *qt;
|
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
|
||||||
AppIndicator *unity;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // SYSTEMTRAYICON_PRIVATE_H
|
#endif // SYSTEMTRAYICON_PRIVATE_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user