forked from quickshell/quickshell
service/tray: move menu access to SystemTrayMenuWatcher
This commit is contained in:
parent
3c0456a3c0
commit
e7cfb5cf37
2
docs
2
docs
|
@ -1 +1 @@
|
||||||
Subproject commit 0488683f290c9bf38147de06c2692a1d9b98ae07
|
Subproject commit 149b784a5a4c40ada67cb9f6af5a5350678ab6d4
|
|
@ -104,7 +104,7 @@ class DBusMenuItem: public QObject {
|
||||||
/// > instead of checking if `children` is empty.
|
/// > instead of checking if `children` is empty.
|
||||||
Q_PROPERTY(QQmlListProperty<DBusMenuItem> children READ children NOTIFY childrenChanged);
|
Q_PROPERTY(QQmlListProperty<DBusMenuItem> children READ children NOTIFY childrenChanged);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
QML_NAMED_ELEMENT(DBusMenu);
|
QML_ELEMENT;
|
||||||
QML_UNCREATABLE("DBusMenus can only be acquired from a DBusMenuHandle");
|
QML_UNCREATABLE("DBusMenus can only be acquired from a DBusMenuHandle");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -29,11 +29,8 @@ SystemTrayItem::SystemTrayItem(qs::service::sni::StatusNotifierItem* item, QObje
|
||||||
QObject::connect(this->item, &StatusNotifierItem::iconChanged, this, &SystemTrayItem::iconChanged);
|
QObject::connect(this->item, &StatusNotifierItem::iconChanged, this, &SystemTrayItem::iconChanged);
|
||||||
QObject::connect(&this->item->tooltip, &AbstractDBusProperty::changed, this, &SystemTrayItem::tooltipTitleChanged);
|
QObject::connect(&this->item->tooltip, &AbstractDBusProperty::changed, this, &SystemTrayItem::tooltipTitleChanged);
|
||||||
QObject::connect(&this->item->tooltip, &AbstractDBusProperty::changed, this, &SystemTrayItem::tooltipDescriptionChanged);
|
QObject::connect(&this->item->tooltip, &AbstractDBusProperty::changed, this, &SystemTrayItem::tooltipDescriptionChanged);
|
||||||
QObject::connect(&this->item->menuPath, &AbstractDBusProperty::changed, this, &SystemTrayItem::onMenuPathChanged);
|
|
||||||
QObject::connect(&this->item->isMenu, &AbstractDBusProperty::changed, this, &SystemTrayItem::onlyMenuChanged);
|
QObject::connect(&this->item->isMenu, &AbstractDBusProperty::changed, this, &SystemTrayItem::onlyMenuChanged);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
if (!this->item->menuPath.get().path().isEmpty()) this->onMenuPathChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SystemTrayItem::id() const {
|
QString SystemTrayItem::id() const {
|
||||||
|
@ -89,30 +86,14 @@ QString SystemTrayItem::tooltipDescription() const {
|
||||||
return this->item->tooltip.get().description;
|
return this->item->tooltip.get().description;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusMenuItem* SystemTrayItem::menu() const {
|
|
||||||
if (this->mMenu == nullptr) return nullptr;
|
|
||||||
return &this->mMenu->rootItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SystemTrayItem::onlyMenu() const {
|
bool SystemTrayItem::onlyMenu() const {
|
||||||
if (this->item == nullptr) return false;
|
if (this->item == nullptr) return false;
|
||||||
return this->item->isMenu.get();
|
return this->item->isMenu.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTrayItem::onMenuPathChanged() {
|
void SystemTrayItem::activate() const { this->item->activate(); }
|
||||||
if (this->mMenu != nullptr) {
|
void SystemTrayItem::secondaryActivate() const { this->item->secondaryActivate(); }
|
||||||
this->mMenu->deleteLater();
|
void SystemTrayItem::scroll(qint32 delta, bool horizontal) const {
|
||||||
}
|
|
||||||
|
|
||||||
this->mMenu = this->item->createMenu();
|
|
||||||
emit this->menuChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemTrayItem::activate() { this->item->activate(); }
|
|
||||||
|
|
||||||
void SystemTrayItem::secondaryActivate() { this->item->secondaryActivate(); }
|
|
||||||
|
|
||||||
void SystemTrayItem::scroll(qint32 delta, bool horizontal) {
|
|
||||||
this->item->scroll(delta, horizontal);
|
this->item->scroll(delta, horizontal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,3 +146,49 @@ qsizetype SystemTray::itemsCount(QQmlListProperty<SystemTrayItem>* property) {
|
||||||
SystemTrayItem* SystemTray::itemAt(QQmlListProperty<SystemTrayItem>* property, qsizetype index) {
|
SystemTrayItem* SystemTray::itemAt(QQmlListProperty<SystemTrayItem>* property, qsizetype index) {
|
||||||
return reinterpret_cast<SystemTray*>(property->object)->mItems.at(index); // NOLINT
|
return reinterpret_cast<SystemTray*>(property->object)->mItems.at(index); // NOLINT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemTrayItem* SystemTrayMenuWatcher::trayItem() const { return this->item; }
|
||||||
|
|
||||||
|
void SystemTrayMenuWatcher::setTrayItem(SystemTrayItem* item) {
|
||||||
|
if (item == this->item) return;
|
||||||
|
|
||||||
|
if (this->item != nullptr) {
|
||||||
|
QObject::disconnect(this->item, nullptr, this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->item = item;
|
||||||
|
|
||||||
|
if (item != nullptr) {
|
||||||
|
QObject::connect(item, &QObject::destroyed, this, &SystemTrayMenuWatcher::onItemDestroyed);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
&item->item->menuPath,
|
||||||
|
&AbstractDBusProperty::changed,
|
||||||
|
this,
|
||||||
|
&SystemTrayMenuWatcher::onMenuPathChanged
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->onMenuPathChanged();
|
||||||
|
emit this->trayItemChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusMenuItem* SystemTrayMenuWatcher::menu() const {
|
||||||
|
if (this->mMenu == nullptr) return nullptr;
|
||||||
|
return &this->mMenu->rootItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemTrayMenuWatcher::onItemDestroyed() {
|
||||||
|
this->item = nullptr;
|
||||||
|
this->onMenuPathChanged();
|
||||||
|
emit this->trayItemChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemTrayMenuWatcher::onMenuPathChanged() {
|
||||||
|
if (this->mMenu != nullptr) {
|
||||||
|
this->mMenu->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mMenu = this->item == nullptr ? nullptr : this->item->item->createMenu();
|
||||||
|
emit this->menuChanged();
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@ Q_ENUM_NS(Enum);
|
||||||
/// A system tray item, roughly conforming to the [kde/freedesktop spec]
|
/// A system tray item, roughly conforming to the [kde/freedesktop spec]
|
||||||
/// (there is no real spec, we just implemented whatever seemed to actually be used).
|
/// (there is no real spec, we just implemented whatever seemed to actually be used).
|
||||||
///
|
///
|
||||||
|
/// The associated context menu can be retrieved using a [SystemTrayMenuWatcher](../systemtraymenuwatcher).
|
||||||
|
///
|
||||||
/// [kde/freedesktop spec]: https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/
|
/// [kde/freedesktop spec]: https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/
|
||||||
class SystemTrayItem: public QObject {
|
class SystemTrayItem: public QObject {
|
||||||
using DBusMenuItem = qs::dbus::dbusmenu::DBusMenuItem;
|
using DBusMenuItem = qs::dbus::dbusmenu::DBusMenuItem;
|
||||||
|
@ -60,8 +62,6 @@ class SystemTrayItem: public QObject {
|
||||||
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged);
|
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged);
|
||||||
Q_PROPERTY(QString tooltipTitle READ tooltipTitle NOTIFY tooltipTitleChanged);
|
Q_PROPERTY(QString tooltipTitle READ tooltipTitle NOTIFY tooltipTitleChanged);
|
||||||
Q_PROPERTY(QString tooltipDescription READ tooltipDescription NOTIFY tooltipDescriptionChanged);
|
Q_PROPERTY(QString tooltipDescription READ tooltipDescription NOTIFY tooltipDescriptionChanged);
|
||||||
// The context menu provided by the application, generally displayed via a right click.
|
|
||||||
Q_PROPERTY(DBusMenuItem* menu READ menu NOTIFY menuChanged);
|
|
||||||
/// If this tray item only offers a menu and activation will do nothing.
|
/// If this tray item only offers a menu and activation will do nothing.
|
||||||
Q_PROPERTY(bool onlyMenu READ onlyMenu NOTIFY onlyMenuChanged);
|
Q_PROPERTY(bool onlyMenu READ onlyMenu NOTIFY onlyMenuChanged);
|
||||||
QML_ELEMENT;
|
QML_ELEMENT;
|
||||||
|
@ -71,13 +71,13 @@ public:
|
||||||
explicit SystemTrayItem(qs::service::sni::StatusNotifierItem* item, QObject* parent = nullptr);
|
explicit SystemTrayItem(qs::service::sni::StatusNotifierItem* item, QObject* parent = nullptr);
|
||||||
|
|
||||||
/// Primary activation action, generally triggered via a left click.
|
/// Primary activation action, generally triggered via a left click.
|
||||||
Q_INVOKABLE void activate();
|
Q_INVOKABLE void activate() const;
|
||||||
|
|
||||||
/// Secondary activation action, generally triggered via a middle click.
|
/// Secondary activation action, generally triggered via a middle click.
|
||||||
Q_INVOKABLE void secondaryActivate();
|
Q_INVOKABLE void secondaryActivate() const;
|
||||||
|
|
||||||
/// Scroll action, such as changing volume on a mixer.
|
/// Scroll action, such as changing volume on a mixer.
|
||||||
Q_INVOKABLE void scroll(qint32 delta, bool horizontal);
|
Q_INVOKABLE void scroll(qint32 delta, bool horizontal) const;
|
||||||
|
|
||||||
[[nodiscard]] QString id() const;
|
[[nodiscard]] QString id() const;
|
||||||
[[nodiscard]] QString title() const;
|
[[nodiscard]] QString title() const;
|
||||||
|
@ -86,9 +86,10 @@ public:
|
||||||
[[nodiscard]] QString icon() const;
|
[[nodiscard]] QString icon() const;
|
||||||
[[nodiscard]] QString tooltipTitle() const;
|
[[nodiscard]] QString tooltipTitle() const;
|
||||||
[[nodiscard]] QString tooltipDescription() const;
|
[[nodiscard]] QString tooltipDescription() const;
|
||||||
[[nodiscard]] DBusMenuItem* menu() const;
|
|
||||||
[[nodiscard]] bool onlyMenu() const;
|
[[nodiscard]] bool onlyMenu() const;
|
||||||
|
|
||||||
|
qs::service::sni::StatusNotifierItem* item = nullptr;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void idChanged();
|
void idChanged();
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
|
@ -97,17 +98,7 @@ signals:
|
||||||
void iconChanged();
|
void iconChanged();
|
||||||
void tooltipTitleChanged();
|
void tooltipTitleChanged();
|
||||||
void tooltipDescriptionChanged();
|
void tooltipDescriptionChanged();
|
||||||
void menuChanged();
|
|
||||||
void onlyMenuChanged();
|
void onlyMenuChanged();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onMenuPathChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
qs::service::sni::StatusNotifierItem* item = nullptr;
|
|
||||||
qs::dbus::dbusmenu::DBusMenu* mMenu = nullptr;
|
|
||||||
|
|
||||||
friend class SystemTray;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///! System tray
|
///! System tray
|
||||||
|
@ -139,3 +130,39 @@ private:
|
||||||
|
|
||||||
QList<SystemTrayItem*> mItems;
|
QList<SystemTrayItem*> mItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///! Accessor for SystemTrayItem menus.
|
||||||
|
/// SystemTrayMenuWatcher provides access to the associated
|
||||||
|
/// [DBusMenuItem](../../quickshell.dbusmenu/dbusmenuitem) for a tray item.
|
||||||
|
class SystemTrayMenuWatcher: public QObject {
|
||||||
|
using DBusMenu = qs::dbus::dbusmenu::DBusMenu;
|
||||||
|
using DBusMenuItem = qs::dbus::dbusmenu::DBusMenuItem;
|
||||||
|
|
||||||
|
Q_OBJECT;
|
||||||
|
/// The tray item to watch.
|
||||||
|
Q_PROPERTY(SystemTrayItem* trayItem READ trayItem WRITE setTrayItem NOTIFY trayItemChanged);
|
||||||
|
/// The menu associated with the tray item. Will be null if `trayItem` is null
|
||||||
|
/// or has no associated menu.
|
||||||
|
Q_PROPERTY(DBusMenuItem* menu READ menu NOTIFY menuChanged);
|
||||||
|
QML_ELEMENT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SystemTrayMenuWatcher(QObject* parent = nullptr): QObject(parent) {}
|
||||||
|
|
||||||
|
[[nodiscard]] SystemTrayItem* trayItem() const;
|
||||||
|
void setTrayItem(SystemTrayItem* item);
|
||||||
|
|
||||||
|
[[nodiscard]] DBusMenuItem* menu() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void menuChanged();
|
||||||
|
void trayItemChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onItemDestroyed();
|
||||||
|
void onMenuPathChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SystemTrayItem* item = nullptr;
|
||||||
|
DBusMenu* mMenu = nullptr;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue