mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Implement SystemTrayIcon Unity backend
With some limitations and some awful hacks, since appindicators can not differentiate left click, right click and middle click. It's already a massive pain to just get a signal when the menu is shown, without actually knowing what opened it. I love ubuntu.
This commit is contained in:
parent
f8e069f053
commit
fe83dd9445
4
qtox.pro
4
qtox.pro
|
@ -65,9 +65,9 @@ contains(ENABLE_SYSTRAY_UNITY_BACKEND, YES) {
|
||||||
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include"
|
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include"
|
||||||
INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0"
|
INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0"
|
||||||
INCLUDEPATH += "/usr/include/atk-1.0"
|
INCLUDEPATH += "/usr/include/atk-1.0"
|
||||||
|
INCLUDEPATH += "/usr/include/libdbusmenu-glib-0.4"
|
||||||
|
|
||||||
LIBS += -L/usr/lib/x86_64-linux-gnu -lappindicator
|
LIBS += -lgobject-2.0 -lappindicator -lgtk-x11-2.0
|
||||||
LIBS += -L/usr/lib/x86_64-linux-gnu -lgtk-x11-2.0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contains(DISABLE_PLATFORM_EXT, YES) {
|
contains(DISABLE_PLATFORM_EXT, YES) {
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#include "systemtrayicon.h"
|
#include "systemtrayicon.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <libdbusmenu-glib/server.h>
|
||||||
|
#include "src/misc/settings.h"
|
||||||
|
|
||||||
SystemTrayIcon::SystemTrayIcon()
|
SystemTrayIcon::SystemTrayIcon()
|
||||||
{
|
{
|
||||||
|
@ -10,8 +14,25 @@ SystemTrayIcon::SystemTrayIcon()
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (desktop.toLower() == "unity")
|
else if (desktop.toLower() == "unity")
|
||||||
{
|
{
|
||||||
|
QString settingsDir = Settings::getSettingsDirPath();
|
||||||
|
QFile iconFile(settingsDir+"/icon.png");
|
||||||
|
if (iconFile.open(QIODevice::Truncate | QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
QFile resIconFile(":/img/icon.png");
|
||||||
|
if (resIconFile.open(QIODevice::ReadOnly))
|
||||||
|
iconFile.write(resIconFile.readAll());
|
||||||
|
resIconFile.close();
|
||||||
|
iconFile.close();
|
||||||
|
}
|
||||||
backendType = SystrayBackendType::Unity;
|
backendType = SystrayBackendType::Unity;
|
||||||
unityMenu = gtk_menu_new();
|
unityMenu = gtk_menu_new();
|
||||||
|
unityIndicator = app_indicator_new_with_path(
|
||||||
|
"qTox",
|
||||||
|
"icon",
|
||||||
|
APP_INDICATOR_CATEGORY_APPLICATION_STATUS,
|
||||||
|
settingsDir.toStdString().c_str()
|
||||||
|
);
|
||||||
|
app_indicator_set_menu(unityIndicator, GTK_MENU(unityMenu));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -21,13 +42,59 @@ SystemTrayIcon::SystemTrayIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SystemTrayIcon::extractIconToFile(QIcon icon, QString name)
|
||||||
|
{
|
||||||
|
QString iconPath;
|
||||||
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
|
iconPath = Settings::getSettingsDirPath()+"/"+name+".png";
|
||||||
|
QSize iconSize = icon.actualSize(QSize{64,64});
|
||||||
|
icon.pixmap(iconSize).save(iconPath);
|
||||||
|
#endif
|
||||||
|
return iconPath;
|
||||||
|
}
|
||||||
|
|
||||||
void SystemTrayIcon::setContextMenu(QMenu* menu)
|
void SystemTrayIcon::setContextMenu(QMenu* menu)
|
||||||
{
|
{
|
||||||
if (false);
|
if (false);
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
qCritical() << "SystemTrayIcon::setContextMenu: Not implemented with Unity backend";
|
for (QAction* a : menu->actions())
|
||||||
|
{
|
||||||
|
gtk_image_menu_item_new();
|
||||||
|
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
|
||||||
|
{
|
||||||
|
QString iconPath = extractIconToFile(a->icon(),"iconmenu"+a->icon().name());
|
||||||
|
GtkWidget* image = gtk_image_new_from_file(iconPath.toStdString().c_str());
|
||||||
|
item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str());
|
||||||
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
||||||
|
gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE);
|
||||||
|
}
|
||||||
|
gtk_menu_shell_append(GTK_MENU_SHELL(unityMenu), 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);
|
||||||
|
}
|
||||||
|
app_indicator_set_menu(unityIndicator, GTK_MENU(unityMenu));
|
||||||
|
DbusmenuServer *menuServer;
|
||||||
|
DbusmenuMenuitem *rootMenuItem;
|
||||||
|
g_object_get(unityIndicator, "dbus-menu-server", &menuServer, NULL);
|
||||||
|
g_object_get(menuServer, "root-node", &rootMenuItem, NULL);
|
||||||
|
void (*callback)(DbusmenuMenuitem *, gpointer) =
|
||||||
|
[](DbusmenuMenuitem *, gpointer data)
|
||||||
|
{
|
||||||
|
((SystemTrayIcon*)data)->activated(QSystemTrayIcon::Unknown);
|
||||||
|
};
|
||||||
|
g_signal_connect(rootMenuItem, "about-to-show", G_CALLBACK(callback), this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -52,7 +119,10 @@ void SystemTrayIcon::setVisible(bool newState)
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
qCritical() << "SystemTrayIcon::setVisible: Not implemented with Unity backend";
|
if (newState)
|
||||||
|
app_indicator_set_status(unityIndicator, APP_INDICATOR_STATUS_ACTIVE);
|
||||||
|
else
|
||||||
|
app_indicator_set_status(unityIndicator, APP_INDICATOR_STATUS_PASSIVE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -70,7 +140,17 @@ void SystemTrayIcon::setIcon(QIcon &&icon)
|
||||||
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
#ifdef ENABLE_SYSTRAY_UNITY_BACKEND
|
||||||
else if (backendType == SystrayBackendType::Unity)
|
else if (backendType == SystrayBackendType::Unity)
|
||||||
{
|
{
|
||||||
qCritical() << "SystemTrayIcon::setIcon: Not implemented with Unity backend";
|
// Alternate file names or appindicator will not reload the icon
|
||||||
|
if (app_indicator_get_icon(unityIndicator) == QString("icon2"))
|
||||||
|
{
|
||||||
|
extractIconToFile(icon,"icon");
|
||||||
|
app_indicator_set_icon_full(unityIndicator, "icon","qtox");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extractIconToFile(icon,"icon2");
|
||||||
|
app_indicator_set_icon_full(unityIndicator, "icon2","qtox");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
|
|
@ -21,6 +21,9 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void activated(QSystemTrayIcon::ActivationReason);
|
void activated(QSystemTrayIcon::ActivationReason);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString extractIconToFile(QIcon icon, QString name="icon");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SystrayBackendType backendType;
|
SystrayBackendType backendType;
|
||||||
QSystemTrayIcon* qtIcon;
|
QSystemTrayIcon* qtIcon;
|
||||||
|
|
|
@ -622,6 +622,10 @@ void Widget::onIconClick(QSystemTrayIcon::ActivationReason reason)
|
||||||
case QSystemTrayIcon::MiddleClick:
|
case QSystemTrayIcon::MiddleClick:
|
||||||
hide();
|
hide();
|
||||||
break;
|
break;
|
||||||
|
case QSystemTrayIcon::Unknown:
|
||||||
|
if (isHidden())
|
||||||
|
forceShow();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user