1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-06 19:12:30 +01:00

Merge branch 'qt6-kde' into 'master'

Add basic kde wallpaper support via Websockets

See merge request kelteseth/ScreenPlay!91
This commit is contained in:
Elias Steurer 2021-12-31 13:14:49 +00:00
commit d9ad963a81
37 changed files with 677 additions and 184 deletions

1
.gitignore vendored
View File

@ -95,3 +95,4 @@ _deps
/Common/ffmpeg/* /Common/ffmpeg/*
/Docs/html/screenplay.index /Docs/html/screenplay.index
/ContentBuilder/** /ContentBuilder/**
/aqtinstall.log

View File

@ -2,7 +2,6 @@ stages:
- check - check
- build - build
- test - test
- benchmark
check: check:
stage: check stage: check

View File

@ -1,7 +1,7 @@
project(CMake) project(CMake)
set(FILES # cmake-format: sortable set(FILES # cmake-format: sortable
QtUpdateTranslations.cmake) CopyRecursive.cmake QtUpdateTranslations.cmake)
add_custom_target( add_custom_target(
${PROJECT_NAME} ${PROJECT_NAME}

29
CMake/CopyRecursive.cmake Normal file
View File

@ -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()

View File

@ -1,14 +1,20 @@
cmake_minimum_required(VERSION 3.16.0) 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 # This sets cmake to compile all dlls into the main directory
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_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(SCREENPLAY_STEAM "For FOSS distribution so we do not bundle proprietary code." ON)
option(TESTS_ENABLED OFF) 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 # 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}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
@ -25,14 +31,13 @@ elseif(APPLE)
set(VCPKG_ARCH "x64-osx") set(VCPKG_ARCH "x64-osx")
endif() endif()
if(${TESTS_ENABLED}) if(${SCREENPLAY_TESTS})
enable_testing() enable_testing()
endif() endif()
set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlay-vcpkg") set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlay-vcpkg")
set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}") set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}")
find_package(Git REQUIRED) find_package(Git REQUIRED)
if(WIN32) if(WIN32)
set(date_command "CMD") set(date_command "CMD")
@ -74,6 +79,7 @@ add_subdirectory(ScreenPlayWallpaper)
add_subdirectory(ScreenPlayWidget) add_subdirectory(ScreenPlayWidget)
add_subdirectory(ScreenPlayUtil) add_subdirectory(ScreenPlayUtil)
add_subdirectory(CMake) add_subdirectory(CMake)
add_subdirectory(Tools)
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
add_subdirectory(ScreenPlayWorkshop) add_subdirectory(ScreenPlayWorkshop)
@ -86,13 +92,69 @@ if(WIN32)
add_subdirectory(ScreenPlaySysInfo) add_subdirectory(ScreenPlaySysInfo)
endif() endif()
message(STATUS "[DEFINE] SOURCE_DIR = ${SOURCE_DIR}") message(STATUS "[DEFINE] SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "[DEFINE] BUILD_DATE = ${BUILD_DATE}") message(STATUS "[DEFINE] BUILD_DATE = ${BUILD_DATE}")
message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}") message(STATUS "[DEFINE] BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}") message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}")
message(STATUS "[OPTION] TESTS_ENABLED = ${TESTS_ENABLED}") message(STATUS "[OPTION] SCREENPLAY_CREATE_INSTALLER = ${SCREENPLAY_CREATE_INSTALLER}")
message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}")
message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}") message(STATUS "[OPTION] SCREENPLAY_TESTS = ${SCREENPLAY_TESTS}")
message(STATUS "[PROJECT] VCPKG_ARCH = ${VCPKG_ARCH}") message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}")
message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") 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()

View File

@ -31,7 +31,7 @@ py setup.py
Append this: Append this:
``` bash ``` 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: # Only _one_ of these lines that match your OS:
VCPKG_TARGET_TRIPLET:STRING=x64-windows VCPKG_TARGET_TRIPLET:STRING=x64-windows
VCPKG_TARGET_TRIPLET:STRING=x64-linux VCPKG_TARGET_TRIPLET:STRING=x64-linux
@ -67,7 +67,7 @@ VCPKG_TARGET_TRIPLET:STRING=x64-osx
1. Install dependencies for your distro: 1. Install dependencies for your distro:
``` bash ``` bash
# Debian/Ubuntu # 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) # Fedora/RHEL/CentOS (yum)
sudo yum groupinstall "C Development Tools and Libraries" sudo yum groupinstall "C Development Tools and Libraries"

View File

@ -160,7 +160,6 @@ qt_update_translations("${CMAKE_CURRENT_SOURCE_DIR}/qml" "${L10N_LIST}")
# Needed on macos # Needed on macos
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
find_package(benchmark CONFIG REQUIRED)
find_package(doctest 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... # 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}) add_library(ScreenPlayLib ${SOURCES} ${HEADER} ${RESOURCES} ${FONTS})
target_include_directories(ScreenPlayLib PUBLIC ./ src/)
target_link_libraries( target_link_libraries(
ScreenPlayLib ScreenPlayLib
PUBLIC ScreenPlaySDK PUBLIC ScreenPlaySDK
ScreenPlayUtil ScreenPlayUtil
benchmark::benchmark
benchmark::benchmark_main
doctest::doctest doctest::doctest
sentry::sentry sentry::sentry
Threads::Threads Threads::Threads

View File

@ -1,6 +1,8 @@
#include "app.h" #include "app.h"
#include "steam/steam_qt_enums_generated.h" #include "steam/steam_qt_enums_generated.h"
#include <QProcessEnvironment>
#include <QVersionNumber>
namespace ScreenPlay { namespace ScreenPlay {
/*! /*!
@ -98,7 +100,6 @@ App::App()
qRegisterMetaType<MonitorListModel*>(); qRegisterMetaType<MonitorListModel*>();
qRegisterMetaType<ProfileListModel*>(); qRegisterMetaType<ProfileListModel*>();
// TODO: This is a workaround because I don't know how to // TODO: This is a workaround because I don't know how to
// init this in the ScreenPlayWorkshop plugin. // init this in the ScreenPlayWorkshop plugin.
// Move to workshop plugin. // Move to workshop plugin.
@ -211,6 +212,10 @@ void App::init()
qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "ScreenPlay", this); qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "ScreenPlay", this);
QGuiApplication::instance()->addLibraryPath(QGuiApplication::instance()->applicationDirPath()); QGuiApplication::instance()->addLibraryPath(QGuiApplication::instance()->applicationDirPath());
if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) {
setupKDE();
}
m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/ScreenPlay/main.qml"))); m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/ScreenPlay/main.qml")));
// Must be called last to display a error message on startup by the qml engine // 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(); 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;
}
} }

View File

@ -63,7 +63,6 @@
#include <memory> #include <memory>
#include <sentry.h> #include <sentry.h>
namespace ScreenPlay { namespace ScreenPlay {
class App : public QObject { class App : public QObject {
@ -216,6 +215,9 @@ public slots:
emit wizardsChanged(m_wizards.get()); emit wizardsChanged(m_wizards.get());
} }
private:
bool setupKDE();
private: private:
QNetworkAccessManager m_networkAccessManager; QNetworkAccessManager m_networkAccessManager;
QElapsedTimer m_continuousIntegrationMetricsTimer; QElapsedTimer m_continuousIntegrationMetricsTimer;
@ -233,5 +235,6 @@ private:
std::shared_ptr<MonitorListModel> m_monitorListModel; std::shared_ptr<MonitorListModel> m_monitorListModel;
std::shared_ptr<ProfileListModel> m_profileListModel; std::shared_ptr<ProfileListModel> m_profileListModel;
std::shared_ptr<InstalledListFilter> m_installedListFilter; std::shared_ptr<InstalledListFilter> m_installedListFilter;
QProcess process;
}; };
} }

View File

@ -125,7 +125,7 @@ Item {
id: folderDialogSaveLocation id: folderDialogSaveLocation
folder: ScreenPlay.globalVariables.localStoragePath folder: ScreenPlay.globalVariables.localStoragePath
onAccepted: { onAccepted: {
ScreenPlay.settings.setLocalStoragePath(folderDialogSaveLocation.fileUrls[0]); ScreenPlay.settings.setLocalStoragePath(folderDialogSaveLocation.currentFolder);
} }
} }

View File

@ -53,8 +53,15 @@ CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& ex
void CreateImportVideo::setupFFMPEG() 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_ffprobeExecutable = QApplication::applicationDirPath() + "/ffprobe" + ScreenPlayUtil::executableBinEnding();
m_ffmpegExecutable = QApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding(); m_ffmpegExecutable = QApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding();
#endif
if (!QFileInfo::exists(m_ffprobeExecutable)) { if (!QFileInfo::exists(m_ffprobeExecutable)) {
qFatal("FFPROBE executable not found!"); qFatal("FFPROBE executable not found!");
@ -126,10 +133,9 @@ bool CreateImportVideo::createWallpaperInfo()
} }
if (obj->empty()) { 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 processOutput("Error! File could not be parsed.");
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
return false; return false;
} }

View File

@ -83,10 +83,21 @@ void ScreenPlayManager::init(
if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) {
m_websocketServer = std::make_unique<QWebSocketServer>(QStringLiteral("ScreenPlayWebSocket"), QWebSocketServer::SslMode::NonSecureMode); m_websocketServer = std::make_unique<QWebSocketServer>(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]() { QObject::connect(m_websocketServer.get(), &QWebSocketServer::newConnection, this, [this]() {
qInfo() << "New Websocket Connection"; qInfo() << "New Websocket Connection";
auto* socket = m_websocketServer->nextPendingConnection(); 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 QJsonObject& properties,
const bool saveToProfilesConfigFile) const bool saveToProfilesConfigFile)
{ {
const int screenCount = QGuiApplication::screens().count(); const int screenCount = QGuiApplication::screens().count();
QJsonArray monitors; QJsonArray monitors;
@ -137,6 +149,22 @@ bool ScreenPlayManager::createWallpaper(
const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile(); const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile();
const QString appID = ScreenPlayUtil::generateRandomString(); 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<int>(type));
msg.insert("fillMode", static_cast<int>(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 // Only support remove wallpaper that spans over 1 monitor
if (monitorIndex.length() == 1) { if (monitorIndex.length() == 1) {
int i = 0; int i = 0;
@ -172,13 +200,15 @@ bool ScreenPlayManager::createWallpaper(
fillMode, fillMode,
type, type,
properties, properties,
m_settings->checkWallpaperVisible()); m_settings);
QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestSave, this, &ScreenPlayManager::requestSaveProfiles); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestSave, this, &ScreenPlayManager::requestSaveProfiles);
QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestClose, this, &ScreenPlayManager::removeWallpaper); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestClose, this, &ScreenPlayManager::removeWallpaper);
QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::error, this, &ScreenPlayManager::displayErrorPopup); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::error, this, &ScreenPlayManager::displayErrorPopup);
if (!wallpaper->start()) { if (m_settings->desktopEnvironment() != Settings::DesktopEnvironment::KDE) {
return false; if (!wallpaper->start()) {
return false;
}
} }
m_screenPlayWallpapers.append(wallpaper); m_screenPlayWallpapers.append(wallpaper);
m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex); m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex);
@ -254,6 +284,15 @@ bool ScreenPlayManager::removeAllWallpapers()
return false; 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(); emit requestSaveProfiles();
@ -341,7 +380,7 @@ bool ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q
*/ */
bool ScreenPlayManager::setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode) bool ScreenPlayManager::setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode)
{ {
const auto fillModeTyped = static_cast<FillMode::FillMode>(fillmode); const auto fillModeTyped = static_cast<FillMode::FillMode>(fillmode);
if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) {
return setWallpaperValue(*appID, "fillmode", QVariant::fromValue<FillMode::FillMode>(fillModeTyped).toString()); return setWallpaperValue(*appID, "fillmode", QVariant::fromValue<FillMode::FillMode>(fillModeTyped).toString());
@ -445,6 +484,8 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID)
return false; 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(); qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber();

View File

@ -183,6 +183,7 @@ private:
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
std::unique_ptr<QLocalServer> m_server; std::unique_ptr<QLocalServer> m_server;
std::unique_ptr<QWebSocketServer> m_websocketServer; std::unique_ptr<QWebSocketServer> m_websocketServer;
QVector<QWebSocket*> m_connections;
QVector<std::shared_ptr<ScreenPlayWallpaper>> m_screenPlayWallpapers; QVector<std::shared_ptr<ScreenPlayWallpaper>> m_screenPlayWallpapers;
QVector<std::shared_ptr<ScreenPlayWidget>> m_screenPlayWidgets; QVector<std::shared_ptr<ScreenPlayWidget>> m_screenPlayWidgets;

View File

@ -24,7 +24,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
const FillMode::FillMode fillMode, const FillMode::FillMode fillMode,
const InstalledType::InstalledType type, const InstalledType::InstalledType type,
const QJsonObject& properties, const QJsonObject& properties,
const bool checkWallpaperVisible, const std::shared_ptr<Settings>& settings,
QObject* parent) QObject* parent)
: QObject(parent) : QObject(parent)
, m_globalVariables { globalVariables } , m_globalVariables { globalVariables }
@ -37,6 +37,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
, m_file { file } , m_file { file }
, m_volume { volume } , m_volume { volume }
, m_playbackRate { playbackRate } , m_playbackRate { playbackRate }
, m_settings { settings }
{ {
QJsonObject projectSettingsListModelProperties; QJsonObject projectSettingsListModelProperties;
@ -81,7 +82,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
QString::number(static_cast<double>(volume)), QString::number(static_cast<double>(volume)),
QVariant::fromValue(fillMode).toString(), QVariant::fromValue(fillMode).toString(),
QVariant::fromValue(type).toString(), QVariant::fromValue(type).toString(),
QString::number(checkWallpaperVisible), QString::number(m_settings->checkWallpaperVisible()),
// Fixes issue 84 media key overlay // Fixes issue 84 media key overlay
" --disable-features=HardwareMediaKeyHandling" " --disable-features=HardwareMediaKeyHandling"
}; };
@ -145,10 +146,9 @@ void ScreenPlayWallpaper::close()
return; return;
} }
if(m_connection->close()){ if (m_connection->close()) {
m_isExiting = true; m_isExiting = true;
} }
} }
/*! /*!
\brief Prints the exit code if != 0. \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) bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save)
{ {
if(m_isExiting) if (m_isExiting)
return false; return false;
if (!m_connection) { if (!m_connection) {
@ -249,7 +249,7 @@ void ScreenPlayWallpaper::replace(
const bool checkWallpaperVisible) const bool checkWallpaperVisible)
{ {
if(m_isExiting) if (m_isExiting)
return; return;
if (!m_connection) { if (!m_connection) {

View File

@ -44,6 +44,7 @@
#include "globalvariables.h" #include "globalvariables.h"
#include "projectsettingslistmodel.h" #include "projectsettingslistmodel.h"
#include "sdkconnection.h" #include "sdkconnection.h"
#include "settings.h"
#include "util.h" #include "util.h"
namespace ScreenPlay { namespace ScreenPlay {
@ -78,10 +79,12 @@ public:
const QString& absolutePath, const QString& absolutePath,
const QString& previewImage, const QString& previewImage,
const QString& file, const QString& file,
const float volume, const float playbackRate, const float volume,
const float playbackRate,
const FillMode::FillMode fillMode, const FillMode::FillMode fillMode,
const InstalledType::InstalledType type, const QJsonObject& properties, const InstalledType::InstalledType type,
const bool checkWallpaperVisible, const QJsonObject& properties,
const std::shared_ptr<Settings>& settings,
QObject* parent = nullptr); QObject* parent = nullptr);
bool start(); bool start();
@ -124,6 +127,7 @@ signals:
void volumeChanged(float volume); void volumeChanged(float volume);
void isLoopingChanged(bool isLooping); void isLoopingChanged(bool isLooping);
void playbackRateChanged(float playbackRate); void playbackRateChanged(float playbackRate);
void messageKDECloseWallpaper();
void requestSave(); void requestSave();
void requestClose(const QString& appID); void requestClose(const QString& appID);
@ -241,6 +245,7 @@ public slots:
private: private:
const std::shared_ptr<GlobalVariables> m_globalVariables; const std::shared_ptr<GlobalVariables> m_globalVariables;
std::unique_ptr<SDKConnection> m_connection; std::unique_ptr<SDKConnection> m_connection;
const std::shared_ptr<Settings> m_settings;
ProjectSettingsListModel m_projectSettingsListModel; ProjectSettingsListModel m_projectSettingsListModel;
QVector<int> m_screenNumber; QVector<int> m_screenNumber;
@ -256,9 +261,9 @@ private:
float m_playbackRate { 1.0f }; float m_playbackRate { 1.0f };
QTimer m_pingAliveTimer; QTimer m_pingAliveTimer;
QStringList m_appArgumentsList; QStringList m_appArgumentsList;
bool m_isConnected { false }; bool m_isConnected { false };
// There are still cases where we can access the current item // There are still cases where we can access the current item
// while exiting. This flag is to ignore all setWallpaperValue calls // while exiting. This flag is to ignore all setWallpaperValue calls
bool m_isExiting { false }; bool m_isExiting { false };
}; };
} }

View File

@ -108,7 +108,7 @@ bool ScreenPlay::SDKConnection::sendMessage(const QByteArray& message)
*/ */
bool ScreenPlay::SDKConnection::close() bool ScreenPlay::SDKConnection::close()
{ {
if (!m_socket){ if (!m_socket) {
qWarning() << "Cannot close invalid socket."; qWarning() << "Cannot close invalid socket.";
return false; return false;
} }

View File

@ -34,10 +34,14 @@ set(HEADER
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER}) add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER})
qt_add_qml_module(${PROJECT_NAME} qt_add_qml_module(
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/SysInfo ${PROJECT_NAME}
URI ${PROJECT_NAME} OUTPUT_DIRECTORY
VERSION 1.0) ${CMAKE_BINARY_DIR}/bin/SysInfo
URI
${PROJECT_NAME}
VERSION
1.0)
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)

