forked from quickshell/quickshell
		
	service/tray: move menu access to SystemTrayMenuWatcher
This commit is contained in:
		
							parent
							
								
									3c0456a3c0
								
							
						
					
					
						commit
						e7cfb5cf37
					
				
					 4 changed files with 94 additions and 40 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue