/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * * LXQt - a lightweight, Qt based, desktop toolset * http://lxqt.org/ * * Copyright: 2015 LXQt team * Authors: * Paulo Lieuthier * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "lxqtsystemtrayicon.h" #include #include #include #include #include #include #include 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(menuItem)) { bool inserted = false; if (SystemTrayMenuItem *oursBefore = qobject_cast(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(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(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; } LXQtSystemTrayIcon::LXQtSystemTrayIcon() : QPlatformSystemTrayIcon(), mSni(nullptr) { // register types qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); } LXQtSystemTrayIcon::~LXQtSystemTrayIcon() { } void LXQtSystemTrayIcon::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("application-exit")); connect(menuItem, &QPlatformMenuItem::activated, qApp, &QApplication::quit); menu->insertMenuItem(menuItem, nullptr); updateMenu(menu); connect(mSni, &StatusNotifierItem::activateRequested, [this](const QPoint &) { emit activated(QPlatformSystemTrayIcon::Trigger); }); connect(mSni, &StatusNotifierItem::secondaryActivateRequested, [this](const QPoint &) { emit activated(QPlatformSystemTrayIcon::MiddleClick); }); } } void LXQtSystemTrayIcon::cleanup() { delete mSni; mSni = nullptr; } void LXQtSystemTrayIcon::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 LXQtSystemTrayIcon::updateToolTip(const QString &tooltip) { if (!mSni) return; mSni->setToolTipTitle(tooltip); } void LXQtSystemTrayIcon::updateMenu(QPlatformMenu *menu) { if (!mSni) return; if (SystemTrayMenu *ourMenu = qobject_cast(menu)) mSni->setContextMenu(ourMenu->menu()); } QPlatformMenu *LXQtSystemTrayIcon::createMenu() const { return new SystemTrayMenu(); } QRect LXQtSystemTrayIcon::geometry() const { // StatusNotifierItem doesn't provide the geometry return QRect(); } void LXQtSystemTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, MessageIcon, int secs) { if (!mSni) return; mSni->showMessage(title, msg, icon.name(), secs); } bool LXQtSystemTrayIcon::isSystemTrayAvailable() const { QDBusInterface systrayHost("org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher"); return systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool(); } bool LXQtSystemTrayIcon::supportsMessages() const { return true; }