feat: initial video wallpaper implementation

This commit is contained in:
2026-10-25 02:10:50 +02:00
parent 200a6a5d54
commit 0d0faecb1c
14 changed files with 1280 additions and 88 deletions
+62 -2
View File
@@ -9,6 +9,7 @@
#include <QImage>
#include <QList>
#include <QElapsedTimer>
#include <QRectF>
#include <QSize>
#include <QString>
@@ -16,12 +17,18 @@
#include <QVariantMap>
#include <QtQml/qqml.h>
#include <qtmetamacros.h>
#include <atomic>
#include <qwayland-wlr-layer-shell-unstable-v1.h>
#include <wayland-client-protocol.h>
#include "wallpapersurface.hpp"
struct mpv_handle;
struct mpv_render_context;
class QProcess;
namespace ZShell::internal {
class WallpaperSurface;
@@ -57,6 +64,29 @@ class WallpaperService : public QObject {
private:
friend class WallpaperSurface;
static bool isVideoPath(const QString& path);
static bool isHardwareCodec(const QString& codec);
[[nodiscard]] QString codecName(const QString& path) const;
[[nodiscard]] QString cacheDir() const;
[[nodiscard]] QString transcodeTarget(const QString& path) const;
[[nodiscard]] bool needsTranscode(const QString& path) const;
void transcodeVideo(const QString& src, const QString& dst);
void applyPath(const QString& path);
void startVideo(const QString& path);
void stopVideo();
void teardownMpv();
void initMpvRender();
void renderMpvToSurface(const QSize& size);
void pumpMpvEvents();
static void* getMpvProcAddress(void* ctx, const char* name);
static void mpvUpdate(void* ctx);
void bindGlobals();
static void registryGlobal(
void* data,
@@ -70,7 +100,16 @@ class WallpaperService : public QObject {
[[nodiscard]] bool setupGl();
[[nodiscard]] uint32_t createProgram();
void uploadTexture(uint32_t& texture, const QImage& image);
void uploadImage();
void createBlackTexture(uint32_t& texture);
void drawTexture(
uint32_t texture,
const QRectF& rect,
float sizeW,
float sizeH,
float alpha);
bool decode(const QString& path);
@@ -95,7 +134,8 @@ class WallpaperService : public QObject {
[[nodiscard]] QRectF sourceRect(
const QVariantMap& crops,
const QString& screen,
const QSize& size) const;
const QSize& size,
const QSize& image) const;
void start();
@@ -108,6 +148,18 @@ class WallpaperService : public QObject {
QImage m_image;
bool m_isVideo = false;
bool m_videoReload = false;
bool m_previousVideo = false;
mpv_handle* m_mpv = nullptr;
mpv_render_context* m_mpvRender = nullptr;
uint32_t m_blackTex = 0;
std::atomic<bool> m_mpvFrameReady{false};
std::atomic<bool> m_videoReady{false};
std::atomic<bool> m_videoLoaded{false};
QProcess* m_transcode = nullptr;
QSize m_sourceSize;
QSize m_decodeSize;
@@ -125,12 +177,20 @@ class WallpaperService : public QObject {
uint32_t m_program = 0;
int m_sizeUniform = -1;
int m_cropUniform = -1;
int m_alphaUniform = -1;
QImage m_previousImage;
QVariantMap m_previousCrops;
uint32_t m_previousTexture = 0;
bool m_fading = false;
bool m_fadeClockStarted = false;
bool m_firstFadeDone = false;
QElapsedTimer m_fadeTimer;
QList<WallpaperSurface*> m_surfaces;
std::thread m_thread;
mutable std::recursive_mutex m_mutex;
std::vector<WallpaperSurface*> m_pending;
wl_event_queue* m_queue = nullptr;
int m_wake[2] = {-1, -1};