diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9d76abf2..0f4ff40f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -88,7 +88,9 @@ build:linux_debug: - check script: - sudo apt-get update -y - - sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common -y + - sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common snapd -y + - systemctl start snapd.service + - sudo snap install cqtdeployer - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null - sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic-rc main' -y - sudo apt-get update -y @@ -112,12 +114,14 @@ build:linux_release: - check script: - sudo apt-get update -y - - sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common -y + - sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common snapd -y + - systemctl start snapd.service + - sudo snap install cqtdeployer - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null - sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic-rc main' -y - sudo apt-get update -y - sudo apt install build-essential libgl1-mesa-dev lld ninja-build cmake -y - - cd Tools + - cd Tools - python build.py -t release artifacts: expire_in: '4 weeks' diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index 1bf5ef68..120c1492 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -7,7 +7,13 @@ set(CMAKE_AUTOMOC ON) find_package( Qt5 - COMPONENTS Quick QuickCompiler Widgets Gui WebEngine LinguistTools + COMPONENTS Quick + QuickCompiler + Widgets + Gui + WebEngine + LinguistTools + WebSockets REQUIRED) find_package(OpenSSL REQUIRED) @@ -96,6 +102,7 @@ target_link_libraries( Qt5::Widgets Qt5::Core Qt5::WebEngine + Qt5::WebSockets ScreenPlaySDK benchmark::benchmark benchmark::benchmark_main diff --git a/ScreenPlay/Resources.qrc b/ScreenPlay/Resources.qrc index db9433d4..9525df18 100644 --- a/ScreenPlay/Resources.qrc +++ b/ScreenPlay/Resources.qrc @@ -107,7 +107,6 @@ assets/images/mask.svg assets/images/mask_workshop.png assets/images/Untitled.png - assets/images/window.svg translations/ScreenPlay_zh_cn.qm translations/ScreenPlay_de.qm translations/ScreenPlay_en.qm diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index 6e6e9fc9..0904cd8f 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -19,7 +19,6 @@ namespace ScreenPlay { ScreenPlayManager::ScreenPlayManager( QObject* parent) : QObject { parent } - , m_server { std::make_unique() } { if (checkIsAnotherScreenPlayInstanceRunning()) { @@ -27,6 +26,8 @@ ScreenPlayManager::ScreenPlayManager( return; } + m_server = std::make_unique(); + QObject::connect(m_server.get(), &QLocalServer::newConnection, this, &ScreenPlayManager::newConnection); m_server->setSocketOptions(QLocalServer::WorldAccessOption); if (!m_server->listen("ScreenPlay")) { @@ -76,6 +77,16 @@ void ScreenPlayManager::init( m_monitorListModel = mlm; m_telemetry = telemetry; m_settings = settings; + + if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { + m_websocketServer = std::make_unique(QStringLiteral("ScreenPlayWebSocket"), QWebSocketServer::SslMode::NonSecureMode); + m_websocketServer->listen(QHostAddress::Any, m_webSocketPort); + QObject::connect(m_websocketServer.get(), &QWebSocketServer::newConnection, this, [this]() { + qInfo() << "New Websocket Connection"; + auto* socket = m_websocketServer->nextPendingConnection(); + }); + } + loadProfiles(); } @@ -388,7 +399,7 @@ void ScreenPlayManager::newConnection() */ void ScreenPlayManager::closeAllWallpapers() { - if(m_screenPlayWallpapers.empty() && m_activeWallpaperCounter == 0) + if (m_screenPlayWallpapers.empty() && m_activeWallpaperCounter == 0) return; closeConntectionByType(GlobalVariables::getAvailableWallpaper()); @@ -405,7 +416,7 @@ void ScreenPlayManager::closeAllWallpapers() */ void ScreenPlayManager::closeAllWidgets() { - if(m_screenPlayWidgets.empty() && m_activeWidgetsCounter == 0) + if (m_screenPlayWidgets.empty() && m_activeWidgetsCounter == 0) return; closeConntectionByType(GlobalVariables::getAvailableWidgets()); diff --git a/ScreenPlay/src/screenplaymanager.h b/ScreenPlay/src/screenplaymanager.h index c934e065..40a8a5f2 100644 --- a/ScreenPlay/src/screenplaymanager.h +++ b/ScreenPlay/src/screenplaymanager.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "ganalytics.h" #include "globalvariables.h" @@ -199,6 +200,7 @@ private: std::shared_ptr m_telemetry; std::shared_ptr m_settings; std::unique_ptr m_server; + std::unique_ptr m_websocketServer; QVector> m_screenPlayWallpapers; QVector> m_screenPlayWidgets; @@ -208,6 +210,8 @@ private: bool m_isAnotherScreenPlayInstanceRunning = false; QTimer m_saveLimiter; + + const quint16 m_webSocketPort = 16395; }; } diff --git a/ScreenPlay/src/sdkconnection.h b/ScreenPlay/src/sdkconnection.h index 804777b4..6e2dffd9 100644 --- a/ScreenPlay/src/sdkconnection.h +++ b/ScreenPlay/src/sdkconnection.h @@ -44,6 +44,7 @@ #include #include #include +#include #include diff --git a/ScreenPlay/src/settings.cpp b/ScreenPlay/src/settings.cpp index 5bfe5364..0bed95cb 100644 --- a/ScreenPlay/src/settings.cpp +++ b/ScreenPlay/src/settings.cpp @@ -40,6 +40,7 @@ Settings::Settings(const std::shared_ptr& globalVariables, qRegisterMetaType("Settings::Language"); qRegisterMetaType("Settings::Theme"); + qRegisterMetaType("Settings::DesktopEnvironment"); qmlRegisterUncreatableType("Settings", 1, 0, "Settings", "Error only for enums"); @@ -119,6 +120,19 @@ Settings::Settings(const std::shared_ptr& globalVariables, setupWidgetAndWindowPaths(); setGitBuildHash(COMPILE_INFO); + +#ifdef Q_OS_WIN + setDesktopEnvironment(DesktopEnvironment::Windows); +#endif + +#ifdef Q_OS_OSX + setDesktopEnvironment(DesktopEnvironment::OSX); +#endif + +#ifdef Q_OS_LINUX + // We only support KDE for now + setDesktopEnvironment(DesktopEnvironment::KDE); +#endif } /*! diff --git a/ScreenPlay/src/settings.h b/ScreenPlay/src/settings.h index a4574ecd..f66a2fda 100644 --- a/ScreenPlay/src/settings.h +++ b/ScreenPlay/src/settings.h @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ class Settings : public QObject { Q_PROPERTY(bool steamVersion READ steamVersion WRITE setSteamVersion NOTIFY steamVersionChanged) Q_PROPERTY(ScreenPlay::FillMode::FillMode videoFillMode READ videoFillMode WRITE setVideoFillMode NOTIFY videoFillModeChanged) + Q_PROPERTY(DesktopEnvironment desktopEnvironment READ desktopEnvironment WRITE setDesktopEnvironment NOTIFY desktopEnvironmentChanged) Q_PROPERTY(Language language READ language WRITE setLanguage NOTIFY languageChanged) Q_PROPERTY(Theme theme READ theme WRITE setTheme NOTIFY themeChanged) @@ -96,6 +98,21 @@ public: const std::shared_ptr& globalVariables, QObject* parent = nullptr); + enum class DesktopEnvironment { + Unknown, + OSX, + Windows, + Cinnamon, + Enlightenment, + Gnome, + KDE, + Lxde, + Lxqt, + Mate, + Unity, + XFCE, + }; + enum class Language { En, De, @@ -188,6 +205,11 @@ public: return m_steamVersion; } + DesktopEnvironment desktopEnvironment() const + { + return m_desktopEnvironment; + } + signals: void requestRetranslation(); void resetInstalledListmodel(); @@ -206,8 +228,8 @@ signals: void languageChanged(ScreenPlay::Settings::Language language); void fontChanged(QString font); void themeChanged(ScreenPlay::Settings::Theme theme); - void steamVersionChanged(bool steamVersion); + void desktopEnvironmentChanged(DesktopEnvironment desktopEnvironment); public slots: void writeJsonFileFromResource(const QString& filename); @@ -397,6 +419,15 @@ public slots: emit steamVersionChanged(m_steamVersion); } + void setDesktopEnvironment(DesktopEnvironment desktopEnvironment) + { + if (m_desktopEnvironment == desktopEnvironment) + return; + + m_desktopEnvironment = desktopEnvironment; + emit desktopEnvironmentChanged(m_desktopEnvironment); + } + private: void restoreDefault(const QString& appConfigLocation, const QString& settingsFileType); @@ -420,5 +451,6 @@ private: Theme m_theme { Theme::System }; QString m_font { "Roboto" }; bool m_steamVersion { false }; + DesktopEnvironment m_desktopEnvironment = DesktopEnvironment::Unknown; }; } diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index 3cab342e..1ee0b944 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -78,7 +78,7 @@ void ScreenPlaySDK::disconnected() void ScreenPlaySDK::readyRead() { QString tmp = m_socket.readAll(); - QJsonParseError err; + QJsonParseError err{}; auto doc = QJsonDocument::fromJson(QByteArray::fromStdString(tmp.toStdString()), &err); if (!(err.error == QJsonParseError::NoError)) { diff --git a/ScreenPlayWallpaper/SPWResources.qrc b/ScreenPlayWallpaper/SPWResources.qrc index f044004e..498a63df 100644 --- a/ScreenPlayWallpaper/SPWResources.qrc +++ b/ScreenPlayWallpaper/SPWResources.qrc @@ -1,7 +1,7 @@ Wallpaper.qml - test.qml + Test.qml dot.png qtquickcontrols2.conf WebView.qml diff --git a/ScreenPlayWallpaper/test.qml b/ScreenPlayWallpaper/Test.qml similarity index 100% rename from ScreenPlayWallpaper/test.qml rename to ScreenPlayWallpaper/Test.qml diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/README.md b/ScreenPlayWallpaper/kde/ScreenPlay/README.md new file mode 100644 index 00000000..2eb20a60 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/README.md @@ -0,0 +1,13 @@ +# ScreenPlay Wallpaper for KDE Plasma Desktop + +One has to install it via the command below. Simply putting it into: +* ~/.local/share/plasma/wallpapers/ +Will not work because KDE uses the kpluginindex.json (that is actually a bz2 file. Do not ask why...) to load all available wallpaper. + +#### Installation +``` +plasmapkg2 --install ScreenPlay +``` + +#### Application structure +Because Wallpaper and Widgets are already a different application we can extend the logic for KDE. For this we create a local websocket instance to communicate with our main ScreenPlay app. diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/config/main.xml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/config/main.xml new file mode 100644 index 00000000..32877480 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/config/main.xml @@ -0,0 +1,15 @@ + + + + + + + + false + + + + diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml new file mode 100644 index 00000000..666a6da2 --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml @@ -0,0 +1,32 @@ +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 + anchors.fill:parent + + property alias cfg_StopWallpaperIfHidden: stopWallpaperIfHidden.checked + spacing: units.largeSpacing + + Row { + anchors.horizontalCenter: parent.horizontalCenter + spacing: units.largeSpacing + QQC.CheckBox { + id: stopWallpaperIfHidden + text: i18nd("plasma_applet_org.kde.image","Stop animation when a window is maximized"); + } + } + + + } + diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/index.html b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/index.html new file mode 100644 index 00000000..717a664d --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/index.html @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml new file mode 100644 index 00000000..d9ebd91f --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml @@ -0,0 +1,91 @@ +import QtQuick 2.11 +import QtGraphicalEffects 1.0 +import QtQuick.Window 2.0 +import Qt.WebSockets 1.15 +import QtWebEngine 1.8 + +Rectangle { + id: root + color: "#333333" + property string fullContentPath + property real volume: 1.0 + property string fillMode: "Cover" + property string type + + WebSocket { + id: socket + url: "ws://127.0.0.1:16395" + active: true + onTextMessageReceived: { + var obj = JSON.parse(message) + if (obj.command === "replace") { + root.type = obj.type + root.fillMode = obj.fillMode + root.volume = obj.volume + root.fullContentPath = obj.absolutePath + "/" + obj.file + webView.setVideo() + } + } + 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" + } + } + 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 + } + + 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 + } + + WebEngineView { + id: webView + anchors.fill: parent + opacity: loadProgress === 100 ? 1 : 0 + onLoadProgressChanged: { + if (loadProgress === 100) + setVideo() + } + + function setVideo() { + webView.runJavaScript(root.getSetVideoCommand()) + } + } + + Rectangle { + id: infoWrapper + width: 300 + height: 200 + opacity: 0 + anchors.centerIn: parent + + Text { + id: messageBox + text: qsTr("text") + anchors.centerIn: parent + } + } +} diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop new file mode 100644 index 00000000..84c6968d --- /dev/null +++ b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=ScreenPlay +Keywords=ScreenPlay +Icon=preferences-desktop-wallpaper + +Type=Service + +X-KDE-ServiceTypes=Plasma/Wallpaper +X-KDE-ParentApp= +X-KDE-PluginInfo-Name=ScreenPlay +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-PluginInfo-Version=3 +X-KDE-PluginInfo-Website=https://gitlab.com/kelteseth/screenplay + +X-Plasma-MainScript=ui/main.qml + +MimeType=image/gif;image/png;image/svg+xml;image/svg+xml-compressed;video/x-mng; +X-Plasma-DropMimeTypes=image/gif,image/png,image/svg+xml,image/svg+xml-compressed,video/x-mng diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 8031374c..bdaf6d64 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -20,7 +20,7 @@ BaseWindow::BaseWindow(QString projectFilePath, const QVector activeScreens if (projectFilePath == "test") { setType(BaseWindow::WallpaperType::Qml); - setFullContentPath("qrc:/test.qml"); + setFullContentPath("qrc:/Test.qml"); return; } diff --git a/Tools/build.py b/Tools/build.py index c889ca9b..b21fbeb2 100644 --- a/Tools/build.py +++ b/Tools/build.py @@ -36,14 +36,16 @@ print("Starting build with type %s. Qt Version: %s" % cmake_prefix_path = "" cmake_target_triplet = "" +cmake_build_type = "" executable_file_ending = "" -deploy_executable = "" +deploy_command = "" if platform == "win32": print("Loading MSVC env variables via vsvars32.bat") + cmake_build_type = args.build_type windows_msvc = "msvc2019_64" executable_file_ending = ".exe" - deploy_executable = "windeployqt.exe" + deploy_command = "windeployqt.exe --{type} --qmldir ../../{app}/qml {app}{executable_file_ending}" dict = vs_env_dict() dict["PATH"] = dict["PATH"] + ";C:\\Qt\\" + qt_version + "\\" + windows_msvc + "\\bin;C:\\Qt\\Tools\\QtCreator\\bin" os.environ.update(dict) @@ -52,18 +54,18 @@ if platform == "win32": os.system("install_dependencies_windows.bat") elif platform == "darwin": cmake_prefix_path = "~/Qt/" + qt_version + "/clang_64" - deploy_executable = "macdeployqt" + deploy_command = "macdeployqt --{type} --qmldir ../../{app}/qml {app}" cmake_target_triplet = "x64-osx" print("Executing install_dependencies_linux_mac.sh") os.system("chmod +x install_dependencies_linux_mac.sh") os.system("./install_dependencies_linux_mac.sh") elif platform == "linux": - deploy_executable = "linuxdeployqt" - cmake_prefix_path = "~/Qt/" + deploy_command = "cqtdeployer -qmldir ../../{app}/qml -bin {app}" + cmake_prefix_path = "~/Qt/" + qt_version + "/gcc_64" cmake_target_triplet = "x64-linux" print("Executing install_dependencies_linux_mac.sh") os.system("chmod +x install_dependencies_linux_mac.sh") - os.system("./install_dependencies_linux_mac.sh") + #os.system("./install_dependencies_linux_mac.sh") # REMOVE OLD BUILD FOLDER cwd = os.getcwd() @@ -105,20 +107,21 @@ if process.returncode != 0: os.system("cmake --build . --target all") os.chdir("bin") -os.system(("{deploy_executable} --{type} --qmldir ../../ScreenPlay/qml ScreenPlay{executable_file_ending}").format( - type=args.build_type, - executable_file_ending=executable_file_ending, - deploy_executable=deploy_executable)) +os.system((deploy_command).format( + type=cmake_build_type, + app="ScreenPlay", + executable_file_ending=executable_file_ending)) -os.system(("{deploy_executable} --{type} --qmldir ../../ScreenPlayWidget ScreenPlayWidget{executable_file_ending}").format( - type=args.build_type, - executable_file_ending=executable_file_ending, - deploy_executable=deploy_executable)) +os.system((deploy_command).format( + type=cmake_build_type, + app="ScreenPlayWidget", + executable_file_ending=executable_file_ending)) + +os.system((deploy_command).format( + type=cmake_build_type, + app="ScreenPlayWallpaper", + executable_file_ending=executable_file_ending)) -os.system(("{deploy_executable} --{type} --qmldir ../../ScreenPlayWallpaper ScreenPlayWallpaper{executable_file_ending}").format( - type=args.build_type, - executable_file_ending=executable_file_ending, - deploy_executable=deploy_executable)) file_endings = [".ninja_deps", ".ninja", ".ninja_log", ".lib", ".exp",