View File

@ -12,8 +12,10 @@ find_package(
set(SOURCES # cmake-format: sortable set(SOURCES # cmake-format: sortable
src/util.cpp src/contenttypes.cpp inc/public/ScreenPlayUtil/httpfileserver.cpp) src/util.cpp src/contenttypes.cpp inc/public/ScreenPlayUtil/httpfileserver.cpp)
set(HEADER # cmake-format: sortable set(HEADER
inc/public/ScreenPlayUtil/util.h inc/public/ScreenPlayUtil/httpfileserver.h inc/public/ScreenPlayUtil/contenttypes.h inc/public/ScreenPlayUtil/projectfile.h) # 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}) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADER})

View File

@ -68,6 +68,11 @@ target_link_libraries(
Qt6::WebEngineCore Qt6::WebEngineCore
Qt6::WebEngineQuick) 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) if(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) 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") target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")

View File

@ -6,6 +6,8 @@ Will not work because KDE uses the kpluginindex.json (that is actually a bz2 fil
#### Installation #### Installation
``` ```
sudo apt install qml-module-qt-websockets qtwebengine5-*
plasmapkg2 --install ScreenPlay plasmapkg2 --install ScreenPlay
``` ```
@ -21,3 +23,6 @@ Because Wallpaper and Widgets are already a different application we can extend
1. Open Desktop Settings 1. Open Desktop Settings
- Select Wallpaper type ScreenPlay - Select Wallpaper type ScreenPlay
```
plasmapkg2 --upgrade ScreenPlay ; kquitapp5 plasmashell; kstart5 plasmashell
```

View File

@ -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()
}
}
}
}
}

View File

@ -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
}
}

View File

@ -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"
}
}

View File

@ -1,13 +1,14 @@
import QtQuick import QtQuick 2.11
import QtQuick.Controls as QQC import QtQuick.Controls 2.4 as QQC
import QtQuick.Window import QtQuick.Window 2.0
import Qt5Compat.GraphicalEffects import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
import org.kde.kcm 1.1 as KCM import org.kde.kcm 1.1 as KCM
import org.kde.kirigami 2.4 as Kirigami import org.kde.kirigami 2.4 as Kirigami
import org.kde.newstuff 1.1 as NewStuff import org.kde.newstuff 1.1 as NewStuff
Column { Column {
id: root id: root

View File

@ -1,100 +1,115 @@
import QtQuick import QtQuick 2.0
import Qt5Compat.GraphicalEffects import QtQuick.Controls 2.12
import QtQuick.Window import QtWebSockets 1.1
import Qt.WebSockets 1.15 import QtWebEngine 1.8
import QtWebEngine import QtMultimedia 5.12
import Qt.labs.settings 1.1
Rectangle { Rectangle {
id: root id:root
color:"orange"
property bool connected: false
property string fullContentPath Settings {
property real volume: 1 id:settings
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;
} }
color: "#333333"
Component.onCompleted: { Component.onCompleted: {
WebEngine.settings.localContentCanAccessFileUrls = true; wallpaper.projectSourceFileAbsolute = settings.value("SP_projectSourceFileAbsolute","NULL")
WebEngine.settings.localContentCanAccessRemoteUrls = true; // if(root.projectSourceFileAbsolute === "NULL")
WebEngine.settings.allowRunningInsecureContent = true; // return
WebEngine.settings.accelerated2dCanvasEnabled = true;
WebEngine.settings.javascriptCanOpenWindows = false; wallpaper.type = settings.value("SP_type")
WebEngine.settings.showScrollBars = false; wallpaper.fillMode = settings.value("SP_fillMode")
WebEngine.settings.playbackRequiresUserGesture = false; wallpaper.volume = settings.value("SP_volume")
WebEngine.settings.focusOnNavigationEnabled = true; 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 { WebSocket {
id: socket id: socket
url: "ws://127.0.0.1:16395" url: "ws://127.0.0.1:16395"
active: true
onStatusChanged: { onStatusChanged: {
if (socket.status === WebSocket.Error) if (socket.status === WebSocket.Open)
messageBox.text = "Error: " + socket.errorString; socket.sendTextMessage("Hello World from QML wallpaper")
else if (socket.status === WebSocket.Open)
socket.sendTextMessage("Hello World");
else if (socket.status === WebSocket.Closed)
messageBox.text += "Socket closed";
} }
onTextMessageReceived: {
var obj = JSON.parse(message); onTextMessageReceived: (message)=> {
var obj = JSON.parse(message)
root.connected = true
txtCommand.text = obj.command
if (obj.command === "replace") { if (obj.command === "replace") {
root.type = obj.type; socket.sendTextMessage("replace")
root.fillMode = obj.fillMode; wallpaper.type = obj.type
root.volume = obj.volume; wallpaper.fillMode = obj.fillMode
root.fullContentPath = obj.absolutePath + "/" + obj.file; wallpaper.volume = obj.volume
webView.setVideo(); wallpaper.projectSourceFileAbsolute = "file://" + obj.absolutePath + "/" + obj.file
} print("got: " + root.projectSourceFileAbsolute)
wallpaper.play()
return;
}
if(obj.command === "quit"){
wallpaper.stop()
}
} }
} }
// WaitingForScreenplay {
WebEngineView { // anchors.fill: parent
id: webView // visible: !root.connected
// }
function setVideo() { Column {
webView.runJavaScript(root.getSetVideoCommand()); 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 { Text {
id: messageBox id:txtCommand
color: "white"
text: qsTr("text") }
anchors.centerIn: parent Text {
color: "white"
text:wallpaper.type + wallpaper.projectSourceFileAbsolute
}
Text {
color: "white"
text:"Actitve: " +socket.active +" status: "+ socket.status + " reconnectTimer.retryCounter : "+ reconnectTimer.retryCounter
} }
} }
} }

View File

@ -3,6 +3,7 @@ Encoding=UTF-8
Name=ScreenPlay Name=ScreenPlay
Keywords=ScreenPlay Keywords=ScreenPlay
Icon=preferences-desktop-wallpaper Icon=preferences-desktop-wallpaper
Version=0.15.0
Type=Service Type=Service

View File

@ -46,24 +46,9 @@ LinuxWindow::LinuxWindow(
setHeight(m_window.height()); setHeight(m_window.height());
m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView);
m_window.rootContext()->setContextProperty("window", this); qmlRegisterSingletonInstance<LinuxWindow>("ScreenPlayWallpaper", 1, 0, "Wallpaper", this);
//m_window.rootContext()->setContextProperty("desktopProperties", &m_windowsDesktopProperties);
// Instead of setting "renderType: Text.NativeRendering" every time
// we can set it here once :)
m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering);
m_window.setSource(QUrl("qrc:/mainWindow.qml")); m_window.setSource(QUrl("qrc:/ScreenPlayWallpaper/qml/Wallpaper.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"));
} }
void LinuxWindow::setupWallpaperForOneScreen(int activeScreen) void LinuxWindow::setupWallpaperForOneScreen(int activeScreen)

View File

@ -320,7 +320,7 @@ void WinWindow::setupWallpaperForAllScreens()
m_window.setHeight(rect.height()); m_window.setHeight(rect.height());
m_window.setWidth(rect.width()); m_window.setWidth(rect.width());
m_window.setY(offsetY); m_window.setY(offsetY);
m_window.setX(offsetX+1920); m_window.setX(offsetX + 1920);
qInfo() << m_window.geometry(); qInfo() << m_window.geometry();
} }

View File

@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 20)
find_package( find_package(
Qt6 Qt6
COMPONENTS Quick QML Widgets Gui COMPONENTS Quick Widgets Gui
REQUIRED) REQUIRED)
set(SOURCES set(SOURCES
@ -58,24 +58,27 @@ qt_add_qml_module(
${PROJECT_NAME} ${PROJECT_NAME}
OUTPUT_DIRECTORY OUTPUT_DIRECTORY
${WORKSHOP_PLUGIN_DIR} ${WORKSHOP_PLUGIN_DIR}
URI "Workshop" URI
SOURCES ${SOURCES} ${HEADER} "Workshop"
VERSION 1.0) SOURCES
${SOURCES}
${HEADER}
VERSION
1.0)
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
if(APPLE) if(APPLE)
file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR}) file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
file(MAKE_DIRECTORY ${MACOS_FRAMEWORKS_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(${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(${STEAM_BIN} ${WORKSHOP_PLUGIN_DIR} COPYONLY)
set_target_properties(${PROJECT_NAME} PROPERTIES set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop) ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop)
else() else()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt 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) configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY)
endif() endif()
endif() endif()

View File

@ -49,9 +49,7 @@ set(HEADER
public/steam/steamnetworkingtypes.h public/steam/steamnetworkingtypes.h
public/steam/steamps3params.h public/steam/steamps3params.h
public/steam/steamtypes.h public/steam/steamtypes.h
public/steam/steamuniverse.h public/steam/steamuniverse.h)
)
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
add_library(${PROJECT_NAME} STATIC ${HEADER}) add_library(${PROJECT_NAME} STATIC ${HEADER})
@ -59,8 +57,8 @@ if(${SCREENPLAY_STEAM})
target_link_libraries(${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME})
endif() endif()
# We allaways need the generated enums as a workaround to register these enums in app.cpp. # We allaways need the generated enums as a workaround to register these enums in app.cpp. Registering in the ScreenPlayWorkshop plugin does
# Registering in the ScreenPlayWorkshop plugin does not work for some reason. # not work for some reason.
add_library(SteamSDKQtEnums STATIC public/steam/steam_qt_enums_generated.h) add_library(SteamSDKQtEnums STATIC public/steam/steam_qt_enums_generated.h)
target_include_directories(SteamSDKQtEnums PUBLIC public/) target_include_directories(SteamSDKQtEnums PUBLIC public/)
target_link_libraries(SteamSDKQtEnums PRIVATE Qt6::Core) target_link_libraries(SteamSDKQtEnums PRIVATE Qt6::Core)

View File

@ -88,10 +88,10 @@ void InstalledListModel::append(const QJsonObject& obj, const QString& folderNam
void InstalledListModel::loadInstalledContent() void InstalledListModel::loadInstalledContent()
{ {
if(m_loadContentFutureWatcher.isRunning()) if (m_loadContentFutureWatcher.isRunning())
return; return;
m_loadContentFuture = QtConcurrent::run([this]() { m_loadContentFuture = QtConcurrent::run([this]() {
QFileInfoList list = QDir(m_absoluteStoragePath.toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs); QFileInfoList list = QDir(m_absoluteStoragePath.toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
for (const auto& item : list) { for (const auto& item : list) {

View File

@ -103,16 +103,16 @@ public slots:
emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::UploadProgressRole) }); emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::UploadProgressRole) });
}); });
QObject::connect(item.get(), &SteamWorkshopItem::nameChanged, this, [this]() { QObject::connect(item.get(), &SteamWorkshopItem::nameChanged, this, [this]() {
emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::NameRole) }); emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::NameRole) });
}); });
QObject::connect(item.get(), &SteamWorkshopItem::absolutePreviewImagePathChanged, this, [this]() { QObject::connect(item.get(), &SteamWorkshopItem::absolutePreviewImagePathChanged, this, [this]() {
emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::AbsolutePreviewImagePath) }); emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::AbsolutePreviewImagePath) });
}); });
QObject::connect(item.get(), &SteamWorkshopItem::uploadComplete, this, [this](bool successful) { QObject::connect(item.get(), &SteamWorkshopItem::uploadComplete, this, [this](bool successful) {
emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::AbsolutePreviewImagePath) }); emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::AbsolutePreviewImagePath) });
}); });
QObject::connect(item.get(), &SteamWorkshopItem::statusChanged, this, [this](ScreenPlayWorkshopSteamEnums::EResult status) { QObject::connect(item.get(), &SteamWorkshopItem::statusChanged, this, [this](ScreenPlayWorkshopSteamEnums::EResult status) {
emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::Status) }); emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int> { static_cast<int>(UploadListModelRole::Status) });
// Check if all items are // Check if all items are

