all: optimize build

This commit is contained in:
outfoxxed 2024-11-05 04:15:17 -08:00
parent 1168879d6d
commit 7ffce72b31
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
51 changed files with 1526 additions and 1277 deletions

View file

@ -1,5 +1,3 @@
find_package(CLI11 CONFIG REQUIRED)
qt_add_library(quickshell-core STATIC
plugin.cpp
shell.cpp
@ -37,10 +35,9 @@ qt_add_library(quickshell-core STATIC
paths.cpp
instanceinfo.cpp
common.cpp
iconprovider.cpp
)
target_link_libraries(quickshell-core PRIVATE quickshell-build)
qt_add_qml_module(quickshell-core
URI Quickshell
VERSION 0.1
@ -51,10 +48,9 @@ qt_add_qml_module(quickshell-core
install_qml_module(quickshell-core)
target_link_libraries(quickshell-core PRIVATE ${QT_DEPS} CLI11::CLI11)
target_link_libraries(quickshell-core PRIVATE Qt::Quick Qt::Widgets)
qs_pch(quickshell-core)
qs_pch(quickshell-coreplugin)
qs_module_pch(quickshell-core SET large)
target_link_libraries(quickshell PRIVATE quickshell-coreplugin)

View file

@ -4,6 +4,7 @@
#include <qobject.h>
#include <qtimer.h>
#include <qtmetamacros.h>
#include <qtypes.h>
#include "util.hpp"

View file

@ -8,17 +8,12 @@
#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"
@ -331,90 +326,6 @@ 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);
}

View file

@ -4,13 +4,11 @@
#include <qdir.h>
#include <qfilesystemwatcher.h>
#include <qhash.h>
#include <qicon.h>
#include <qobject.h>
#include <qpair.h>
#include <qqmlengine.h>
#include <qqmlincubator.h>
#include <qtclasshelpermacros.h>
#include <qurl.h>
#include "incubator.hpp"
#include "qsintercept.hpp"
@ -54,8 +52,6 @@ public:
// otherwise null.
static EngineGeneration* currentGeneration();
[[nodiscard]] QIcon iconByUrl(const QUrl& url) const;
RootWrapper* wrapper = nullptr;
QDir rootPath;
QmlScanner scanner;

105
src/core/iconprovider.cpp Normal file
View file

@ -0,0 +1,105 @@
#include "iconprovider.hpp"
#include <utility>
#include <qicon.h>
#include <qiconengine.h>
#include <qlogging.h>
#include <qobject.h>
#include <qpixmap.h>
#include <qqmlengine.h>
#include <qquickimageprovider.h>
#include <qrect.h>
#include <qsize.h>
#include <qstring.h>
#include "generation.hpp"
// 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 getEngineImageAsIcon(QQmlEngine* engine, const QUrl& url) {
if (!engine || 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*>(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();
}
QIcon getCurrentEngineImageAsIcon(const QUrl& url) {
auto* generation = EngineGeneration::currentGeneration();
if (!generation) return QIcon();
return getEngineImageAsIcon(generation->engine, url);
}

View file

@ -0,0 +1,8 @@
#pragma once
#include <qicon.h>
#include <qqmlengine.h>
#include <qurl.h>
QIcon getEngineImageAsIcon(QQmlEngine* engine, const QUrl& url);
QIcon getCurrentEngineImageAsIcon(const QUrl& url);

View file

@ -19,7 +19,8 @@
#include "../window/proxywindow.hpp"
#include "../window/windowinterface.hpp"
#include "generation.hpp"
#include "iconprovider.hpp"
#include "platformmenu_p.hpp"
#include "popupanchor.hpp"
#include "qsmenu.hpp"
@ -174,8 +175,7 @@ void PlatformMenuEntry::relayout() {
auto icon = this->menu->icon();
if (!icon.isEmpty()) {
auto* generation = EngineGeneration::currentGeneration();
this->qmenu->setIcon(generation->iconByUrl(this->menu->icon()));
this->qmenu->setIcon(getCurrentEngineImageAsIcon(icon));
}
auto children = this->menu->children();
@ -216,8 +216,7 @@ void PlatformMenuEntry::relayout() {
auto icon = this->menu->icon();
if (!icon.isEmpty()) {
auto* generation = EngineGeneration::currentGeneration();
this->qaction->setIcon(generation->iconByUrl(this->menu->icon()));
this->qaction->setIcon(getCurrentEngineImageAsIcon(icon));
}
this->qaction->setEnabled(this->menu->enabled());
@ -272,8 +271,7 @@ void PlatformMenuEntry::onIconChanged() {
QIcon icon;
if (!iconName.isEmpty()) {
auto* generation = EngineGeneration::currentGeneration();
icon = generation->iconByUrl(iconName);
icon = getCurrentEngineImageAsIcon(iconName);
}
if (this->qmenu != nullptr) {

View file

@ -5,9 +5,7 @@
#include <qaction.h>
#include <qactiongroup.h>
#include <qcontainerfwd.h>
#include <qmenu.h>
#include <qobject.h>
#include <qpoint.h>
#include <qqmlintegration.h>
#include <qqmllist.h>
#include <qtclasshelpermacros.h>
@ -18,17 +16,7 @@
namespace qs::menu::platform {
class PlatformMenuQMenu: public QMenu {
public:
explicit PlatformMenuQMenu() = default;
~PlatformMenuQMenu() override;
Q_DISABLE_COPY_MOVE(PlatformMenuQMenu);
void setVisible(bool visible) override;
PlatformMenuQMenu* containingMenu = nullptr;
QPoint targetPosition;
};
class PlatformMenuQMenu;
class PlatformMenuEntry: public QObject {
Q_OBJECT;

View file

@ -0,0 +1,19 @@
#pragma once
#include <qmenu.h>
#include <qpoint.h>
namespace qs::menu::platform {
class PlatformMenuQMenu: public QMenu {
public:
explicit PlatformMenuQMenu() = default;
~PlatformMenuQMenu() override;
Q_DISABLE_COPY_MOVE(PlatformMenuQMenu);
void setVisible(bool visible) override;
PlatformMenuQMenu* containingMenu = nullptr;
QPoint targetPosition;
};
} // namespace qs::menu::platform

View file

@ -2,7 +2,6 @@
#include <optional>
#include <QtQmlIntegration/qqmlintegration.h>
#include <qflags.h>
#include <qnamespace.h>
#include <qobject.h>

View file

@ -1,6 +1,6 @@
function (qs_test name)
add_executable(${name} ${ARGN})
target_link_libraries(${name} PRIVATE ${QT_DEPS} Qt6::Test quickshell-core quickshell-window)
target_link_libraries(${name} PRIVATE Qt::Quick Qt::Test quickshell-core quickshell-window)
add_test(NAME ${name} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND $<TARGET_FILE:${name}>)
endfunction()