forked from quickshell/quickshell
service/tray!: redesign menus / dbusmenu and add native menu support
Reworks dbusmenu menus to be displayable with a system context menu. Breaks the entire DBusMenu api.
This commit is contained in:
parent
c31bbea837
commit
ec362637b8
18 changed files with 898 additions and 191 deletions
|
@ -8,12 +8,17 @@
|
|||
#include <qfileinfo.h>
|
||||
#include <qfilesystemwatcher.h>
|
||||
#include <qhash.h>
|
||||
#include <qicon.h>
|
||||
#include <qiconengine.h>
|
||||
#include <qlogging.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qqmlcontext.h>
|
||||
#include <qqmlengine.h>
|
||||
#include <qqmlincubator.h>
|
||||
#include <qquickimageprovider.h>
|
||||
#include <qsize.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "iconimageprovider.hpp"
|
||||
|
@ -308,6 +313,90 @@ EngineGeneration* EngineGeneration::currentGeneration() {
|
|||
} else return nullptr;
|
||||
}
|
||||
|
||||
// QMenu re-calls pixmap() every time the mouse moves so its important to cache it.
|
||||
class PixmapCacheIconEngine: public QIconEngine {
|
||||
void paint(
|
||||
QPainter* /*unused*/,
|
||||
const QRect& /*unused*/,
|
||||
QIcon::Mode /*unused*/,
|
||||
QIcon::State /*unused*/
|
||||
) override {
|
||||
qFatal(
|
||||
) << "Unexpected icon paint request bypassed pixmap method. Please report this as a bug.";
|
||||
}
|
||||
|
||||
QPixmap pixmap(const QSize& size, QIcon::Mode /*unused*/, QIcon::State /*unused*/) override {
|
||||
if (this->lastPixmap.isNull() || size != this->lastSize) {
|
||||
this->lastPixmap = this->createPixmap(size);
|
||||
this->lastSize = size;
|
||||
}
|
||||
|
||||
return this->lastPixmap;
|
||||
}
|
||||
|
||||
virtual QPixmap createPixmap(const QSize& size) = 0;
|
||||
|
||||
private:
|
||||
QSize lastSize;
|
||||
QPixmap lastPixmap;
|
||||
};
|
||||
|
||||
class ImageProviderIconEngine: public PixmapCacheIconEngine {
|
||||
public:
|
||||
explicit ImageProviderIconEngine(QQuickImageProvider* provider, QString id)
|
||||
: provider(provider)
|
||||
, id(std::move(id)) {}
|
||||
|
||||
QPixmap createPixmap(const QSize& size) override {
|
||||
if (this->provider->imageType() == QQmlImageProviderBase::Pixmap) {
|
||||
return this->provider->requestPixmap(this->id, nullptr, size);
|
||||
} else if (this->provider->imageType() == QQmlImageProviderBase::Image) {
|
||||
auto image = this->provider->requestImage(this->id, nullptr, size);
|
||||
return QPixmap::fromImage(image);
|
||||
} else {
|
||||
qFatal() << "Unexpected ImageProviderIconEngine image type" << this->provider->imageType();
|
||||
return QPixmap(); // never reached, satisfies lint
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] QIconEngine* clone() const override {
|
||||
return new ImageProviderIconEngine(this->provider, this->id);
|
||||
}
|
||||
|
||||
private:
|
||||
QQuickImageProvider* provider;
|
||||
QString id;
|
||||
};
|
||||
|
||||
QIcon EngineGeneration::iconByUrl(const QUrl& url) const {
|
||||
if (url.isEmpty()) return QIcon();
|
||||
|
||||
auto scheme = url.scheme();
|
||||
if (scheme == "image") {
|
||||
auto providerName = url.authority();
|
||||
auto path = url.path();
|
||||
if (!path.isEmpty()) path = path.sliced(1);
|
||||
|
||||
auto* provider = qobject_cast<QQuickImageProvider*>(this->engine->imageProvider(providerName));
|
||||
|
||||
if (provider == nullptr) {
|
||||
qWarning() << "iconByUrl failed: no provider found for" << url;
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
if (provider->imageType() == QQmlImageProviderBase::Pixmap
|
||||
|| provider->imageType() == QQmlImageProviderBase::Image)
|
||||
{
|
||||
return QIcon(new ImageProviderIconEngine(provider, path));
|
||||
}
|
||||
|
||||
} else {
|
||||
qWarning() << "iconByUrl failed: unsupported scheme" << scheme << "in path" << url;
|
||||
}
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
EngineGeneration* EngineGeneration::findEngineGeneration(QQmlEngine* engine) {
|
||||
return g_generations.value(engine);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue