From f2bb03c93b3b41ebb496012ebdc6c0206f6a3a78 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Mon, 6 Sep 2021 19:18:56 +0200 Subject: [PATCH] Add basic kde wallpaper support via Websockets This means: Set ScreenPlay as a Wallpaper ( see ScreenPlayWallpaper/kde/ScreenPlay) and start a video wallpaper. Nothing else works yet. --- Docs/DeveloperSetup.md | 4 +- ScreenPlay/src/createimportvideo.cpp | 10 +- ScreenPlay/src/screenplaymanager.cpp | 38 +++++++- ScreenPlay/src/screenplaymanager.h | 1 + ScreenPlay/src/screenplaywallpaper.cpp | 5 +- ScreenPlay/src/screenplaywallpaper.h | 11 ++- ScreenPlayWallpaper/kde/ScreenPlay/README.md | 5 + .../kde/ScreenPlay/contents/ui/main.qml | 93 +++++++------------ 8 files changed, 97 insertions(+), 70 deletions(-) diff --git a/Docs/DeveloperSetup.md b/Docs/DeveloperSetup.md index 45e2a1df..ea79e49a 100644 --- a/Docs/DeveloperSetup.md +++ b/Docs/DeveloperSetup.md @@ -32,7 +32,7 @@ py setup.py Append this: ``` bash -CMAKE_TOOLCHAIN_FILE:STRING=%{CurrentProject:Path}/../ScreenPlay-vcpkg/vcpkg/scripts/buildsystems/vcpkg.cmake +CMAKE_TOOLCHAIN_FILE:STRING=%{CurrentProject:Path}/../ScreenPlay-vcpkg/scripts/buildsystems/vcpkg.cmake # Only _one_ of these lines that match your OS: VCPKG_TARGET_TRIPLET:STRING=x64-windows VCPKG_TARGET_TRIPLET:STRING=x64-linux @@ -65,7 +65,7 @@ VCPKG_TARGET_TRIPLET:STRING=x64-osx 1. Install dependencies for your distro: ``` bash # Debian/Ubuntu -sudo apt install build-essential libgl1-mesa-dev lld ninja-build cmake +sudo apt install build-essential libgl1-mesa-dev lld ninja-build cmake git curl pkg-config ffmpeg qml-module-qt-websockets qtwebengine5-* # Fedora/RHEL/CentOS (yum) sudo yum groupinstall "C Development Tools and Libraries" diff --git a/ScreenPlay/src/createimportvideo.cpp b/ScreenPlay/src/createimportvideo.cpp index eaa3d85f..d1befbdf 100644 --- a/ScreenPlay/src/createimportvideo.cpp +++ b/ScreenPlay/src/createimportvideo.cpp @@ -38,6 +38,12 @@ CreateImportVideo::CreateImportVideo( m_videoPath = videoPath; m_exportPath = exportPath; m_codec = codec; + +#ifdef Q_OS_LINUX + // Use system ffmpeg + m_ffprobeExecutable = "ffprobe"; + m_ffmpegExecutable = "ffmpeg"; +#else m_ffprobeExecutable = QApplication::applicationDirPath() + "/ffprobe" + ScreenPlayUtil::executableBinEnding(); m_ffmpegExecutable = QApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding(); @@ -48,6 +54,7 @@ CreateImportVideo::CreateImportVideo( if (!QFileInfo::exists(m_ffmpegExecutable)) { qFatal("FFMPEG executable not found!"); } +#endif } /*! @@ -111,10 +118,9 @@ bool CreateImportVideo::createWallpaperInfo() } if (obj->empty()) { - qWarning() << "Error! File could not be parsed."; + qCritical() << "Error! File could not be parsed."; emit processOutput("Error! File could not be parsed."); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError); - return false; } diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index 7110c713..a58f3f4c 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -87,6 +87,18 @@ void ScreenPlayManager::init( QObject::connect(m_websocketServer.get(), &QWebSocketServer::newConnection, this, [this]() { qInfo() << "New Websocket Connection"; auto* socket = m_websocketServer->nextPendingConnection(); + QObject::connect(socket, &QWebSocket::textMessageReceived, this, [this](const QString &message) { + qInfo() << "Message:" << message; + }); + QObject::connect(socket, &QWebSocket::disconnected, this, [this,socket]() { + m_connections.removeOne(socket); + qInfo() << "Disconnected connection count: " << m_connections.count(); + }); + + + m_connections.push_back(socket); + socket->sendTextMessage("asdasd"); + socket->flush(); }); } @@ -137,6 +149,22 @@ bool ScreenPlayManager::createWallpaper( const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile(); const QString appID = ScreenPlayUtil::generateRandomString(); + if(m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE){ + if(m_connections.empty()) + return false; + + QJsonObject msg; + msg.insert("command", "replace"); + msg.insert("absolutePath", path); + msg.insert("type", static_cast(type)); + msg.insert("fillMode", static_cast(fillMode)); + msg.insert("volume", volume); + msg.insert("file", file); + + m_connections.first()->sendTextMessage(QJsonDocument(msg).toJson()); + m_connections.first()->flush(); + } + // Only support remove wallpaper that spans over 1 monitor if (monitorIndex.length() == 1) { int i = 0; @@ -172,14 +200,16 @@ bool ScreenPlayManager::createWallpaper( fillMode, type, properties, - m_settings->checkWallpaperVisible()); + m_settings); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestSave, this, &ScreenPlayManager::requestSaveProfiles); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestClose, this, &ScreenPlayManager::removeWallpaper); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::error, this, &ScreenPlayManager::displayErrorPopup); - if (!wallpaper->start()) { - return false; - } + if(m_settings->desktopEnvironment() != Settings::DesktopEnvironment::KDE){ + if (!wallpaper->start()) { + return false; + } + } m_screenPlayWallpapers.append(wallpaper); m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex); increaseActiveWallpaperCounter(); diff --git a/ScreenPlay/src/screenplaymanager.h b/ScreenPlay/src/screenplaymanager.h index 6e76e86b..54655562 100644 --- a/ScreenPlay/src/screenplaymanager.h +++ b/ScreenPlay/src/screenplaymanager.h @@ -182,6 +182,7 @@ private: std::shared_ptr m_settings; std::unique_ptr m_server; std::unique_ptr m_websocketServer; + QVector m_connections; QVector> m_screenPlayWallpapers; QVector> m_screenPlayWidgets; diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index 384e6064..001dc7fb 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -25,7 +25,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, const FillMode::FillMode fillMode, const InstalledType::InstalledType type, const QJsonObject& properties, - const bool checkWallpaperVisible, + const std::shared_ptr& settings, QObject* parent) : QObject(parent) , m_globalVariables { globalVariables } @@ -38,6 +38,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, , m_file { file } , m_volume { volume } , m_playbackRate { playbackRate } + , m_settings { settings } { QJsonObject projectSettingsListModelProperties; @@ -82,7 +83,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, QString::number(static_cast(volume)), QVariant::fromValue(fillMode).toString(), QVariant::fromValue(type).toString(), - QString::number(checkWallpaperVisible), + QString::number(m_settings->checkWallpaperVisible()), // Fixes issue 84 media key overlay " --disable-features=HardwareMediaKeyHandling" }; diff --git a/ScreenPlay/src/screenplaywallpaper.h b/ScreenPlay/src/screenplaywallpaper.h index 4abfecb5..654db2c9 100644 --- a/ScreenPlay/src/screenplaywallpaper.h +++ b/ScreenPlay/src/screenplaywallpaper.h @@ -45,6 +45,7 @@ #include "projectsettingslistmodel.h" #include "sdkconnection.h" #include "util.h" +#include "settings.h" namespace ScreenPlay { @@ -76,12 +77,15 @@ public: const QString& absolutePath, const QString& previewImage, const QString& file, - const float volume, const float playbackRate, + const float volume, + const float playbackRate, const FillMode::FillMode fillMode, - const InstalledType::InstalledType type, const QJsonObject& properties, - const bool checkWallpaperVisible, + const InstalledType::InstalledType type, + const QJsonObject& properties, + const std::shared_ptr& settings, QObject* parent = nullptr); + bool start(); void replace( @@ -227,6 +231,7 @@ public slots: private: const std::shared_ptr m_globalVariables; std::unique_ptr m_connection; + const std::shared_ptr m_settings; ProjectSettingsListModel m_projectSettingsListModel; QVector m_screenNumber; diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/README.md b/ScreenPlayWallpaper/kde/ScreenPlay/README.md index 67f337e7..c62e5229 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/README.md +++ b/ScreenPlayWallpaper/kde/ScreenPlay/README.md @@ -6,6 +6,8 @@ Will not work because KDE uses the kpluginindex.json (that is actually a bz2 fil #### Installation ``` +sudo apt install qml-module-qt-websockets qtwebengine5-* + plasmapkg2 --install ScreenPlay ``` @@ -21,3 +23,6 @@ Because Wallpaper and Widgets are already a different application we can extend 1. Open Desktop Settings - Select Wallpaper type ScreenPlay +``` +plasmapkg2 --upgrade ScreenPlay ; kquitapp5 plasmashell; kstart5 plasmashell +``` \ No newline at end of file diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml index 60285a0a..f5f07dbc 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml @@ -1,11 +1,13 @@ import QtQuick 2.11 +import QtQuick.Controls 2.0 import QtGraphicalEffects 1.0 -import QtQuick.Window 2.0 +import QtQuick.Window 2.15 import Qt.WebSockets 1.15 import QtWebEngine 1.8 Rectangle { id: root + color: "orange" property string fullContentPath property real volume: 1 @@ -15,28 +17,25 @@ Rectangle { function getSetVideoCommand() { // TODO 30: // Currently wont work. Commit anyways til QtCreator and Qt work with js template literals - var src = ""; - src += "var videoPlayer = document.getElementById('videoPlayer');"; - src += "var videoSource = document.getElementById('videoSource');"; - src += "videoSource.src = '" + root.fullContentPath + "';"; - src += "videoPlayer.load();"; - src += "videoPlayer.volume = " + root.volume + ";"; - src += "videoPlayer.setAttribute('style', 'object-fit :" + root.fillMode + ";');"; - src += "videoPlayer.play();"; - print(src); - return src; + var src = "" + src += "var videoPlayer = document.getElementById('videoPlayer');" + src += "var videoSource = document.getElementById('videoSource');" + src += "videoSource.src = '" + root.fullContentPath + "';" + src += "videoPlayer.load();" + src += "videoPlayer.volume = " + root.volume + ";" + src += "videoPlayer.setAttribute('style', 'object-fit :" + root.fillMode + ";');" + src += "videoPlayer.play();" + return src } - - color: "#333333" Component.onCompleted: { - WebEngine.settings.localContentCanAccessFileUrls = true; - WebEngine.settings.localContentCanAccessRemoteUrls = true; - WebEngine.settings.allowRunningInsecureContent = true; - WebEngine.settings.accelerated2dCanvasEnabled = true; - WebEngine.settings.javascriptCanOpenWindows = false; - WebEngine.settings.showScrollBars = false; - WebEngine.settings.playbackRequiresUserGesture = false; - WebEngine.settings.focusOnNavigationEnabled = true; + WebEngine.settings.localContentCanAccessFileUrls = true + WebEngine.settings.localContentCanAccessRemoteUrls = true + WebEngine.settings.allowRunningInsecureContent = true + WebEngine.settings.accelerated2dCanvasEnabled = true + WebEngine.settings.javascriptCanOpenWindows = false + WebEngine.settings.showScrollBars = false + WebEngine.settings.playbackRequiresUserGesture = false + WebEngine.settings.focusOnNavigationEnabled = true } WebSocket { @@ -45,21 +44,24 @@ Rectangle { url: "ws://127.0.0.1:16395" active: true onStatusChanged: { - if (socket.status === WebSocket.Error) - messageBox.text = "Error: " + socket.errorString; - else if (socket.status === WebSocket.Open) - socket.sendTextMessage("Hello World"); - else if (socket.status === WebSocket.Closed) - messageBox.text += "Socket closed"; + if (socket.status === WebSocket.Open) + socket.sendTextMessage("Hello World from QML wallpaper") } + onTextMessageReceived: { - var obj = JSON.parse(message); + socket.sendTextMessage(message) + + var obj = JSON.parse(message) + if (obj.command === "replace") { - root.type = obj.type; - root.fillMode = obj.fillMode; - root.volume = obj.volume; - root.fullContentPath = obj.absolutePath + "/" + obj.file; - webView.setVideo(); + socket.sendTextMessage("replace") + root.type = obj.type + //root.fillMode = obj.fillMode + root.volume = obj.volume + root.fullContentPath = obj.absolutePath + "/" + obj.file + const msg = "JSON: " +root.type + root.fillMode + root.volume + root.fullContentPath; + socket.sendTextMessage(root.getSetVideoCommand()) + webView.setVideo() } } } @@ -70,31 +72,8 @@ Rectangle { function setVideo() { webView.runJavaScript(root.getSetVideoCommand()); } - + url:"index.html" anchors.fill: parent opacity: loadProgress === 100 ? 1 : 0 - onLoadProgressChanged: { - if (loadProgress === 100) - setVideo(); - - } } - - Rectangle { - id: infoWrapper - - width: 300 - height: 200 - opacity: 0 - anchors.centerIn: parent - - Text { - id: messageBox - - text: qsTr("text") - anchors.centerIn: parent - } - - } - }