forked from quickshell/quickshell
service/tray: rework tray image providers
This commit is contained in:
parent
aa9f8cd001
commit
7cc1b54587
|
@ -23,6 +23,7 @@ qt_add_library(quickshell-core STATIC
|
||||||
lazyloader.cpp
|
lazyloader.cpp
|
||||||
easingcurve.cpp
|
easingcurve.cpp
|
||||||
iconimageprovider.cpp
|
iconimageprovider.cpp
|
||||||
|
imageprovider.cpp
|
||||||
transformwatcher.cpp
|
transformwatcher.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
|
|
||||||
#include "iconimageprovider.hpp"
|
#include "iconimageprovider.hpp"
|
||||||
|
#include "imageprovider.hpp"
|
||||||
#include "incubator.hpp"
|
#include "incubator.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "qsintercept.hpp"
|
#include "qsintercept.hpp"
|
||||||
|
@ -35,6 +36,8 @@ EngineGeneration::EngineGeneration(QmlScanner scanner)
|
||||||
this->engine->setIncubationController(&this->delayedIncubationController);
|
this->engine->setIncubationController(&this->delayedIncubationController);
|
||||||
|
|
||||||
this->engine->addImageProvider("icon", new IconImageProvider());
|
this->engine->addImageProvider("icon", new IconImageProvider());
|
||||||
|
this->engine->addImageProvider("qsimage", new QsImageProvider());
|
||||||
|
this->engine->addImageProvider("qspixmap", new QsPixmapProvider());
|
||||||
|
|
||||||
QuickshellPlugin::runConstructGeneration(*this);
|
QuickshellPlugin::runConstructGeneration(*this);
|
||||||
}
|
}
|
||||||
|
|
83
src/core/imageprovider.cpp
Normal file
83
src/core/imageprovider.cpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#include "imageprovider.hpp"
|
||||||
|
|
||||||
|
#include <qdebug.h>
|
||||||
|
#include <qimage.h>
|
||||||
|
#include <qlogging.h>
|
||||||
|
#include <qmap.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qpixmap.h>
|
||||||
|
#include <qqmlengine.h>
|
||||||
|
|
||||||
|
static QMap<QString, QsImageHandle*> liveImages;
|
||||||
|
|
||||||
|
QsImageHandle::QsImageHandle(QQmlImageProviderBase::ImageType type, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, type(type) {
|
||||||
|
{
|
||||||
|
auto dbg = QDebug(&this->id);
|
||||||
|
dbg.nospace() << static_cast<void*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
liveImages.insert(this->id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QsImageHandle::~QsImageHandle() { liveImages.remove(this->id); }
|
||||||
|
|
||||||
|
QString QsImageHandle::url() const {
|
||||||
|
QString url = "image://";
|
||||||
|
if (this->type == QQmlImageProviderBase::Image) url += "qsimage";
|
||||||
|
else if (this->type == QQmlImageProviderBase::Pixmap) url += "qspixmap";
|
||||||
|
url += "/" + this->id;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage
|
||||||
|
QsImageHandle::requestImage(const QString& /*unused*/, QSize* /*unused*/, const QSize& /*unused*/) {
|
||||||
|
qWarning() << "Image handle" << this << "does not provide QImages";
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap QsImageHandle::
|
||||||
|
requestPixmap(const QString& /*unused*/, QSize* /*unused*/, const QSize& /*unused*/) {
|
||||||
|
qWarning() << "Image handle" << this << "does not provide QPixmaps";
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseReq(const QString& req, QString& target, QString& param) {
|
||||||
|
auto splitIdx = req.indexOf('/');
|
||||||
|
if (splitIdx != -1) {
|
||||||
|
target = req.sliced(0, splitIdx);
|
||||||
|
param = req.sliced(splitIdx + 1);
|
||||||
|
} else {
|
||||||
|
target = req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage QsImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) {
|
||||||
|
QString target;
|
||||||
|
QString param;
|
||||||
|
parseReq(id, target, param);
|
||||||
|
|
||||||
|
auto* handle = liveImages.value(target);
|
||||||
|
if (handle != nullptr) {
|
||||||
|
return handle->requestImage(param, size, requestedSize);
|
||||||
|
} else {
|
||||||
|
qWarning() << "Requested image from unknown handle" << id;
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap
|
||||||
|
QsPixmapProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
|
||||||
|
QString target;
|
||||||
|
QString param;
|
||||||
|
parseReq(id, target, param);
|
||||||
|
|
||||||
|
auto* handle = liveImages.value(target);
|
||||||
|
if (handle != nullptr) {
|
||||||
|
return handle->requestPixmap(param, size, requestedSize);
|
||||||
|
} else {
|
||||||
|
qWarning() << "Requested image from unknown handle" << id;
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
}
|
39
src/core/imageprovider.hpp
Normal file
39
src/core/imageprovider.hpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qimage.h>
|
||||||
|
#include <qmap.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlengine.h>
|
||||||
|
#include <qquickimageprovider.h>
|
||||||
|
#include <qtclasshelpermacros.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
|
||||||
|
class QsImageProvider: public QQuickImageProvider {
|
||||||
|
public:
|
||||||
|
explicit QsImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) {}
|
||||||
|
QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QsPixmapProvider: public QQuickImageProvider {
|
||||||
|
public:
|
||||||
|
explicit QsPixmapProvider(): QQuickImageProvider(QQuickImageProvider::Pixmap) {}
|
||||||
|
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QsImageHandle: public QObject {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QsImageHandle(QQmlImageProviderBase::ImageType type, QObject* parent = nullptr);
|
||||||
|
~QsImageHandle() override;
|
||||||
|
Q_DISABLE_COPY_MOVE(QsImageHandle);
|
||||||
|
|
||||||
|
[[nodiscard]] QString url() const;
|
||||||
|
|
||||||
|
virtual QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize);
|
||||||
|
virtual QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QQmlImageProviderBase::ImageType type;
|
||||||
|
QString id;
|
||||||
|
};
|
|
@ -27,7 +27,6 @@ qt_add_dbus_interface(DBUS_INTERFACES
|
||||||
|
|
||||||
qt_add_library(quickshell-service-statusnotifier STATIC
|
qt_add_library(quickshell-service-statusnotifier STATIC
|
||||||
qml.cpp
|
qml.cpp
|
||||||
trayimageprovider.cpp
|
|
||||||
|
|
||||||
watcher.cpp
|
watcher.cpp
|
||||||
host.cpp
|
host.cpp
|
||||||
|
@ -36,8 +35,6 @@ qt_add_library(quickshell-service-statusnotifier STATIC
|
||||||
${DBUS_INTERFACES}
|
${DBUS_INTERFACES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(quickshell-service-statusnotifier-init OBJECT init.cpp)
|
|
||||||
|
|
||||||
# dbus headers
|
# dbus headers
|
||||||
target_include_directories(quickshell-service-statusnotifier PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
target_include_directories(quickshell-service-statusnotifier PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
@ -47,9 +44,7 @@ qt_add_qml_module(quickshell-service-statusnotifier
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(quickshell-service-statusnotifier PRIVATE ${QT_DEPS} quickshell-dbus)
|
target_link_libraries(quickshell-service-statusnotifier PRIVATE ${QT_DEPS} quickshell-dbus)
|
||||||
target_link_libraries(quickshell-service-statusnotifier-init PRIVATE ${QT_DEPS})
|
target_link_libraries(quickshell PRIVATE quickshell-service-statusnotifierplugin)
|
||||||
target_link_libraries(quickshell PRIVATE quickshell-service-statusnotifierplugin quickshell-service-statusnotifier-init)
|
|
||||||
|
|
||||||
qs_pch(quickshell-service-statusnotifier)
|
qs_pch(quickshell-service-statusnotifier)
|
||||||
qs_pch(quickshell-service-statusnotifierplugin)
|
qs_pch(quickshell-service-statusnotifierplugin)
|
||||||
qs_pch(quickshell-service-statusnotifier-init)
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "../../core/generation.hpp"
|
|
||||||
#include "../../core/plugin.hpp"
|
|
||||||
#include "trayimageprovider.hpp"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class SniPlugin: public QuickshellPlugin {
|
|
||||||
void constructGeneration(EngineGeneration& generation) override {
|
|
||||||
generation.engine->addImageProvider("service.sni", new qs::service::sni::TrayImageProvider());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QS_REGISTER_PLUGIN(SniPlugin);
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -11,12 +11,15 @@
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qpainter.h>
|
#include <qpainter.h>
|
||||||
#include <qpixmap.h>
|
#include <qpixmap.h>
|
||||||
|
#include <qqmlengine.h>
|
||||||
#include <qrect.h>
|
#include <qrect.h>
|
||||||
#include <qsize.h>
|
#include <qsize.h>
|
||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
|
||||||
#include "../../core/iconimageprovider.hpp"
|
#include "../../core/iconimageprovider.hpp"
|
||||||
|
#include "../../core/imageprovider.hpp"
|
||||||
#include "../../dbus/properties.hpp"
|
#include "../../dbus/properties.hpp"
|
||||||
#include "dbus_item.h"
|
#include "dbus_item.h"
|
||||||
#include "dbus_item_types.hpp"
|
#include "dbus_item_types.hpp"
|
||||||
|
@ -94,7 +97,7 @@ QString StatusNotifierItem::iconId() const {
|
||||||
return IconImageProvider::requestString(name, this->iconThemePath.get());
|
return IconImageProvider::requestString(name, this->iconThemePath.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
return QString("image://service.sni/") + this->watcherId + "/" + QString::number(this->iconIndex);
|
return this->imageHandle.url() + "/" + QString::number(this->iconIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap StatusNotifierItem::createPixmap(const QSize& size) const {
|
QPixmap StatusNotifierItem::createPixmap(const QSize& size) const {
|
||||||
|
@ -230,4 +233,22 @@ void StatusNotifierItem::onGetAllFinished() {
|
||||||
emit this->ready();
|
emit this->ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrayImageHandle::TrayImageHandle(StatusNotifierItem* item)
|
||||||
|
: QsImageHandle(QQmlImageProviderBase::Pixmap, item)
|
||||||
|
, item(item) {}
|
||||||
|
|
||||||
|
QPixmap
|
||||||
|
TrayImageHandle::requestPixmap(const QString& /*unused*/, QSize* size, const QSize& requestedSize) {
|
||||||
|
auto targetSize = requestedSize.isValid() ? requestedSize : QSize(100, 100);
|
||||||
|
if (targetSize.width() == 0 || targetSize.height() == 0) targetSize = QSize(2, 2);
|
||||||
|
|
||||||
|
auto pixmap = this->item->createPixmap(targetSize);
|
||||||
|
if (pixmap.isNull()) {
|
||||||
|
pixmap = IconImageProvider::missingPixmap(targetSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != nullptr) *size = pixmap.size();
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace qs::service::sni
|
} // namespace qs::service::sni
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
|
|
||||||
|
#include "../../core/imageprovider.hpp"
|
||||||
#include "../../dbus/properties.hpp"
|
#include "../../dbus/properties.hpp"
|
||||||
#include "dbus_item.h"
|
#include "dbus_item.h"
|
||||||
#include "dbus_item_types.hpp"
|
#include "dbus_item_types.hpp"
|
||||||
|
@ -17,6 +18,18 @@ Q_DECLARE_LOGGING_CATEGORY(logStatusNotifierItem);
|
||||||
|
|
||||||
namespace qs::service::sni {
|
namespace qs::service::sni {
|
||||||
|
|
||||||
|
class StatusNotifierItem;
|
||||||
|
|
||||||
|
class TrayImageHandle: public QsImageHandle {
|
||||||
|
public:
|
||||||
|
explicit TrayImageHandle(StatusNotifierItem* item);
|
||||||
|
|
||||||
|
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StatusNotifierItem* item;
|
||||||
|
};
|
||||||
|
|
||||||
class StatusNotifierItem: public QObject {
|
class StatusNotifierItem: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
|
@ -62,6 +75,7 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DBusStatusNotifierItem* item = nullptr;
|
DBusStatusNotifierItem* item = nullptr;
|
||||||
|
TrayImageHandle imageHandle {this};
|
||||||
bool mReady = false;
|
bool mReady = false;
|
||||||
|
|
||||||
// bumped to inhibit caching
|
// bumped to inhibit caching
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include "trayimageprovider.hpp"
|
|
||||||
|
|
||||||
#include <qlogging.h>
|
|
||||||
#include <qloggingcategory.h>
|
|
||||||
#include <qpixmap.h>
|
|
||||||
#include <qsize.h>
|
|
||||||
#include <qstring.h>
|
|
||||||
|
|
||||||
#include "../../core/iconimageprovider.hpp"
|
|
||||||
#include "host.hpp"
|
|
||||||
|
|
||||||
namespace qs::service::sni {
|
|
||||||
|
|
||||||
QPixmap
|
|
||||||
TrayImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
|
|
||||||
QPixmap pixmap;
|
|
||||||
|
|
||||||
auto targetSize = requestedSize.isValid() ? requestedSize : QSize(100, 100);
|
|
||||||
if (targetSize.width() == 0 || targetSize.height() == 0) targetSize = QSize(2, 2);
|
|
||||||
|
|
||||||
auto lastSplit = id.lastIndexOf('/');
|
|
||||||
if (lastSplit == -1) {
|
|
||||||
qCWarning(logStatusNotifierHost) << "Invalid image request:" << id;
|
|
||||||
} else {
|
|
||||||
auto path = id.sliced(0, lastSplit);
|
|
||||||
|
|
||||||
auto* item = StatusNotifierHost::instance()->itemByService(path);
|
|
||||||
|
|
||||||
if (item == nullptr) {
|
|
||||||
qCWarning(logStatusNotifierHost) << "Image requested for nonexistant service" << path;
|
|
||||||
} else {
|
|
||||||
pixmap = item->createPixmap(targetSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixmap.isNull()) {
|
|
||||||
pixmap = IconImageProvider::missingPixmap(targetSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != nullptr) *size = pixmap.size();
|
|
||||||
return pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace qs::service::sni
|
|
|
@ -1,16 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <qpixmap.h>
|
|
||||||
#include <qquickimageprovider.h>
|
|
||||||
#include <qtmetamacros.h>
|
|
||||||
|
|
||||||
namespace qs::service::sni {
|
|
||||||
|
|
||||||
class TrayImageProvider: public QQuickImageProvider {
|
|
||||||
public:
|
|
||||||
explicit TrayImageProvider(): QQuickImageProvider(QQuickImageProvider::Pixmap) {}
|
|
||||||
|
|
||||||
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace qs::service::sni
|
|
Loading…
Reference in a new issue