diff --git a/.gitignore b/.gitignore index 365f2fa6..b4ef7825 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,4 @@ _deps /Common/ffmpeg/* /Docs/html/screenplay.index /ContentBuilder/** +/aqtinstall.log diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 402395e4..84873e43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ stages: - check - build - test - - benchmark check: stage: check diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt index 130bfc95..8083506c 100644 --- a/CMake/CMakeLists.txt +++ b/CMake/CMakeLists.txt @@ -1,7 +1,7 @@ project(CMake) set(FILES # cmake-format: sortable - QtUpdateTranslations.cmake) + CopyRecursive.cmake QtUpdateTranslations.cmake) add_custom_target( ${PROJECT_NAME} diff --git a/CMake/CopyRecursive.cmake b/CMake/CopyRecursive.cmake new file mode 100644 index 00000000..aecf3c76 --- /dev/null +++ b/CMake/CopyRecursive.cmake @@ -0,0 +1,29 @@ +# Copies all files with the same hierarchy (folder) +# via configure_file but only when the file content is different: +# +# copy_recursive(${SOURCE_PATH} ${DESTINATION_PATH} ${REGEX}) +# +# If you want to copy all files simply set the parameter to: "*" +# Example: +# +# include(CopyRecursive) +# copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/kde/ScreenPlay ${CMAKE_BINARY_DIR}/bin/kde/ScreenPlay "*") +# + +function(copy_recursive SOURCE_PATH DESTINATION_PATH REGEX) + + file(GLOB_RECURSE + FILES + ${SOURCE_PATH} + "${SOURCE_PATH}/${REGEX}") + + foreach(file ${FILES}) + # To recreate the same folder structure we first need to read the base folder + file(RELATIVE_PATH RELATIVE_FILE_PATH ${SOURCE_PATH} ${file}) + get_filename_component(FOLDER ${RELATIVE_FILE_PATH} DIRECTORY ${SOURCE_PATH}) + file(MAKE_DIRECTORY ${DESTINATION_PATH}/${FOLDER} ) + message(STATUS "${file} - ${DESTINATION_PATH}/${RELATIVE_FILE_PATH}") + configure_file(${file} "${DESTINATION_PATH}/${RELATIVE_FILE_PATH}" COPYONLY) + endforeach() + +endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index c4b82a9d..3e261871 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,20 @@ cmake_minimum_required(VERSION 3.16.0) -project(ScreenPlay LANGUAGES CXX) +project( + ScreenPlay + VERSION 0.15.0 + DESCRIPTION "Modern, Cross Plattform, Live Wallpaper, Widgets and AppDrawer!" + HOMEPAGE_URL "https://screen-play.app/" + LANGUAGES CXX) # This sets cmake to compile all dlls into the main directory set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -option(SCREENPLAY_STEAM "For FOSS distribution so we do not bundle proprietary code." ON) -option(TESTS_ENABLED OFF) +option(SCREENPLAY_STEAM "For FOSS distribution so we do not bundle proprietary code." ON) +option(SCREENPLAY_TESTS "Enables UI tests." OFF) +option(SCREENPLAY_CREATE_INSTALLER "Indicates whether an installer via the Qt Installer Framework is created." OFF) # Add our *.cmake diretory to the CMAKE_MODULE_PATH, so that our includes are found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) @@ -25,14 +31,13 @@ elseif(APPLE) set(VCPKG_ARCH "x64-osx") endif() -if(${TESTS_ENABLED}) +if(${SCREENPLAY_TESTS}) enable_testing() endif() set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlay-vcpkg") set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}") - find_package(Git REQUIRED) if(WIN32) set(date_command "CMD") @@ -74,6 +79,7 @@ add_subdirectory(ScreenPlayWallpaper) add_subdirectory(ScreenPlayWidget) add_subdirectory(ScreenPlayUtil) add_subdirectory(CMake) +add_subdirectory(Tools) if(${SCREENPLAY_STEAM}) add_subdirectory(ScreenPlayWorkshop) @@ -86,13 +92,69 @@ if(WIN32) add_subdirectory(ScreenPlaySysInfo) endif() -message(STATUS "[DEFINE] SOURCE_DIR = ${SOURCE_DIR}") -message(STATUS "[DEFINE] BUILD_DATE = ${BUILD_DATE}") -message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}") -message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}") -message(STATUS "[OPTION] TESTS_ENABLED = ${TESTS_ENABLED}") -message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") -message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}") -message(STATUS "[PROJECT] VCPKG_ARCH = ${VCPKG_ARCH}") -message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") -message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") +message(STATUS "[DEFINE] SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}") +message(STATUS "[DEFINE] BUILD_DATE = ${BUILD_DATE}") +message(STATUS "[DEFINE] BUILD_TYPE = ${CMAKE_BUILD_TYPE}") +message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}") +message(STATUS "[OPTION] SCREENPLAY_CREATE_INSTALLER = ${SCREENPLAY_CREATE_INSTALLER}") +message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}") +message(STATUS "[OPTION] SCREENPLAY_TESTS = ${SCREENPLAY_TESTS}") +message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") +message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}") +message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") +message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") +message(STATUS "[PROJECT] CPACK_GENERATOR = ${CPACK_GENERATOR}") + +if(${SCREENPLAY_CREATE_INSTALLER}) + + # Hardcoded Qt paths that are used by the QtMaintanance tool for now... + if(WIN32) + set(CPACK_IFW_ROOT "C:/Qt/Tools/QtInstallerFramework/4.2") + elseif(UNIX AND NOT APPLE) + set(CPACK_IFW_ROOT "$ENV{HOME}/Qt/Tools/QtInstallerFramework/4.2") + endif() + + set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") + set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-Installer") + set(CPACK_PACKAGE_VENDOR "Elias Steurer") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}") + set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}") + + # Ensures that contents written to the CPack configuration files is escaped properly. + set(CPACK_VERBATIM_VARIABLES TRUE) + set(CPACK_GENERATOR IFW) + + set(CPACK_IFW_PACKAGE_START_MENU_DIRECTORY "") # empty => default is install to top-level (?) + set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/Apps/${CMAKE_PROJECT_NAME}") + set(CPACK_IFW_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/ScreenPlay/assets/icons/app.ico") + set(CPACK_IFW_PACKAGE_WINDOW_ICON "${CMAKE_CURRENT_SOURCE_DIR}/ScreenPlay/assets/icons/app.ico") + set(CPACK_IFW_PACKAGE_CONTROL_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/Tools/Installer/installscript.qs") + + set(CPACK_COMPONENTS_GROUPING IGNORE) + set(CPACK_IFW_PACKAGE_GROUP ScreenPlay) + set(CPACK_IFW_VERBOSE ON) + + include(CPack) + include(CPackIFW) + + # Install all files from /bin + install( + DIRECTORY "${CMAKE_BINARY_DIR}/bin/" + COMPONENT ScreenPlay + DESTINATION ".") + + cpack_add_component( + ScreenPlay + DISPLAY_NAME "ScreenPlay" + DESCRIPTION "This installs ScreenPlay.") + + cpack_ifw_configure_component( + ScreenPlayApp FORCED_INSTALLATION + NAME "ScreenPlay" + VERSION ${PROJECT_VERSION} # Version of component + DESCRIPTION "Welcome to the K3000 installer." + # Gets ignored and I do not know why + SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/Tools/Installer/installscript.qs" + CHECKABLE FALSE) + +endif() diff --git a/Docs/DeveloperSetup.md b/Docs/DeveloperSetup.md index 49ff5a3c..626ee2af 100644 --- a/Docs/DeveloperSetup.md +++ b/Docs/DeveloperSetup.md @@ -31,7 +31,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 @@ -67,7 +67,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/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index 53fda182..723a39ac 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -160,7 +160,6 @@ qt_update_translations("${CMAKE_CURRENT_SOURCE_DIR}/qml" "${L10N_LIST}") # Needed on macos find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) -find_package(benchmark CONFIG REQUIRED) find_package(doctest CONFIG REQUIRED) # CURL must be included before sentry because sentry needs the module and does not include it itself on macos... @@ -183,14 +182,10 @@ qt_add_big_resources(FONTS fonts.qrc) add_library(ScreenPlayLib ${SOURCES} ${HEADER} ${RESOURCES} ${FONTS}) -target_include_directories(ScreenPlayLib PUBLIC ./ src/) - target_link_libraries( ScreenPlayLib PUBLIC ScreenPlaySDK ScreenPlayUtil - benchmark::benchmark - benchmark::benchmark_main doctest::doctest sentry::sentry Threads::Threads diff --git a/ScreenPlay/app.cpp b/ScreenPlay/app.cpp index 0cdde83b..cfe79715 100644 --- a/ScreenPlay/app.cpp +++ b/ScreenPlay/app.cpp @@ -1,6 +1,8 @@ #include "app.h" #include "steam/steam_qt_enums_generated.h" +#include +#include namespace ScreenPlay { /*! @@ -98,7 +100,6 @@ App::App() qRegisterMetaType(); qRegisterMetaType(); - // TODO: This is a workaround because I don't know how to // init this in the ScreenPlayWorkshop plugin. // Move to workshop plugin. @@ -211,6 +212,10 @@ void App::init() qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "ScreenPlay", this); QGuiApplication::instance()->addLibraryPath(QGuiApplication::instance()->applicationDirPath()); + if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { + setupKDE(); + } + m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/ScreenPlay/main.qml"))); // Must be called last to display a error message on startup by the qml engine @@ -232,4 +237,72 @@ void App::exit() QApplication::instance()->quit(); } +/*! + \brief +*/ +bool App::setupKDE() +{ + QProcessEnvironment env; + qInfo() << qgetenv("KDE_FULL_SESSION"); + qInfo() << qgetenv("DESKTOP_SESSION"); + qInfo() << qgetenv("XDG_CURRENT_DESKTOP"); + + QProcess plasmaShellVersionProcess; + plasmaShellVersionProcess.start("plasmashell", { "--version" }); + plasmaShellVersionProcess.waitForFinished(); + QString versionOut = plasmaShellVersionProcess.readAll(); + if (!versionOut.contains("plasmashell ")) { + qWarning() << "Unable to read plasma shell version"; + return false; + } + + const QString kdeWallpaperPath = QDir(QDir::homePath() + "/.local/share/plasma/wallpapers/ScreenPlay/").canonicalPath(); + const QFileInfo installedWallpaperMetadata(kdeWallpaperPath + "/metadata.desktop"); + const QString appKdeWallapperPath = QGuiApplication::instance()->applicationDirPath() + "/kde"; + const QFileInfo currentWallpaperMetadata(appKdeWallapperPath + "/ScreenPlay/metadata.desktop"); + + if (!installedWallpaperMetadata.exists()) { + process.setWorkingDirectory(appKdeWallapperPath); + process.start("plasmapkg2", { "--install", "ScreenPlay" }); + process.waitForFinished(); + process.terminate(); + qInfo() << "Install ScreenPlay KDE Wallpaper"; + } else { + QSettings installedWallpaperSettings(installedWallpaperMetadata.absoluteFilePath(), QSettings::Format::IniFormat); + installedWallpaperSettings.beginGroup("Desktop Entry"); + const QString installedWallpaperVersion = installedWallpaperSettings.value("Version").toString(); + installedWallpaperSettings.endGroup(); + const QVersionNumber installedVersionNumber = QVersionNumber::fromString(installedWallpaperVersion); + + QSettings currentWallpaperSettings(currentWallpaperMetadata.absoluteFilePath(), QSettings::Format::IniFormat); + currentWallpaperSettings.beginGroup("Desktop Entry"); + const QString currentWallpaperVersion = currentWallpaperSettings.value("Version").toString(); + currentWallpaperSettings.endGroup(); + const QVersionNumber currentVersionNumber = QVersionNumber::fromString(installedWallpaperVersion); + + if (installedVersionNumber.isNull() || currentVersionNumber.isNull()) { + qCritical() << "Unable to parse version number from:" << currentWallpaperVersion << installedWallpaperVersion; + return false; + } + + if (installedVersionNumber <= currentVersionNumber) + return true; + + qInfo() << "Upgrade ScreenPlay KDE Wallpaper"; + process.setWorkingDirectory(appKdeWallapperPath); + process.start("plasmapkg2", { "--upgrade", "ScreenPlay" }); + process.waitForFinished(); + process.terminate(); + qInfo() << process.readAllStandardError() << process.readAllStandardOutput(); + } + + qInfo() << "Restart KDE "; + process.start("kquitapp5", { "plasmashell" }); + process.waitForFinished(); + process.terminate(); + qInfo() << process.readAllStandardError() << process.readAllStandardOutput(); + process.startDetached("kstart5", { "plasmashell" }); + qInfo() << process.readAllStandardError() << process.readAllStandardOutput(); + return true; +} } diff --git a/ScreenPlay/app.h b/ScreenPlay/app.h index 876d93ee..342d3ce8 100644 --- a/ScreenPlay/app.h +++ b/ScreenPlay/app.h @@ -63,7 +63,6 @@ #include #include - namespace ScreenPlay { class App : public QObject { @@ -216,6 +215,9 @@ public slots: emit wizardsChanged(m_wizards.get()); } +private: + bool setupKDE(); + private: QNetworkAccessManager m_networkAccessManager; QElapsedTimer m_continuousIntegrationMetricsTimer; @@ -233,5 +235,6 @@ private: std::shared_ptr m_monitorListModel; std::shared_ptr m_profileListModel; std::shared_ptr m_installedListFilter; + QProcess process; }; } diff --git a/ScreenPlay/qml/Settings/Settings.qml b/ScreenPlay/qml/Settings/Settings.qml index a382e260..b1fe542f 100644 --- a/ScreenPlay/qml/Settings/Settings.qml +++ b/ScreenPlay/qml/Settings/Settings.qml @@ -125,7 +125,7 @@ Item { id: folderDialogSaveLocation folder: ScreenPlay.globalVariables.localStoragePath onAccepted: { - ScreenPlay.settings.setLocalStoragePath(folderDialogSaveLocation.fileUrls[0]); + ScreenPlay.settings.setLocalStoragePath(folderDialogSaveLocation.currentFolder); } } diff --git a/ScreenPlay/src/createimportvideo.cpp b/ScreenPlay/src/createimportvideo.cpp index cce0bae3..5eacd89c 100644 --- a/ScreenPlay/src/createimportvideo.cpp +++ b/ScreenPlay/src/createimportvideo.cpp @@ -53,8 +53,15 @@ CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& ex void CreateImportVideo::setupFFMPEG() { + +#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(); +#endif if (!QFileInfo::exists(m_ffprobeExecutable)) { qFatal("FFPROBE executable not found!"); @@ -126,10 +133,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 362a9761..8992ee80 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -83,10 +83,21 @@ void ScreenPlayManager::init( if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { m_websocketServer = std::make_unique(QStringLiteral("ScreenPlayWebSocket"), QWebSocketServer::SslMode::NonSecureMode); - m_websocketServer->listen(QHostAddress::Any, m_webSocketPort); + const bool success = m_websocketServer->listen(QHostAddress::Any, m_webSocketPort); + qInfo() << "Open Websocket:" << success << "port:" << m_webSocketPort; 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->flush(); }); } @@ -116,6 +127,7 @@ bool ScreenPlayManager::createWallpaper( const QJsonObject& properties, const bool saveToProfilesConfigFile) { + const int screenCount = QGuiApplication::screens().count(); QJsonArray monitors; @@ -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,13 +200,15 @@ 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); @@ -254,6 +284,15 @@ bool ScreenPlayManager::removeAllWallpapers() return false; } } + if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { + for (auto& connection : m_connections) { + QJsonObject obj; + obj.insert("command", "quit"); + connection->sendTextMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact)); + connection->flush(); + connection->close(); + } + } emit requestSaveProfiles(); @@ -341,7 +380,7 @@ bool ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q */ bool ScreenPlayManager::setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode) { - const auto fillModeTyped = static_cast(fillmode); + const auto fillModeTyped = static_cast(fillmode); if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { return setWallpaperValue(*appID, "fillmode", QVariant::fromValue(fillModeTyped).toString()); @@ -445,6 +484,8 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID) return false; } + if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::Windows || m_settings->desktopEnvironment() == Settings::DesktopEnvironment::OSX) + wallpaper->messageKDECloseWallpaper(); qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber(); diff --git a/ScreenPlay/src/screenplaymanager.h b/ScreenPlay/src/screenplaymanager.h index b93558e1..d0e699d2 100644 --- a/ScreenPlay/src/screenplaymanager.h +++ b/ScreenPlay/src/screenplaymanager.h @@ -183,6 +183,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 ab27b5e1..c2e293f3 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -24,7 +24,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 } @@ -37,6 +37,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, , m_file { file } , m_volume { volume } , m_playbackRate { playbackRate } + , m_settings { settings } { QJsonObject projectSettingsListModelProperties; @@ -81,7 +82,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" }; @@ -145,10 +146,9 @@ void ScreenPlayWallpaper::close() return; } - if(m_connection->close()){ + if (m_connection->close()) { m_isExiting = true; } - } /*! \brief Prints the exit code if != 0. @@ -175,7 +175,7 @@ void ScreenPlayWallpaper::processError(QProcess::ProcessError error) */ bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save) { - if(m_isExiting) + if (m_isExiting) return false; if (!m_connection) { @@ -249,7 +249,7 @@ void ScreenPlayWallpaper::replace( const bool checkWallpaperVisible) { - if(m_isExiting) + if (m_isExiting) return; if (!m_connection) { diff --git a/ScreenPlay/src/screenplaywallpaper.h b/ScreenPlay/src/screenplaywallpaper.h index 7019c0c6..ab555cf8 100644 --- a/ScreenPlay/src/screenplaywallpaper.h +++ b/ScreenPlay/src/screenplaywallpaper.h @@ -44,6 +44,7 @@ #include "globalvariables.h" #include "projectsettingslistmodel.h" #include "sdkconnection.h" +#include "settings.h" #include "util.h" namespace ScreenPlay { @@ -78,10 +79,12 @@ 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(); @@ -124,6 +127,7 @@ signals: void volumeChanged(float volume); void isLoopingChanged(bool isLooping); void playbackRateChanged(float playbackRate); + void messageKDECloseWallpaper(); void requestSave(); void requestClose(const QString& appID); @@ -241,6 +245,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; @@ -256,9 +261,9 @@ private: float m_playbackRate { 1.0f }; QTimer m_pingAliveTimer; QStringList m_appArgumentsList; - bool m_isConnected { false }; + bool m_isConnected { false }; // There are still cases where we can access the current item // while exiting. This flag is to ignore all setWallpaperValue calls - bool m_isExiting { false }; + bool m_isExiting { false }; }; } diff --git a/ScreenPlay/src/sdkconnection.cpp b/ScreenPlay/src/sdkconnection.cpp index cc4e3ad0..c60bd62a 100644 --- a/ScreenPlay/src/sdkconnection.cpp +++ b/ScreenPlay/src/sdkconnection.cpp @@ -108,7 +108,7 @@ bool ScreenPlay::SDKConnection::sendMessage(const QByteArray& message) */ bool ScreenPlay::SDKConnection::close() { - if (!m_socket){ + if (!m_socket) { qWarning() << "Cannot close invalid socket."; return false; } diff --git a/ScreenPlaySysInfo/CMakeLists.txt b/ScreenPlaySysInfo/CMakeLists.txt index 7e7d1f21..6026ab85 100644 --- a/ScreenPlaySysInfo/CMakeLists.txt +++ b/ScreenPlaySysInfo/CMakeLists.txt @@ -34,10 +34,14 @@ set(HEADER add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER}) -qt_add_qml_module(${PROJECT_NAME} - OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/SysInfo - URI ${PROJECT_NAME} - VERSION 1.0) +qt_add_qml_module( + ${PROJECT_NAME} + OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/bin/SysInfo + URI + ${PROJECT_NAME} + VERSION + 1.0) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$,$>:QT_QML_DEBUG>) diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index 3047e2dc..2d66b427 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -12,8 +12,10 @@ find_package( set(SOURCES # cmake-format: sortable src/util.cpp src/contenttypes.cpp inc/public/ScreenPlayUtil/httpfileserver.cpp) -set(HEADER # cmake-format: sortable - inc/public/ScreenPlayUtil/util.h inc/public/ScreenPlayUtil/httpfileserver.h inc/public/ScreenPlayUtil/contenttypes.h inc/public/ScreenPlayUtil/projectfile.h) +set(HEADER + # cmake-format: sortable + inc/public/ScreenPlayUtil/util.h inc/public/ScreenPlayUtil/httpfileserver.h inc/public/ScreenPlayUtil/contenttypes.h + inc/public/ScreenPlayUtil/projectfile.h) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADER}) diff --git a/ScreenPlayWallpaper/CMakeLists.txt b/ScreenPlayWallpaper/CMakeLists.txt index 3cf79351..f3ea021c 100644 --- a/ScreenPlayWallpaper/CMakeLists.txt +++ b/ScreenPlayWallpaper/CMakeLists.txt @@ -68,6 +68,11 @@ target_link_libraries( Qt6::WebEngineCore Qt6::WebEngineQuick) +if(UNIX AND NOT APPLE) + include(CopyRecursive) + copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/kde/ScreenPlay ${CMAKE_BINARY_DIR}/bin/kde/ScreenPlay "*") +endif() + if(APPLE) set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa") 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/WaitingForScreenplay.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml new file mode 100644 index 00000000..deda4063 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml @@ -0,0 +1,74 @@ +import QtQuick 2.15 + +Rectangle { + anchors.fill: parent + color: "black" + + Rectangle { + id: toBeCreated + anchors.fill: parent + color: "black" + opacity: 0 + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + anchors.centerIn: parent + text: qsTr("Please start ScreenPlay before launching the wallpaper") + color: "White" + font.pixelSize: 50 + } + + OpacityAnimator on opacity{ + id: createAnimation + from: 0; + to: 1; + duration: 1000 + onRunningChanged: { + if(!running){ + toBeDeleted.opacity = 1 + toBeCreated.opacity = 0 + destroyAnimation.start() + } + } + } + Component.onCompleted: { + createAnimation.start() + } + } + + Rectangle { + opacity: 0 + id: toBeDeleted + anchors.fill: parent + color: "black" + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + anchors.centerIn: parent + text: qsTr("Please start ScreenPlay before launching the wallpaper") + color: "White" + font.pixelSize: 50 + } + + OpacityAnimator on opacity{ + id: destroyAnimation + from: 1; + to: 0; + duration: 1000 + running: false + onRunningChanged: { + if(!running){ + toBeDeleted.opacity = 0 + toBeCreated.opacity = 0 + createAnimation.start() + } + } + } + } +} + + diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml new file mode 100644 index 00000000..15d0d782 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml @@ -0,0 +1,92 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.12 +import QtWebSockets 1.1 +import QtWebEngine 1.8 +import QtMultimedia 5.12 +import Qt.labs.settings 1.1 + + +Rectangle { + id: root + color: "black" + anchors.fill: parent + + property string fullContentPath + property real volume: 1 + property string fillMode: "Cover" + property string type + property string projectSourceFileAbsolute + property bool loops: true + + function stop(){ + player1.stop() + player2.stop() + videoOutput1.visible = false + videoOutput2.visible = false + root.enabled = false + } + + function play(){ + root.enabled = true + videoOutput2.visible = false + videoOutput1.visible = true + + //if(wallpaper.configuration.DualPlayback){ + player2.source = root.projectSourceFileAbsolute + player2.play() + player2.pause() + //} + player1.play() + } + + MediaPlayer { + id: player1 + volume: root.volume + source: root.projectSourceFileAbsolute + onStopped: { + if(!root.enabled) + return + + videoOutput1.visible = false + videoOutput2.visible = true + if(player2.source !== root.projectSourceFileAbsolute){ + player2.source = root.projectSourceFileAbsolute + } + player1.play() + player1.pause() + player2.play() + } + } + + MediaPlayer { + id: player2 + volume: root.volume + onStopped: { + if(!root.enabled) + return + videoOutput2.visible = false + videoOutput1.visible = true + player2.play() + player2.pause() + player1.play() + } + } + + + VideoOutput { + id: videoOutput1 + fillMode: VideoOutput.PreserveAspectCrop + anchors.fill: parent + source: player1 + } + + VideoOutput { + id: videoOutput2 + fillMode: VideoOutput.PreserveAspectCrop + anchors.fill: parent + source: player2 + } + + + +} diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml new file mode 100644 index 00000000..d7998261 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml @@ -0,0 +1,42 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.12 +import QtWebSockets 1.1 +import QtWebEngine 1.8 +import QtMultimedia 5.12 + + +Rectangle { + id: container + anchors.fill: parent + + Loader { + id: wp + anchors.fill: parent + source: "Wallpaper.qml" + property bool connected: false + + Timer { + id: connectTimer + interval: 1000 + running: true + repeat: true + onTriggered: { + if(!wp.connected){ + console.log("not connected") + wp.source = "" + wp.source = "Wallpaper.qml" + } else { + console.log("connected") + screensaver.visible = false + connectTimer.stop() + } + } + } + } + + Loader { + anchors.fill: parent + id: screensaver + source: "WaitingForScreenplay.qml" + } +} diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml index d508a3bf..6dae3f0a 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml @@ -1,13 +1,14 @@ -import QtQuick -import QtQuick.Controls as QQC -import QtQuick.Window -import Qt5Compat.GraphicalEffects +import QtQuick 2.11 +import QtQuick.Controls 2.4 as QQC +import QtQuick.Window 2.0 +import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.wallpapers.image 2.0 as Wallpaper import org.kde.kcm 1.1 as KCM import org.kde.kirigami 2.4 as Kirigami import org.kde.newstuff 1.1 as NewStuff + Column { id: root diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml index d69899f0..e31b4ff0 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml @@ -1,100 +1,115 @@ -import QtQuick -import Qt5Compat.GraphicalEffects -import QtQuick.Window -import Qt.WebSockets 1.15 -import QtWebEngine +import QtQuick 2.0 +import QtQuick.Controls 2.12 +import QtWebSockets 1.1 +import QtWebEngine 1.8 +import QtMultimedia 5.12 +import Qt.labs.settings 1.1 + Rectangle { - id: root + id:root + color:"orange" + property bool connected: false - property string fullContentPath - property real volume: 1 - property string fillMode: "Cover" - property string type - - 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; + Settings { + id:settings } - 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; + wallpaper.projectSourceFileAbsolute = settings.value("SP_projectSourceFileAbsolute","NULL") +// if(root.projectSourceFileAbsolute === "NULL") +// return + + wallpaper.type = settings.value("SP_type") + wallpaper.fillMode = settings.value("SP_fillMode") + wallpaper.volume = settings.value("SP_volume") + wallpaper.play() + } + + + Wallpaper { + id:wallpaper + anchors.fill: parent + // visible: root.connected + + onFullContentPathChanged: settings.setValue("SP_fullContentPath",fullContentPath) + onVolumeChanged: settings.setValue("SP_volume",volume) + onFillModeChanged: settings.setValue("SP_fillMode",fillMode) + onTypeChanged: settings.setValue("SP_type",type) + onProjectSourceFileAbsoluteChanged: settings.setValue("SP_projectSourceFileAbsolute",projectSourceFileAbsolute) + onLoopsChanged: settings.setValue("SP_loops",loops) + + } + + Timer { + id:reconnectTimer + interval: 1000 + running: true + repeat: true + onTriggered: { + if (socket.status === WebSocket.Open) + return + socket.active = false + socket.active = true + reconnectTimer.retryCounter += 1 + } + property int retryCounter: 0 } WebSocket { id: socket - 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); + + onTextMessageReceived: (message)=> { + + var obj = JSON.parse(message) + root.connected = true + txtCommand.text = obj.command + 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") + wallpaper.type = obj.type + wallpaper.fillMode = obj.fillMode + wallpaper.volume = obj.volume + wallpaper.projectSourceFileAbsolute = "file://" + obj.absolutePath + "/" + obj.file + print("got: " + root.projectSourceFileAbsolute) + wallpaper.play() + return; + } + if(obj.command === "quit"){ + wallpaper.stop() + } } } - - WebEngineView { - id: webView - - function setVideo() { - webView.runJavaScript(root.getSetVideoCommand()); +// WaitingForScreenplay { +// anchors.fill: parent +// visible: !root.connected +// } + Column { + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + margins: 60 } - - 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 + id:txtCommand + color: "white" + } + Text { + color: "white" + text:wallpaper.type + wallpaper.projectSourceFileAbsolute + } + Text { + color: "white" + text:"Actitve: " +socket.active +" status: "+ socket.status + " reconnectTimer.retryCounter : "+ reconnectTimer.retryCounter } - } + + } + diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop index 84c6968d..149c69de 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop +++ b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop @@ -3,6 +3,7 @@ Encoding=UTF-8 Name=ScreenPlay Keywords=ScreenPlay Icon=preferences-desktop-wallpaper +Version=0.15.0 Type=Service diff --git a/ScreenPlayWallpaper/src/linuxwindow.cpp b/ScreenPlayWallpaper/src/linuxwindow.cpp index fab82bd5..2dd66b5c 100644 --- a/ScreenPlayWallpaper/src/linuxwindow.cpp +++ b/ScreenPlayWallpaper/src/linuxwindow.cpp @@ -46,24 +46,9 @@ LinuxWindow::LinuxWindow( setHeight(m_window.height()); m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); - m_window.rootContext()->setContextProperty("window", this); - //m_window.rootContext()->setContextProperty("desktopProperties", &m_windowsDesktopProperties); - // Instead of setting "renderType: Text.NativeRendering" every time - // we can set it here once :) - + qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); - m_window.setSource(QUrl("qrc:/mainWindow.qml")); - - // WARNING: Setting Window flags must be called *here*! - Qt::WindowFlags flags = m_window.flags(); - m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::Desktop); - - m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); - m_window.rootContext()->setContextProperty("window", this); - // Instead of setting "renderType: Text.NativeRendering" every time - // we can set it here once :) - m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); - m_window.setSource(QUrl("qrc:/Wallpaper.qml")); + m_window.setSource(QUrl("qrc:/ScreenPlayWallpaper/qml/Wallpaper.qml")); } void LinuxWindow::setupWallpaperForOneScreen(int activeScreen) diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index 28177872..9f3935ad 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -320,7 +320,7 @@ void WinWindow::setupWallpaperForAllScreens() m_window.setHeight(rect.height()); m_window.setWidth(rect.width()); m_window.setY(offsetY); - m_window.setX(offsetX+1920); + m_window.setX(offsetX + 1920); qInfo() << m_window.geometry(); } diff --git a/ScreenPlayWorkshop/CMakeLists.txt b/ScreenPlayWorkshop/CMakeLists.txt index d7ef8ff1..00211656 100644 --- a/ScreenPlayWorkshop/CMakeLists.txt +++ b/ScreenPlayWorkshop/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 20) find_package( Qt6 - COMPONENTS Quick QML Widgets Gui + COMPONENTS Quick Widgets Gui REQUIRED) set(SOURCES @@ -58,24 +58,27 @@ qt_add_qml_module( ${PROJECT_NAME} OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR} - URI "Workshop" - SOURCES ${SOURCES} ${HEADER} - VERSION 1.0) - + URI + "Workshop" + SOURCES + ${SOURCES} + ${HEADER} + VERSION + 1.0) if(${SCREENPLAY_STEAM}) if(APPLE) - file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR}) - file(MAKE_DIRECTORY ${MACOS_FRAMEWORKS_DIR}) + file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR}) + file(MAKE_DIRECTORY ${MACOS_FRAMEWORKS_DIR}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/ COPYONLY) - configure_file(${STEAM_BIN} ${WORKSHOP_PLUGIN_DIR} COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/ COPYONLY) + configure_file(${STEAM_BIN} ${WORKSHOP_PLUGIN_DIR} COPYONLY) - set_target_properties(${PROJECT_NAME} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop) + set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop) else() - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt COPYONLY) - configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt COPYONLY) + configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY) endif() endif() diff --git a/ScreenPlayWorkshop/SteamSDK/CMakeLists.txt b/ScreenPlayWorkshop/SteamSDK/CMakeLists.txt index 74e908c4..ea23c2fc 100644 --- a/ScreenPlayWorkshop/SteamSDK/CMakeLists.txt +++ b/ScreenPlayWorkshop/SteamSDK/CMakeLists.txt @@ -49,9 +49,7 @@ set(HEADER public/steam/steamnetworkingtypes.h public/steam/steamps3params.h public/steam/steamtypes.h - public/steam/steamuniverse.h -) - + public/steam/steamuniverse.h) if(${SCREENPLAY_STEAM}) add_library(${PROJECT_NAME} STATIC ${HEADER}) @@ -59,8 +57,8 @@ if(${SCREENPLAY_STEAM}) target_link_libraries(${PROJECT_NAME}) endif() -# We allaways need the generated enums as a workaround to register these enums in app.cpp. -# Registering in the ScreenPlayWorkshop plugin does not work for some reason. +# We allaways need the generated enums as a workaround to register these enums in app.cpp. Registering in the ScreenPlayWorkshop plugin does +# not work for some reason. add_library(SteamSDKQtEnums STATIC public/steam/steam_qt_enums_generated.h) target_include_directories(SteamSDKQtEnums PUBLIC public/) target_link_libraries(SteamSDKQtEnums PRIVATE Qt6::Core) diff --git a/ScreenPlayWorkshop/src/installedlistmodel.cpp b/ScreenPlayWorkshop/src/installedlistmodel.cpp index 7773c35a..b7d22c69 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.cpp +++ b/ScreenPlayWorkshop/src/installedlistmodel.cpp @@ -88,10 +88,10 @@ void InstalledListModel::append(const QJsonObject& obj, const QString& folderNam void InstalledListModel::loadInstalledContent() { - if(m_loadContentFutureWatcher.isRunning()) + if (m_loadContentFutureWatcher.isRunning()) return; - m_loadContentFuture = QtConcurrent::run([this]() { + m_loadContentFuture = QtConcurrent::run([this]() { QFileInfoList list = QDir(m_absoluteStoragePath.toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs); for (const auto& item : list) { diff --git a/ScreenPlayWorkshop/src/uploadlistmodel.h b/ScreenPlayWorkshop/src/uploadlistmodel.h index 4ba07d80..2da372ae 100644 --- a/ScreenPlayWorkshop/src/uploadlistmodel.h +++ b/ScreenPlayWorkshop/src/uploadlistmodel.h @@ -103,16 +103,16 @@ public slots: emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::UploadProgressRole) }); }); QObject::connect(item.get(), &SteamWorkshopItem::nameChanged, this, [this]() { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::NameRole) }); + emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::NameRole) }); }); QObject::connect(item.get(), &SteamWorkshopItem::absolutePreviewImagePathChanged, this, [this]() { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); + emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); }); QObject::connect(item.get(), &SteamWorkshopItem::uploadComplete, this, [this](bool successful) { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); + emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); }); QObject::connect(item.get(), &SteamWorkshopItem::statusChanged, this, [this](ScreenPlayWorkshopSteamEnums::EResult status) { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::Status) }); + emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::Status) }); // Check if all items are diff --git a/Tools/CMakeLists.txt b/Tools/CMakeLists.txt new file mode 100644 index 00000000..7cbb9ccf --- /dev/null +++ b/Tools/CMakeLists.txt @@ -0,0 +1,11 @@ +project(Tools LANGUAGES CXX) + +file(GLOB PYTHON *.py) + +set(FILES # cmake-format: sortable + Installer/package.xml Installer/installscript.qs) + +add_custom_target( + ${PROJECT_NAME} + SOURCES ${FILES} ${PYTHON} + COMMENT "Dummy target to list these files in the IDE") diff --git a/Tools/Installer/installscript.qs b/Tools/Installer/installscript.qs new file mode 100644 index 00000000..c742aeea --- /dev/null +++ b/Tools/Installer/installscript.qs @@ -0,0 +1,14 @@ +function Component() +{ + // Install to @RootDir@ instead of @HomeDir@ on Windows + if (installer.value("os") === "win") { + var homeDir = installer.value("HomeDir"); + var targetDir = installer.value("TargetDir").replace(homeDir, "@RootDir@"); + installer.setValue("TargetDir", targetDir); + } + + // do not show component selection page + installer.setDefaultPageVisible(QInstaller.ComponentSelection, false); + // no startmenu entry so no need to ask where to create it + installer.setDefaultPageVisible(QInstaller.StartMenuSelection, false); +} diff --git a/Tools/Installer/package.xml b/Tools/Installer/package.xml new file mode 100644 index 00000000..bf774efd --- /dev/null +++ b/Tools/Installer/package.xml @@ -0,0 +1,9 @@ + + + Register a file extension + Register a randomly generated file extension to open with notepad.exe + 1.0.0-1 + 2020-01-01 + true + + diff --git a/Tools/build.py b/Tools/build.py index 10744e42..43bb0b39 100644 --- a/Tools/build.py +++ b/Tools/build.py @@ -40,16 +40,27 @@ parser.add_argument('-sign', action="store", dest="sign_build", help="Enable if you want to sign the apps. This is macos only for now.") parser.add_argument('-steam', action="store", dest="steam_build", help="Enable if you want to build the Steam workshop plugin.") +parser.add_argument('-tests', action="store", dest="build_tests", + help="Build tests.") +parser.add_argument('-installer', action="store", dest="create_installer", + help="Create a installer.") args = parser.parse_args() if not args.build_type: print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True") sys.exit(1) -qt_version = "6.2.1" +qt_version = "6.2.2" steam_build = "OFF" +build_tests = "OFF" +create_installer = "OFF" + if args.steam_build: - steam_build = "ON" + steam_build = "ON" +if args.build_tests: + build_tests = "ON" +if args.create_installer: + create_installer = "ON" print("Starting build with type %s. Qt Version: %s" % (args.build_type, qt_version)) @@ -79,7 +90,7 @@ elif platform == "darwin": deploy_command = "{prefix_path}/bin/macdeployqt {app}.app -qmldir=../../{app}/qml -executable={app}.app/Contents/MacOS/{app}" cmake_target_triplet = "x64-osx" elif platform == "linux": - deploy_command = "cqtdeployer -qmldir ../../{app}/qml -bin {app}" + deploy_command = "cqtdeployer -qmlDir ../../{app}/qml -bin {app}" cmake_prefix_path = "~/Qt/" + qt_version + "/gcc_64" cmake_target_triplet = "x64-linux" @@ -98,7 +109,6 @@ if os.path.isdir(build_folder): print("Remove previous build folder: " + build_folder) shutil.rmtree(build_folder) - os.mkdir(build_folder) os.chdir(build_folder) @@ -107,8 +117,9 @@ cmake_configure_command = """cmake ../ -DCMAKE_BUILD_TYPE={type} -DCMAKE_TOOLCHAIN_FILE={toolchain} -DVCPKG_TARGET_TRIPLET={triplet} - -DTESTS_ENABLED=OFF -DSCREENPLAY_STEAM={steam} + -DSCREENPLAY_TESTS={tests} + -DSCREENPLAY_CREATE_INSTALLER={installer} -G "CodeBlocks - Ninja" -B. """.format( @@ -116,7 +127,10 @@ cmake_configure_command = """cmake ../ prefix_path=cmake_prefix_path, triplet=cmake_target_triplet, toolchain=cmake_toolchain_file, - steam=steam_build).replace("\n", "") + steam=steam_build, + tests = build_tests, + installer= create_installer + ).replace("\n", "") execute(cmake_configure_command) execute("cmake --build . --target all") @@ -184,3 +198,7 @@ for filename in os.listdir(os.getcwd()): full_file_path = os.path.join(os.getcwd(), filename) print("Remove: %s" % full_file_path) os.remove(full_file_path) + +if args.create_installer: + os.chdir("..") + execute("cpack") \ No newline at end of file diff --git a/Tools/setup.py b/Tools/setup.py index 0980c10c..9e33f0a1 100644 --- a/Tools/setup.py +++ b/Tools/setup.py @@ -31,7 +31,7 @@ if __name__ == "__main__": vcpkg_path = os.path.join(project_source_parent_path, "ScreenPlay-vcpkg") print("vcpkg_path: ", vcpkg_path) - vcpkg_version = "9172179c513aa84308e48b8dd0e3df90acec7204" # Master 25.06.2021 + vcpkg_version = "5ddd7f0" # Master 02.12.2021 print("Build vcpkg ", vcpkg_version) execute("git fetch", vcpkg_path) execute("git checkout {}".format(vcpkg_version), vcpkg_path) @@ -41,7 +41,6 @@ if __name__ == "__main__": "curl", "sentry-native", "doctest", - "benchmark", "cpp-httplib" ]