Skip to content

Commit 7cc1b54

Browse files
committed
service/tray: rework tray image providers
1 parent aa9f8cd commit 7cc1b54

File tree

10 files changed

+163
-82
lines changed

10 files changed

+163
-82
lines changed

src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ qt_add_library(quickshell-core STATIC
2323
lazyloader.cpp
2424
easingcurve.cpp
2525
iconimageprovider.cpp
26+
imageprovider.cpp
2627
transformwatcher.cpp
2728
)
2829

src/core/generation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <qtmetamacros.h>
1717

1818
#include "iconimageprovider.hpp"
19+
#include "imageprovider.hpp"
1920
#include "incubator.hpp"
2021
#include "plugin.hpp"
2122
#include "qsintercept.hpp"
@@ -35,6 +36,8 @@ EngineGeneration::EngineGeneration(QmlScanner scanner)
3536
this->engine->setIncubationController(&this->delayedIncubationController);
3637

3738
this->engine->addImageProvider("icon", new IconImageProvider());
39+
this->engine->addImageProvider("qsimage", new QsImageProvider());
40+
this->engine->addImageProvider("qspixmap", new QsPixmapProvider());
3841

3942
QuickshellPlugin::runConstructGeneration(*this);
4043
}

src/core/imageprovider.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "imageprovider.hpp"
2+
3+
#include <qdebug.h>
4+
#include <qimage.h>
5+
#include <qlogging.h>
6+
#include <qmap.h>
7+
#include <qobject.h>
8+
#include <qpixmap.h>
9+
#include <qqmlengine.h>
10+
11+
static QMap<QString, QsImageHandle*> liveImages;
12+
13+
QsImageHandle::QsImageHandle(QQmlImageProviderBase::ImageType type, QObject* parent)
14+
: QObject(parent)
15+
, type(type) {
16+
{
17+
auto dbg = QDebug(&this->id);
18+
dbg.nospace() << static_cast<void*>(this);
19+
}
20+
21+
liveImages.insert(this->id, this);
22+
}
23+
24+
QsImageHandle::~QsImageHandle() { liveImages.remove(this->id); }
25+
26+
QString QsImageHandle::url() const {
27+
QString url = "image://";
28+
if (this->type == QQmlImageProviderBase::Image) url += "qsimage";
29+
else if (this->type == QQmlImageProviderBase::Pixmap) url += "qspixmap";
30+
url += "/" + this->id;
31+
return url;
32+
}
33+
34+
QImage
35+
QsImageHandle::requestImage(const QString& /*unused*/, QSize* /*unused*/, const QSize& /*unused*/) {
36+
qWarning() << "Image handle" << this << "does not provide QImages";
37+
return QImage();
38+
}
39+
40+
QPixmap QsImageHandle::
41+
requestPixmap(const QString& /*unused*/, QSize* /*unused*/, const QSize& /*unused*/) {
42+
qWarning() << "Image handle" << this << "does not provide QPixmaps";
43+
return QPixmap();
44+
}
45+
46+
void parseReq(const QString& req, QString& target, QString& param) {
47+
auto splitIdx = req.indexOf('/');
48+
if (splitIdx != -1) {
49+
target = req.sliced(0, splitIdx);
50+
param = req.sliced(splitIdx + 1);
51+
} else {
52+
target = req;
53+
}
54+
}
55+
56+
QImage QsImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) {
57+
QString target;
58+
QString param;
59+
parseReq(id, target, param);
60+
61+
auto* handle = liveImages.value(target);
62+
if (handle != nullptr) {
63+
return handle->requestImage(param, size, requestedSize);
64+
} else {
65+
qWarning() << "Requested image from unknown handle" << id;
66+
return QImage();
67+
}
68+
}
69+
70+
QPixmap
71+
QsPixmapProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
72+
QString target;
73+
QString param;
74+
parseReq(id, target, param);
75+
76+
auto* handle = liveImages.value(target);
77+
if (handle != nullptr) {
78+
return handle->requestPixmap(param, size, requestedSize);
79+
} else {
80+
qWarning() << "Requested image from unknown handle" << id;
81+
return QPixmap();
82+
}
83+
}

src/core/imageprovider.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include <qimage.h>
4+
#include <qmap.h>
5+
#include <qobject.h>
6+
#include <qqmlengine.h>
7+
#include <qquickimageprovider.h>
8+
#include <qtclasshelpermacros.h>
9+
#include <qtmetamacros.h>
10+
11+
class QsImageProvider: public QQuickImageProvider {
12+
public:
13+
explicit QsImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) {}
14+
QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override;
15+
};
16+
17+
class QsPixmapProvider: public QQuickImageProvider {
18+
public:
19+
explicit QsPixmapProvider(): QQuickImageProvider(QQuickImageProvider::Pixmap) {}
20+
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
21+
};
22+
23+
class QsImageHandle: public QObject {
24+
Q_OBJECT;
25+
26+
public:
27+
explicit QsImageHandle(QQmlImageProviderBase::ImageType type, QObject* parent = nullptr);
28+
~QsImageHandle() override;
29+
Q_DISABLE_COPY_MOVE(QsImageHandle);
30+
31+
[[nodiscard]] QString url() const;
32+
33+
virtual QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize);
34+
virtual QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize);
35+
36+
private:
37+
QQmlImageProviderBase::ImageType type;
38+
QString id;
39+
};