11
Tools/CMakeLists.txt Normal file
View File

@ -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")

View File

@ -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);
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Register a file extension</DisplayName>
<Description>Register a randomly generated file extension to open with notepad.exe</Description>
<Version>1.0.0-1</Version>
<ReleaseDate>2020-01-01</ReleaseDate>
<Default>true</Default>
<Script>installscript.qs</Script>
</Package>

View File

@ -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.") help="Enable if you want to sign the apps. This is macos only for now.")
parser.add_argument('-steam', action="store", dest="steam_build", parser.add_argument('-steam', action="store", dest="steam_build",
help="Enable if you want to build the Steam workshop plugin.") 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() args = parser.parse_args()
if not args.build_type: if not args.build_type:
print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True") print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True")
sys.exit(1) sys.exit(1)
qt_version = "6.2.1" qt_version = "6.2.2"
steam_build = "OFF" steam_build = "OFF"
build_tests = "OFF"
create_installer = "OFF"
if args.steam_build: 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" % print("Starting build with type %s. Qt Version: %s" %
(args.build_type, qt_version)) (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}" deploy_command = "{prefix_path}/bin/macdeployqt {app}.app -qmldir=../../{app}/qml -executable={app}.app/Contents/MacOS/{app}"
cmake_target_triplet = "x64-osx" cmake_target_triplet = "x64-osx"
elif platform == "linux": 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_prefix_path = "~/Qt/" + qt_version + "/gcc_64"
cmake_target_triplet = "x64-linux" cmake_target_triplet = "x64-linux"
@ -98,7 +109,6 @@ if os.path.isdir(build_folder):
print("Remove previous build folder: " + build_folder) print("Remove previous build folder: " + build_folder)
shutil.rmtree(build_folder) shutil.rmtree(build_folder)
os.mkdir(build_folder) os.mkdir(build_folder)
os.chdir(build_folder) os.chdir(build_folder)
@ -107,8 +117,9 @@ cmake_configure_command = """cmake ../
-DCMAKE_BUILD_TYPE={type} -DCMAKE_BUILD_TYPE={type}
-DCMAKE_TOOLCHAIN_FILE={toolchain} -DCMAKE_TOOLCHAIN_FILE={toolchain}
-DVCPKG_TARGET_TRIPLET={triplet} -DVCPKG_TARGET_TRIPLET={triplet}
-DTESTS_ENABLED=OFF
-DSCREENPLAY_STEAM={steam} -DSCREENPLAY_STEAM={steam}
-DSCREENPLAY_TESTS={tests}
-DSCREENPLAY_CREATE_INSTALLER={installer}
-G "CodeBlocks - Ninja" -G "CodeBlocks - Ninja"
-B. -B.
""".format( """.format(
@ -116,7 +127,10 @@ cmake_configure_command = """cmake ../
prefix_path=cmake_prefix_path, prefix_path=cmake_prefix_path,
triplet=cmake_target_triplet, triplet=cmake_target_triplet,
toolchain=cmake_toolchain_file, 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_configure_command)
execute("cmake --build . --target all") 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) full_file_path = os.path.join(os.getcwd(), filename)
print("Remove: %s" % full_file_path) print("Remove: %s" % full_file_path)
os.remove(full_file_path) os.remove(full_file_path)
if args.create_installer:
os.chdir("..")
execute("cpack")

View File

@ -31,7 +31,7 @@ if __name__ == "__main__":
vcpkg_path = os.path.join(project_source_parent_path, "ScreenPlay-vcpkg") vcpkg_path = os.path.join(project_source_parent_path, "ScreenPlay-vcpkg")
print("vcpkg_path: ", vcpkg_path) print("vcpkg_path: ", vcpkg_path)
vcpkg_version = "9172179c513aa84308e48b8dd0e3df90acec7204" # Master 25.06.2021 vcpkg_version = "5ddd7f0" # Master 02.12.2021
print("Build vcpkg ", vcpkg_version) print("Build vcpkg ", vcpkg_version)
execute("git fetch", vcpkg_path) execute("git fetch", vcpkg_path)
execute("git checkout {}".format(vcpkg_version), vcpkg_path) execute("git checkout {}".format(vcpkg_version), vcpkg_path)
@ -41,7 +41,6 @@ if __name__ == "__main__":
"curl", "curl",
"sentry-native", "sentry-native",
"doctest", "doctest",
"benchmark",
"cpp-httplib" "cpp-httplib"
] ]