mirror of https://github.com/cutefishos/qt-plugins
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			355 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			355 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C++
		
	
#include "systemtrayicon.h"
 | 
						|
#include <QAction>
 | 
						|
#include <QIcon>
 | 
						|
#include <QMenu>
 | 
						|
#include <QRect>
 | 
						|
#include <QApplication>
 | 
						|
#include <QDBusMetaType>
 | 
						|
#include <QDBusInterface>
 | 
						|
 | 
						|
SystemTrayMenu::SystemTrayMenu()
 | 
						|
    : QPlatformMenu(),
 | 
						|
    m_tag(0),
 | 
						|
    m_menu(new QMenu())
 | 
						|
{
 | 
						|
    connect(m_menu.data(), &QMenu::aboutToShow, this, &QPlatformMenu::aboutToShow);
 | 
						|
    connect(m_menu.data(), &QMenu::aboutToHide, this, &QPlatformMenu::aboutToHide);
 | 
						|
}
 | 
						|
 | 
						|
SystemTrayMenu::~SystemTrayMenu()
 | 
						|
{
 | 
						|
    if (m_menu)
 | 
						|
        m_menu->deleteLater();
 | 
						|
}
 | 
						|
 | 
						|
QPlatformMenuItem *SystemTrayMenu::createMenuItem() const
 | 
						|
{
 | 
						|
    return new SystemTrayMenuItem();
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
 | 
						|
{
 | 
						|
    if (SystemTrayMenuItem *ours = qobject_cast<SystemTrayMenuItem*>(menuItem))
 | 
						|
    {
 | 
						|
        bool inserted = false;
 | 
						|
 | 
						|
        if (SystemTrayMenuItem *oursBefore = qobject_cast<SystemTrayMenuItem*>(before))
 | 
						|
        {
 | 
						|
            for (auto it = m_items.begin(); it != m_items.end(); ++it)
 | 
						|
            {
 | 
						|
                if (*it == oursBefore)
 | 
						|
                {
 | 
						|
                    m_items.insert(it, ours);
 | 
						|
                    if (m_menu)
 | 
						|
                        m_menu->insertAction(oursBefore->action(), ours->action());
 | 
						|
 | 
						|
                    inserted = true;
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (!inserted)
 | 
						|
        {
 | 
						|
            m_items.append(ours);
 | 
						|
            if (m_menu)
 | 
						|
                m_menu->addAction(ours->action());
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
QPlatformMenuItem *SystemTrayMenu::menuItemAt(int position) const
 | 
						|
{
 | 
						|
    if (position < m_items.size())
 | 
						|
        return m_items.at(position);
 | 
						|
 | 
						|
    return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
QPlatformMenuItem *SystemTrayMenu::menuItemForTag(quintptr tag) const
 | 
						|
{
 | 
						|
    auto it = std::find_if(m_items.constBegin(), m_items.constEnd(), [tag] (SystemTrayMenuItem *item)
 | 
						|
    {
 | 
						|
        return item->tag() == tag;
 | 
						|
    });
 | 
						|
 | 
						|
    if (it != m_items.constEnd())
 | 
						|
        return *it;
 | 
						|
 | 
						|
    return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::removeMenuItem(QPlatformMenuItem *menuItem)
 | 
						|
{
 | 
						|
    if (SystemTrayMenuItem *ours = qobject_cast<SystemTrayMenuItem*>(menuItem))
 | 
						|
    {
 | 
						|
        m_items.removeOne(ours);
 | 
						|
        if (ours->action() && m_menu)
 | 
						|
            m_menu->removeAction(ours->action());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::setEnabled(bool enabled)
 | 
						|
{
 | 
						|
    if (!m_menu)
 | 
						|
        return;
 | 
						|
 | 
						|
    m_menu->setEnabled(enabled);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::setIcon(const QIcon &icon)
 | 
						|
{
 | 
						|
    if (!m_menu)
 | 
						|
        return;
 | 
						|
 | 
						|
    m_menu->setIcon(icon);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::setTag(quintptr tag)
 | 
						|
{
 | 
						|
    m_tag = tag;
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::setText(const QString &text)
 | 
						|
{
 | 
						|
    if (!m_menu)
 | 
						|
        return;
 | 
						|
 | 
						|
    m_menu->setTitle(text);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::setVisible(bool visible)
 | 
						|
{
 | 
						|
    if (!m_menu)
 | 
						|
        return;
 | 
						|
 | 
						|
    m_menu->setVisible(visible);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::syncMenuItem(QPlatformMenuItem *)
 | 
						|
{
 | 
						|
    // Nothing to do
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenu::syncSeparatorsCollapsible(bool enable)
 | 
						|
{
 | 
						|
    if (!m_menu)
 | 
						|
        return;
 | 
						|
 | 
						|
    m_menu->setSeparatorsCollapsible(enable);
 | 
						|
}
 | 
						|
 | 
						|
quintptr SystemTrayMenu::tag() const
 | 
						|
{
 | 
						|
    return m_tag;
 | 
						|
}
 | 
						|
 | 
						|
QMenu *SystemTrayMenu::menu() const
 | 
						|
{
 | 
						|
    return m_menu.data();
 | 
						|
}
 | 
						|
 | 
						|
SystemTrayMenuItem::SystemTrayMenuItem()
 | 
						|
    : QPlatformMenuItem(),
 | 
						|
    m_tag(0),
 | 
						|
    m_action(new QAction(this))
 | 
						|
{
 | 
						|
    connect(m_action, &QAction::triggered, this, &QPlatformMenuItem::activated);
 | 
						|
    connect(m_action, &QAction::hovered, this, &QPlatformMenuItem::hovered);
 | 
						|
}
 | 
						|
 | 
						|
SystemTrayMenuItem::~SystemTrayMenuItem()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setCheckable(bool checkable)
 | 
						|
{
 | 
						|
    m_action->setCheckable(checkable);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setChecked(bool isChecked)
 | 
						|
{
 | 
						|
    m_action->setChecked(isChecked);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setEnabled(bool enabled)
 | 
						|
{
 | 
						|
    m_action->setEnabled(enabled);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setFont(const QFont &font)
 | 
						|
{
 | 
						|
    m_action->setFont(font);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setIcon(const QIcon &icon)
 | 
						|
{
 | 
						|
    m_action->setIcon(icon);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setIsSeparator(bool isSeparator)
 | 
						|
{
 | 
						|
    m_action->setSeparator(isSeparator);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setMenu(QPlatformMenu *menu)
 | 
						|
{
 | 
						|
    if (SystemTrayMenu *ourMenu = qobject_cast<SystemTrayMenu *>(menu))
 | 
						|
        m_action->setMenu(ourMenu->menu());
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setRole(QPlatformMenuItem::MenuRole)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setShortcut(const QKeySequence &shortcut)
 | 
						|
{
 | 
						|
    m_action->setShortcut(shortcut);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setTag(quintptr tag)
 | 
						|
{
 | 
						|
    m_tag = tag;
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setText(const QString &text)
 | 
						|
{
 | 
						|
    m_action->setText(text);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setVisible(bool isVisible)
 | 
						|
{
 | 
						|
    m_action->setVisible(isVisible);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayMenuItem::setIconSize(int)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
quintptr SystemTrayMenuItem::tag() const
 | 
						|
{
 | 
						|
    return m_tag;
 | 
						|
}
 | 
						|
 | 
						|
QAction *SystemTrayMenuItem::action() const
 | 
						|
{
 | 
						|
    return m_action;
 | 
						|
}
 | 
						|
 | 
						|
SystemTrayIcon::SystemTrayIcon()
 | 
						|
    : QPlatformSystemTrayIcon(),
 | 
						|
    mSni(nullptr)
 | 
						|
{
 | 
						|
    // register types
 | 
						|
    qDBusRegisterMetaType<ToolTip>();
 | 
						|
    qDBusRegisterMetaType<IconPixmap>();
 | 
						|
    qDBusRegisterMetaType<IconPixmapList>();
 | 
						|
}
 | 
						|
 | 
						|
SystemTrayIcon::~SystemTrayIcon()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::init()
 | 
						|
{
 | 
						|
    if (!mSni)
 | 
						|
    {
 | 
						|
        mSni = new StatusNotifierItem(QString::number(QCoreApplication::applicationPid()), this);
 | 
						|
        mSni->setTitle(QApplication::applicationDisplayName());
 | 
						|
 | 
						|
        // default menu
 | 
						|
        QPlatformMenu *menu = createMenu();
 | 
						|
        menu->setParent(mSni);
 | 
						|
        QPlatformMenuItem *menuItem = menu->createMenuItem();
 | 
						|
        menuItem->setParent(menu);
 | 
						|
        menuItem->setText(tr("Quit"));
 | 
						|
        menuItem->setIcon(QIcon::fromTheme(QLatin1String("application-exit")));
 | 
						|
        connect(menuItem, &QPlatformMenuItem::activated, qApp, &QApplication::quit);
 | 
						|
        menu->insertMenuItem(menuItem, nullptr);
 | 
						|
        updateMenu(menu);
 | 
						|
 | 
						|
        connect(mSni, &StatusNotifierItem::activateRequested, [this](const QPoint &)
 | 
						|
        {
 | 
						|
            Q_EMIT activated(QPlatformSystemTrayIcon::Trigger);
 | 
						|
        });
 | 
						|
 | 
						|
        connect(mSni, &StatusNotifierItem::secondaryActivateRequested, [this](const QPoint &)
 | 
						|
        {
 | 
						|
            Q_EMIT activated(QPlatformSystemTrayIcon::MiddleClick);
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::cleanup()
 | 
						|
{
 | 
						|
    delete mSni;
 | 
						|
    mSni = nullptr;
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::updateIcon(const QIcon &icon)
 | 
						|
{
 | 
						|
    if (!mSni)
 | 
						|
        return;
 | 
						|
 | 
						|
    if (icon.name().isEmpty())
 | 
						|
    {
 | 
						|
        mSni->setIconByPixmap(icon);
 | 
						|
        mSni->setToolTipIconByPixmap(icon);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        mSni->setIconByName(icon.name());
 | 
						|
        mSni->setToolTipIconByName(icon.name());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::updateToolTip(const QString &tooltip)
 | 
						|
{
 | 
						|
    if (!mSni)
 | 
						|
        return;
 | 
						|
 | 
						|
    mSni->setToolTipTitle(tooltip);
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::updateMenu(QPlatformMenu *menu)
 | 
						|
{
 | 
						|
    if (!mSni)
 | 
						|
        return;
 | 
						|
 | 
						|
    if (SystemTrayMenu *ourMenu = qobject_cast<SystemTrayMenu*>(menu))
 | 
						|
        mSni->setContextMenu(ourMenu->menu());
 | 
						|
}
 | 
						|
 | 
						|
QPlatformMenu *SystemTrayIcon::createMenu() const
 | 
						|
{
 | 
						|
    return new SystemTrayMenu();
 | 
						|
}
 | 
						|
 | 
						|
QRect SystemTrayIcon::geometry() const
 | 
						|
{
 | 
						|
    // StatusNotifierItem doesn't provide the geometry
 | 
						|
    return {};
 | 
						|
}
 | 
						|
 | 
						|
void SystemTrayIcon::showMessage(const QString &title, const QString &msg,
 | 
						|
                                     const QIcon &icon, MessageIcon, int secs)
 | 
						|
{
 | 
						|
    if (!mSni)
 | 
						|
        return;
 | 
						|
 | 
						|
    mSni->showMessage(title, msg, icon.name(), secs);
 | 
						|
}
 | 
						|
 | 
						|
bool SystemTrayIcon::isSystemTrayAvailable() const
 | 
						|
{
 | 
						|
    QDBusInterface systrayHost(QLatin1String("org.kde.StatusNotifierWatcher"),
 | 
						|
                               QLatin1String("/StatusNotifierWatcher"),
 | 
						|
                               QLatin1String("org.kde.StatusNotifierWatcher"));
 | 
						|
 | 
						|
    return systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool();
 | 
						|
}
 | 
						|
 | 
						|
bool SystemTrayIcon::supportsMessages() const
 | 
						|
{
 | 
						|
    return true;
 | 
						|
} |