src/services/status_notifier/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ qt_add_dbus_interface(DBUS_INTERFACES
2727

2828
qt_add_library(quickshell-service-statusnotifier STATIC
2929
qml.cpp
30-
trayimageprovider.cpp
3130

3231
watcher.cpp
3332
host.cpp
@@ -36,8 +35,6 @@ qt_add_library(quickshell-service-statusnotifier STATIC
3635
${DBUS_INTERFACES}
3736
)
3837

39-
add_library(quickshell-service-statusnotifier-init OBJECT init.cpp)
40-
4138
# dbus headers
4239
target_include_directories(quickshell-service-statusnotifier PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
4340

@@ -47,9 +44,7 @@ qt_add_qml_module(quickshell-service-statusnotifier
4744
)
4845

4946
target_link_libraries(quickshell-service-statusnotifier PRIVATE ${QT_DEPS} quickshell-dbus)
50-
target_link_libraries(quickshell-service-statusnotifier-init PRIVATE ${QT_DEPS})
51-
target_link_libraries(quickshell PRIVATE quickshell-service-statusnotifierplugin quickshell-service-statusnotifier-init)
47+
target_link_libraries(quickshell PRIVATE quickshell-service-statusnotifierplugin)
5248

5349
qs_pch(quickshell-service-statusnotifier)
5450
qs_pch(quickshell-service-statusnotifierplugin)
55-
qs_pch(quickshell-service-statusnotifier-init)

src/services/status_notifier/init.cpp

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/services/status_notifier/item.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
#include <qobject.h>
1212
#include <qpainter.h>
1313
#include <qpixmap.h>
14+
#include <qqmlengine.h>
1415
#include <qrect.h>
1516
#include <qsize.h>
1617
#include <qstring.h>
1718
#include <qtmetamacros.h>
19+
#include <qtypes.h>
1820

1921
#include "../../core/iconimageprovider.hpp"
22+
#include "../../core/imageprovider.hpp"
2023
#include "../../dbus/properties.hpp"
2124
#include "dbus_item.h"
2225
#include "dbus_item_types.hpp"
@@ -94,7 +97,7 @@ QString StatusNotifierItem::iconId() const {
9497
return IconImageProvider::requestString(name, this->iconThemePath.get());
9598
}
9699

97-
return QString("image://service.sni/") + this->watcherId + "/" + QString::number(this->iconIndex);
100+
return this->imageHandle.url() + "/" + QString::number(this->iconIndex);
98101
}
99102

100103
QPixmap StatusNotifierItem::createPixmap(const QSize& size) const {
@@ -230,4 +233,22 @@ void StatusNotifierItem::onGetAllFinished() {
230233
emit this->ready();
231234
}
232235

236+
TrayImageHandle::TrayImageHandle(StatusNotifierItem* item)
237+
: QsImageHandle(QQmlImageProviderBase::Pixmap, item)
238+
, item(item) {}
239+
240+
QPixmap
241+
TrayImageHandle::requestPixmap(const QString& /*unused*/, QSize* size, const QSize& requestedSize) {
242+
auto targetSize = requestedSize.isValid() ? requestedSize : QSize(100, 100);
243+
if (targetSize.width() == 0 || targetSize.height() == 0) targetSize = QSize(2, 2);
244+
245+
auto pixmap = this->item->createPixmap(targetSize);
246+
if (pixmap.isNull()) {
247+
pixmap = IconImageProvider::missingPixmap(targetSize);
248+
}
249+
250+
if (size != nullptr) *size = pixmap.size();
251+
return pixmap;
252+
}
253+
233254
} // namespace qs::service::sni

src/services/status_notifier/item.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <qtmetamacros.h>
1010
#include <qtypes.h>
1111

12+
#include "../../core/imageprovider.hpp"
1213
#include "../../dbus/properties.hpp"
1314
#include "dbus_item.h"
1415
#include "dbus_item_types.hpp"
@@ -17,6 +18,18 @@ Q_DECLARE_LOGGING_CATEGORY(logStatusNotifierItem);
1718

1819
namespace qs::service::sni {
1920

21+
class StatusNotifierItem;
22+
23+
class TrayImageHandle: public QsImageHandle {
24+
public:
25+
explicit TrayImageHandle(StatusNotifierItem* item);
26+
27+
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
28+
29+
public:
30+
StatusNotifierItem* item;
31+
};
32+
2033
class StatusNotifierItem: public QObject {
2134
Q_OBJECT;
2235

@@ -62,6 +75,7 @@ private slots:
6275

6376
private:
6477
DBusStatusNotifierItem* item = nullptr;
78+
TrayImageHandle imageHandle {this};
6579
bool mReady = false;
6680

6781
// bumped to inhibit caching

src/services/status_notifier/trayimageprovider.cpp

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/services/status_notifier/trayimageprovider.hpp

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)