diff --git a/README.md b/README.md index ec938deb..cfc49dca 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ ScreenPlay [![pipeline status](https://gitlab.com/kelteseth/ScreenPlay/badges/master/pipeline.svg)](https://gitlab.com/kelteseth/ScreenPlay/-/commits/master)
Dev. Docs [![pipeline status](https://gitlab.com/kelteseth/ScreenPlayDeveloperDocs/badges/master/pipeline.svg)](https://gitlab.com/kelteseth/ScreenPlayDeveloperDocs/-/commits/master)

+ +[中文总览](README_zh_CN.md) +

![Twitter Follow](https://img.shields.io/twitter/follow/kelteseth?style=for-the-badge) ![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/screenplayapp?style=for-the-badge)

@@ -34,6 +37,11 @@ Windows only, Linux and MacOS (soon™)

Click gif to see the Steam Early Access Trailer (YouTube)

+# Important Issues +* [Support for Windows monitor scaling is currently buggy. All monitors must be set to 100%!](https://gitlab.com/kelteseth/ScreenPlay/-/issues/125) +* [Implement KDE Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111) +* [Implement MacOS Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130) + # Content Creation [Learn the basics of QML for Wallpapers and Widgets in 5 minutes](https://screen-play.app/blog/guide_learn_the_basics_of_qml/)
diff --git a/README_zh_CN.md b/README_zh_CN.md new file mode 100644 index 00000000..5b7fb763 --- /dev/null +++ b/README_zh_CN.md @@ -0,0 +1,126 @@ +
+ +
+ +
+ +
+ +ScreenPlay [![pipeline status](https://gitlab.com/kelteseth/ScreenPlay/badges/master/pipeline.svg)](https://gitlab.com/kelteseth/ScreenPlay/-/commits/master)
+开发文档 [![pipeline status](https://gitlab.com/kelteseth/ScreenPlayDeveloperDocs/badges/master/pipeline.svg)](https://gitlab.com/kelteseth/ScreenPlayDeveloperDocs/-/commits/master)

+![Twitter Follow](https://img.shields.io/twitter/follow/kelteseth?style=for-the-badge) +![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/screenplayapp?style=for-the-badge) +

+用户交流 (Discord,英语) +![Discord](https://img.shields.io/discord/516635043435773970?style=for-the-badge) +开发者交流(英语) [![Gitter](https://badges.gitter.im/ScreenPlayApp/community.svg)](https://gitter.im/ScreenPlayApp/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + + + +
+ScreenPlay 是一款开源、跨平台,显示视频壁纸,部件,应用抽屉的软件。它以现代的 C++20/Qt5/QML编写。 +带有创意工坊支持的二进制(在 Windows ,以及不久的 Linux 及 MacOSX 可用)可以通过Steam获取。加入我们(英语):首页 - 论坛 + +
+

✨通过Steam下载ScreenPlay - Steam 创意工坊,获取壁纸与部件✨

+仅支持Windows,Linux 和 MacOS 在做了 +
+
+ + + +![预览](.gitlab/media/preview.gif) + + +

点击gif,查看尽早访问预告片! (YouTube)

+
+ +# 重要议题 +* [对Windows显示器缩放的支持目前有问题。所有显示器必须被设为100%!](https://gitlab.com/kelteseth/ScreenPlay/-/issues/125) +* [KDE 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111) +* [MacOS 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130) + +# 内容创建 +[5分钟内学习QML基础(壁纸,部件)(English)](https://screen-play.app/blog/guide_learn_the_basics_of_qml/) +
+ +
+ +* [视频壁纸](https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/video_wallpaper/) - 您可以直接导入任何WebM文件, +或者使用导入工具导入任何其他视频类型。 +* [性能指南](https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/) - 流畅的播放需要您有一块现代的显卡。如果您遇到性能问题,您可以一直用 QML/HTML/GIF 壁纸! +* [通过Handbrake导入视频](https://forum.screen-play.app/topic/43/fast-bulk-video-conversion-with-handbrake)。 Handbrake 提供了方便的视频批量导入。 + +
+ +
+ + +* [部件引导](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/widgets/) - 通用引导,如何创建部件。 +ScreenPlay使用易于学习的 QML 语言。无需任何编程知识! +* [Storage Widget](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_Storage/). Display your drives and usage. +* [CPU 占用部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_CPU/) 显示您当前的CPU使用情况 +* [RSS订阅部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_RSS/) 以RSS部件显示新闻, + + +# 一般贡献 + +每个人都可以贡献代码,设计,文档以及翻译。更多信息见[贡献引导](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute)。也请查阅 [Collaboration Guidelines](Docs/CodeOfConduct.md). + +这里是一些您贡献的方式: +* 通过使用预发布版本/ master分支或者Steam每夜构建。 +* 通过 [添加/修复翻译](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/translations/) +* by [设计 UI/UX](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute/#design) +* by [创建示例 HTML/QML/Javascript 内容](https://kelteseth.gitlab.io/ScreenPlayDocs/) +* by [报告漏洞](https://gitlab.com/kelteseth/ScreenPlay/-/issues) +* by [编写用户文档](https://gitlab.com/kelteseth/ScreenPlayDocs) +* by [编写需要的功能](https://gitlab.com/kelteseth/ScreenPlay/-/issues?label_name%5B%5D=Feature) +* by [重构代码](https://gitlab.com/kelteseth/ScreenPlay/-/issues?label_name%5B%5D=Code+Quality) +* by [检阅合并请求](https://gitlab.com/kelteseth/ScreenPlay/-/merge_requests) +* by [验证Issue](https://gitlab.com/kelteseth/ScreenPlay/-/issues?label_name%5B%5D=Unverified) + +# Development +* [**Developer setup guide on how to download and compile ScreenPlay yourself.**](Docs/DeveloperSetup.md) + * If you want to contribute but don't know how to start, take a look at our open issues and WIP merge request. + * If you need help don't hesitate to ask me (Kelteseth) via: + * [Create a forum topic with a detailed description](https://forum.screen-play.app/category/2/general-discussion) + * [discord channel general](https://discord.gg/3RygPHZ) + * [ScreenPlay project overview](Docs/ProjectOverview.md) + * [Developer C++ Classes Documentation](https://kelteseth.gitlab.io/ScreenPlayDeveloperDocs/) + +# Platform support + +* ❌ Not working/Not implemented +* ❓ Only partially implemented/Not tested, help needed + +
+ +| 功能 | Windows | Linux | MacOS | +|------------------------ |--------- |------- |------- | +| __ScreenPlay 主程序__ | ✔ | ✔ | ✔ | +| __Steam 二进制__ | ✔ | ❌ | ❌ | +| __壁纸__ | ✔ | ❓ 需要帮助 Gnome/KDE 等! | ✔ | +| __部件__ | ✔ | ✔ | ✔ | +| __多语言 (EN,DE,RU,FR,ES,KO,VI,ZH_CN,PT_BR🆕)__ | ✔ | ✔ | ✔ | + +
+ +因为每个操作系统有它自己的桌面环境,我们需要分别适配 ScreenPlayWindow 到各个平台。 +目前功能最完好的是Windows 10。Windows 7下也可用,但有[错误的coordinates](https://gitlab.com/kelteseth/ScreenPlay/issues/34). MacOS has some basic wallpaper functionality but no maintainer. For Linux we sadly have no support for any desktop environments at the moment, except basic KDE support. + +__If you want to help and add new desktop environments look at ScreenPlayWallpaper/src folder__ + +* [BaseWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/basewindow.h) baseclass for: + * [LinuxWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/linuxwindow.h) + * [WinWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/winwindow.h) + * [MacWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/macwindow.h) + +
+ +| 平台 | Windows 10 | Gnome | KDE | MacOS | +|------------------------ |------- |--------- |------- | ------- | +| __壁纸__ | ✔ |❌ Help Needed! | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/tree/master/ScreenPlayWallpaper/kde/ScreenPlay) | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/blob/master/ScreenPlayWallpaper/src/MacBridge.mm) | + + +
+ diff --git a/ScreenPlay/app.cpp b/ScreenPlay/app.cpp index 97fb54d9..b648c9ea 100644 --- a/ScreenPlay/app.cpp +++ b/ScreenPlay/app.cpp @@ -54,7 +54,7 @@ App::App() QGuiApplication::setOrganizationName("ScreenPlay"); QGuiApplication::setOrganizationDomain("https://screen-play.app"); QGuiApplication::setApplicationName("ScreenPlay"); - QGuiApplication::setApplicationVersion("0.13.0"); + QGuiApplication::setApplicationVersion("0.13.1"); QGuiApplication::setQuitOnLastWindowClosed(false); QFontDatabase::addApplicationFont(":/assets/fonts/LibreBaskerville-Italic.ttf"); @@ -205,7 +205,12 @@ void App::init() // Must be called last to display a error message on startup by the qml engine m_screenPlayManager->init(m_globalVariables, m_monitorListModel, m_telemetry, m_settings); - QObject::connect(m_monitorListModel.get(), &MonitorListModel::monitorConfigurationChanged, m_screenPlayManager.get(), &ScreenPlayManager::closeAllWallpapers); + QObject::connect(m_monitorListModel.get(), &MonitorListModel::monitorConfigurationChanged, m_screenPlayManager.get(), &ScreenPlayManager::removeAllWallpapers); +} + +QString App::version() const +{ + return QGuiApplication::applicationVersion(); } /*! @@ -220,7 +225,7 @@ void App::exit() // Workaround because we cannot force to send exit event m_telemetry->setSendInterval(5); m_telemetry->endSession(); - QTimer::singleShot(150, []() { QApplication::instance()->quit(); }); + QTimer::singleShot(150, this, []() { QApplication::instance()->quit(); }); } } diff --git a/ScreenPlay/app.h b/ScreenPlay/app.h index 84f027f7..33ce1e40 100644 --- a/ScreenPlay/app.h +++ b/ScreenPlay/app.h @@ -92,60 +92,17 @@ public: void init(); bool m_isAnotherScreenPlayInstanceRunning { false }; - GlobalVariables* globalVariables() const - { - return m_globalVariables.get(); - } - - ScreenPlayManager* screenPlayManager() const - { - return m_screenPlayManager.get(); - } - - Create* create() const - { - return m_create.get(); - } - - Util* util() const - { - return m_util.get(); - } - - Settings* settings() const - { - return m_settings.get(); - } - - InstalledListModel* installedListModel() const - { - return m_installedListModel.get(); - } - - MonitorListModel* monitorListModel() const - { - return m_monitorListModel.get(); - } - - ProfileListModel* profileListModel() const - { - return m_profileListModel.get(); - } - - InstalledListFilter* installedListFilter() const - { - return m_installedListFilter.get(); - } - - QQmlApplicationEngine* mainWindowEngine() const - { - return m_mainWindowEngine.get(); - } - - Wizards* wizards() const - { - return m_wizards.get(); - } + GlobalVariables* globalVariables() const { return m_globalVariables.get(); } + ScreenPlayManager* screenPlayManager() const { return m_screenPlayManager.get(); } + Create* create() const { return m_create.get(); } + Util* util() const { return m_util.get(); } + Settings* settings() const { return m_settings.get(); } + InstalledListModel* installedListModel() const { return m_installedListModel.get(); } + MonitorListModel* monitorListModel() const { return m_monitorListModel.get(); } + ProfileListModel* profileListModel() const { return m_profileListModel.get(); } + InstalledListFilter* installedListFilter() const { return m_installedListFilter.get(); } + QQmlApplicationEngine* mainWindowEngine() const { return m_mainWindowEngine.get(); } + Wizards* wizards() const { return m_wizards.get(); } signals: void globalVariablesChanged(GlobalVariables* globalVariables); @@ -161,7 +118,7 @@ signals: void wizardsChanged(Wizards* wizards); public slots: - + QString version() const; void exit(); bool loadSteamPlugin(); bool unloadSteamPlugin(); diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index 18b535c5..ba4163b2 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -76,7 +76,6 @@ int main(int argc, char* argv[]) ScreenPlay::App app; - if (app.m_isAnotherScreenPlayInstanceRunning) { return 0; } else { diff --git a/ScreenPlay/main.qml b/ScreenPlay/main.qml index 01c508ab..39a41a11 100644 --- a/ScreenPlay/main.qml +++ b/ScreenPlay/main.qml @@ -24,7 +24,7 @@ ApplicationWindow { visible: false width: 1400 height: 788 - title: "ScreenPlay Alpha - 0.13.0" + title: "ScreenPlay Alpha - " + ScreenPlay.version(); minimumHeight: 450 minimumWidth: 1050 onVisibilityChanged: { diff --git a/ScreenPlay/qml/Community/Community.qml b/ScreenPlay/qml/Community/Community.qml index ee19f878..947dfbc3 100644 --- a/ScreenPlay/qml/Community/Community.qml +++ b/ScreenPlay/qml/Community/Community.qml @@ -105,6 +105,9 @@ Item { id: repeater model: ListModel { id: webModel + ListElement { + url: "https://screen-play.app/blog/" + } ListElement { url: "https://kelteseth.gitlab.io/ScreenPlayDocs/" } @@ -142,4 +145,10 @@ Item { } } } + + Binding{ + target: nav + property: "currentIndex" + value: swipeView.currentIndex + } } diff --git a/ScreenPlay/qml/Monitors/Monitors.qml b/ScreenPlay/qml/Monitors/Monitors.qml index feb88580..091dc56c 100644 --- a/ScreenPlay/qml/Monitors/Monitors.qml +++ b/ScreenPlay/qml/Monitors/Monitors.qml @@ -98,14 +98,12 @@ Popup { if (installedType === InstalledType.VideoWallpaper) { videoControlWrapper.state = "visible" customPropertiesGridView.visible = false - const wallpaper = ScreenPlay.screenPlayManager.getWallpaperByAppID( - appID) + const wallpaper = ScreenPlay.screenPlayManager.getWallpaperByAppID(appID) videoControlWrapper.wallpaper = wallpaper } else { videoControlWrapper.state = "hidden" customPropertiesGridView.visible = true - ScreenPlay.screenPlayManager.requestProjectSettingsAtMonitorIndex( - index) + ScreenPlay.screenPlayManager.requestProjectSettingsAtMonitorIndex(index) } activeMonitorIndex = index @@ -135,8 +133,10 @@ Popup { font.family: ScreenPlay.settings.font enabled: monitorSelection.activeMonitors.length == 1 onClicked: { - ScreenPlay.screenPlayManager.removeWallpaperAt( - monitorSelection.activeMonitors[0]) + if (!ScreenPlay.screenPlayManager.removeWallpaperAt( + monitorSelection.activeMonitors[0])) { + print("Unable to close singel wallpaper") + } } } Button { @@ -149,21 +149,26 @@ Popup { font.family: ScreenPlay.settings.font enabled: ScreenPlay.screenPlayManager.activeWallpaperCounter > 0 onClicked: { - ScreenPlay.screenPlayManager.removeAllWallpapers() + if (!ScreenPlay.screenPlayManager.removeAllWallpapers()) { + print("Unable to close all wallpaper!") + } + monitors.close() } } Button { id: btnRemoveAllWidgets text: qsTr("Remove ") - + ScreenPlay.screenPlayManager.activeWidgetsCounter + " " + qsTr( - "Widgets") + + ScreenPlay.screenPlayManager.activeWidgetsCounter + " " + qsTr("Widgets") Material.background: Material.accent Material.foreground: "white" font.family: ScreenPlay.settings.font enabled: ScreenPlay.screenPlayManager.activeWidgetsCounter > 0 onClicked: { - ScreenPlay.screenPlayManager.removeAllWidgets() + if (!ScreenPlay.screenPlayManager.removeAllWidgets()) { + print("Unable to close all widgets!") + } + monitors.close() } } diff --git a/ScreenPlay/src/create.h b/ScreenPlay/src/create.h index f605c86d..e4c87638 100644 --- a/ScreenPlay/src/create.h +++ b/ScreenPlay/src/create.h @@ -84,20 +84,11 @@ public: }; Q_ENUM(VideoCodec) - float progress() const - { - return m_progress; - } + float progress() const { return m_progress; } - QString workingDir() const - { - return m_workingDir; - } + QString workingDir() const { return m_workingDir; } - QString ffmpegOutput() const - { - return m_ffmpegOutput; - } + QString ffmpegOutput() const { return m_ffmpegOutput; } signals: void createWallpaperStateChanged(CreateImportVideo::ImportVideoState state); diff --git a/ScreenPlay/src/createimportvideo.h b/ScreenPlay/src/createimportvideo.h index 00503f2f..ca4a3546 100644 --- a/ScreenPlay/src/createimportvideo.h +++ b/ScreenPlay/src/createimportvideo.h @@ -100,10 +100,7 @@ public: }; Q_ENUM(ImportVideoState) - float progress() const - { - return m_progress; - } + float progress() const { return m_progress; } bool m_skipAudio { false }; diff --git a/ScreenPlay/src/globalvariables.h b/ScreenPlay/src/globalvariables.h index eb665e2c..d72a4e7e 100644 --- a/ScreenPlay/src/globalvariables.h +++ b/ScreenPlay/src/globalvariables.h @@ -67,42 +67,27 @@ public: \property GlobalVariables::localStoragePath \brief Returns the localStoragePath. */ - QUrl localStoragePath() const - { - return m_localStoragePath; - } + QUrl localStoragePath() const { return m_localStoragePath; } /*! \property GlobalVariables::localSettingsPath \brief Returns the localSettingsPath. */ - QUrl localSettingsPath() const - { - return m_localSettingsPath; - } + QUrl localSettingsPath() const { return m_localSettingsPath; } /*! \property GlobalVariables::wallpaperExecutablePath \brief Returns the wallpaperExecutablePath. This only differes in development builds. */ - QUrl wallpaperExecutablePath() const - { - return m_wallpaperExecutablePath; - } + QUrl wallpaperExecutablePath() const { return m_wallpaperExecutablePath; } /*! \property GlobalVariables::widgetExecutablePath \brief Returns the widgetExecutablePath. This only differes in development builds. */ - QUrl widgetExecutablePath() const - { - return m_widgetExecutablePath; - } + QUrl widgetExecutablePath() const { return m_widgetExecutablePath; } /*! \property GlobalVariables::m_version \brief Returns the current app version. Not yet used. */ - QVersionNumber version() const - { - return m_version; - } + QVersionNumber version() const { return m_version; } signals: void localStoragePathChanged(QUrl localStoragePath); diff --git a/ScreenPlay/src/installedlistmodel.cpp b/ScreenPlay/src/installedlistmodel.cpp index 49fe4df8..3b541e85 100644 --- a/ScreenPlay/src/installedlistmodel.cpp +++ b/ScreenPlay/src/installedlistmodel.cpp @@ -33,7 +33,7 @@ void InstalledListModel::init() } auto reloadLambda = [this]() { - QTimer::singleShot(500, [this]() { + QTimer::singleShot(500, this, [this]() { reset(); }); }; @@ -170,7 +170,6 @@ void InstalledListModel::loadInstalledContent() if (!obj->contains("type")) continue; - if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString())) { if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString(), Qt::CaseInsensitive)) { append(*obj, item.baseName(), item.lastModified()); diff --git a/ScreenPlay/src/monitorlistmodel.cpp b/ScreenPlay/src/monitorlistmodel.cpp index 4ed25ec0..36b92993 100644 --- a/ScreenPlay/src/monitorlistmodel.cpp +++ b/ScreenPlay/src/monitorlistmodel.cpp @@ -223,9 +223,10 @@ QRect MonitorListModel::getAbsoluteDesktopSize() const } /*! - \brief Sets the previewImage and appID for a list item. + \brief Sets a shared_ptr to the monitor list. This should be used to set and + remove the shared_ptr. */ -void MonitorListModel::setWallpaperActiveMonitor(const std::shared_ptr& wallpaper, const QVector monitors) +void MonitorListModel::setWallpaperMonitor(const std::shared_ptr& wallpaper, const QVector monitors) { for (const int monitor : monitors) { diff --git a/ScreenPlay/src/monitorlistmodel.h b/ScreenPlay/src/monitorlistmodel.h index f3bea917..311ec59e 100644 --- a/ScreenPlay/src/monitorlistmodel.h +++ b/ScreenPlay/src/monitorlistmodel.h @@ -99,7 +99,8 @@ public: int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - void setWallpaperActiveMonitor(const std::shared_ptr& wallpaper, + void setWallpaperMonitor( + const std::shared_ptr& wallpaper, const QVector monitors); std::optional getAppIDByMonitorIndex(const int index) const; diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index 6edfa125..aa810a92 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -101,7 +101,7 @@ void ScreenPlayManager::init( a \a fillMode, a \a type (htmlWallpaper, qmlWallpaper etc.), a \a saveToProfilesConfigFile bool only set to flase if we call the method when using via the settings on startup to skip a unnecessary save. */ -void ScreenPlayManager::createWallpaper( +bool ScreenPlayManager::createWallpaper( const InstalledType::InstalledType type, const FillMode::FillMode fillMode, const QString& absoluteStoragePath, @@ -146,9 +146,9 @@ void ScreenPlayManager::createWallpaper( fillMode, type, m_settings->checkWallpaperVisible()); - m_monitorListModel->setWallpaperActiveMonitor(wallpaper, monitorIndex); + m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex); - return; + return true; } } i++; @@ -170,17 +170,21 @@ void ScreenPlayManager::createWallpaper( m_settings->checkWallpaperVisible()); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestSave, this, &ScreenPlayManager::requestSaveProfiles); - QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestClose, this, &ScreenPlayManager::removeApp); + QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::requestClose, this, &ScreenPlayManager::removeWallpaper); QObject::connect(wallpaper.get(), &ScreenPlayWallpaper::error, this, &ScreenPlayManager::displayErrorPopup); + if (!wallpaper->start()) { + return false; + } m_screenPlayWallpapers.append(wallpaper); - m_monitorListModel->setWallpaperActiveMonitor(wallpaper, monitorIndex); + m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex); increaseActiveWallpaperCounter(); + return true; } /*! \brief Creates a ScreenPlayWidget object via a \a absoluteStoragePath and a \a preview image (relative path). */ -void ScreenPlayManager::createWidget( +bool ScreenPlayManager::createWidget( const InstalledType::InstalledType type, const QPoint& position, const QString& absoluteStoragePath, @@ -200,7 +204,7 @@ void ScreenPlayManager::createWidget( if (path.isEmpty()) { qWarning() << "Path is empty, Abort! String: " << absoluteStoragePath; - return; + return false; } auto widget = std::make_shared( @@ -213,79 +217,63 @@ void ScreenPlayManager::createWidget( type); QObject::connect(widget.get(), &ScreenPlayWidget::requestSave, this, &ScreenPlayManager::requestSaveProfiles); - QObject::connect(widget.get(), &ScreenPlayWidget::requestClose, this, &ScreenPlayManager::removeApp); + QObject::connect(widget.get(), &ScreenPlayWidget::requestClose, this, &ScreenPlayManager::removeWidget); QObject::connect(widget.get(), &ScreenPlayWidget::error, this, &ScreenPlayManager::displayErrorPopup); + if (!widget->start()) { + return false; + } increaseActiveWidgetsCounter(); m_screenPlayWidgets.append(widget); + return true; } /*! - \brief Iterates all Wallpaper and Widgets for the matching appID. Returns true if a matching appID - was successful set. + \brief Removes all wallpaper entries in the profiles.json. */ -bool ScreenPlayManager::appConnected(const std::shared_ptr& connection) +bool ScreenPlayManager::removeAllWallpapers() { - for (const auto& item : qAsConst(m_screenPlayWidgets)) { - if (item->appID() == connection->appID()) { - item->setSDKConnection(connection); - return true; + + if (m_screenPlayWallpapers.empty()) { + qWarning() << "Trying to remove all Wallpapers while m_screenPlayWallpapers is not empty. Count: " << m_screenPlayWallpapers.size(); + return false; + } + + QStringList appIDs; + // Do not remove items from the vector you iterate on. + for (auto& client : m_screenPlayWallpapers) { + appIDs.append(client->appID()); + } + + for (const auto& appID : appIDs) { + if (!removeWallpaper(appID)) { + return false; } } - for (const auto& item : qAsConst(m_screenPlayWallpapers)) { - if (item->appID() == connection->appID()) { - item->setSDKConnection(connection); - return true; - } - } + emit requestSaveProfiles(); - qWarning() << "No matching appID for id" << connection->appID() << " was found!"; - - return false; -} - -/*! - \brief Removes all wallpaper entries in the profiles.json. This method will likely be removed - when using nlohmann/json in the future. -*/ -void ScreenPlayManager::removeAllWallpapers() -{ - if (!m_screenPlayWallpapers.empty()) { - - closeAllWallpapers(); - m_screenPlayWallpapers.clear(); - - m_monitorListModel->clearActiveWallpaper(); - - emit requestSaveProfiles(); - setActiveWallpaperCounter(0); - if (activeWallpaperCounter() != m_screenPlayWallpapers.length()) { - if (m_telemetry) { - m_telemetry->sendEvent("wallpaper", "error_removeAllWallpapers"); - } - - qWarning() << "activeWallpaperCounter value: " << activeWallpaperCounter() - << "does not match m_screenPlayWallpapers length:" << m_screenPlayWallpapers.length(); - } - } else { - if (m_telemetry) { - m_telemetry->sendEvent("wallpaper", "error_removeAllWallpapers_m_screenPlayWallpapers_notEmpty"); - } - qWarning() << "Trying to remove all wallpapers while m_screenPlayWallpapers is not empty. Count: " << m_screenPlayWallpapers.size(); - } + return true; } /*! \brief Removes all widgets and resets the activeWidgetCounter to 0. */ -void ScreenPlayManager::removeAllWidgets() +bool ScreenPlayManager::removeAllWidgets() { - if (!m_screenPlayWidgets.empty()) { - closeAllWidgets(); - m_screenPlayWidgets.clear(); - emit requestSaveProfiles(); - setActiveWidgetsCounter(0); + if (m_screenPlayWallpapers.empty()) { + qWarning() << "Trying to remove all Widgets while m_screenPlayWallpapers is not empty. Count: " << m_screenPlayWallpapers.size(); + return false; } + + for (auto& client : m_screenPlayWallpapers) { + if (!removeWidget(client->appID())) { + return false; + } + } + + emit requestSaveProfiles(); + + return true; } /*! @@ -297,52 +285,30 @@ bool ScreenPlayManager::removeWallpaperAt(int index) { if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { - return removeApp(*appID); - } - if (m_telemetry) { - m_telemetry->sendEvent("wallpaper", "error_removeWallpaperAt"); + if (removeWallpaper(*appID)) { + emit requestSaveProfiles(); + return true; + } } + qWarning() << "Could not remove Wallpaper at index:" << index; return false; } -/*! - \brief Disconnects the connection, remove -*/ -bool ScreenPlayManager::removeApp(const QString& appID) -{ - if (!closeConnection(appID)) { - qWarning() << "Could not close socket. Abort!"; - return false; - } - - m_monitorListModel->closeWallpaper(appID); - - const QString appIDCopy = appID; - if (!removeWallpaperByAppID(appIDCopy)) { - if (m_telemetry) { - m_telemetry->sendEvent("wallpaper", "error_removeWallpaperAt_removeWallpaperByAppID"); - } - qWarning() << "Could not remove Wallpaper " << appIDCopy << " from wallpaper list!"; - return false; - } - emit requestSaveProfiles(); - return true; -} - /*! \brief Request a spesific json profile to display in the active wallpaper popup on the right. */ -void ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index) +bool ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index) { for (const std::shared_ptr& uPtrWallpaper : qAsConst(m_screenPlayWallpapers)) { if (uPtrWallpaper->screenNumber()[0] == index) { emit projectSettingsListModelResult( uPtrWallpaper->getProjectSettingsListModel()); - return; + return true; } } + return false; } /*! @@ -351,8 +317,7 @@ void ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index) bool ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value) { if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { - setWallpaperValue(*appID, key, value); - return true; + return setWallpaperValue(*appID, key, value); } qWarning() << "Could net get appID from m_monitorListModel!"; @@ -362,15 +327,17 @@ bool ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q /*! \brief Convenient function to set a \a value at a given \a index and \a key for all wallaper. For exmaple used to mute all wallpaper. */ -void ScreenPlayManager::setAllWallpaperValue(const QString& key, const QString& value) +bool ScreenPlayManager::setAllWallpaperValue(const QString& key, const QString& value) { - for (const std::shared_ptr& uPtrWallpaper : qAsConst(m_screenPlayWallpapers)) { - setWallpaperValue(uPtrWallpaper->appID(), key, value); + for (auto& wallpaper : m_screenPlayWallpapers) { + return setWallpaperValue(wallpaper->appID(), key, value); } + return true; } /*! \brief Returns \c a ScreenPlayWallpaper if successful, otherwhise \c std::nullopt. + This function is only used in QML. */ ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID) const { @@ -387,113 +354,139 @@ ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID */ void ScreenPlayManager::newConnection() { - auto connection = std::make_shared(m_server->nextPendingConnection()); + auto connection = std::make_unique(m_server->nextPendingConnection()); + // Because user can close widgets by pressing x the widgets must send us the event QObject::connect(connection.get(), &SDKConnection::requestDecreaseWidgetCount, this, [this]() { setActiveWidgetsCounter(activeWallpaperCounter() - 1); }); QObject::connect(connection.get(), &SDKConnection::requestRaise, this, &ScreenPlayManager::requestRaise); - // Only after we receive the first message with appID and type we can set the shared reference to the - // ScreenPlayWallpaper or ScreenPlayWidgets class + + // Only after we receive the first message with appID and type we can set the SDKConnection to the + // ScreenPlayWallpaper or ScreenPlayWidgets class. QObject::connect(connection.get(), &SDKConnection::appConnected, this, [this](const SDKConnection* connection) { - for (const auto& client : qAsConst(m_clients)) { - if (client.get() == connection) { - appConnected(client); + if (m_unconnectedClients.empty()) { + qWarning() << "Unable to match a connection. UnconnectedClients list is empty!"; + return; + } + + qWarning() << "There are no wallpaper or widgets that have to SDKConnection " + << "m_screenPlayWallpapers count: " << m_screenPlayWallpapers.size() + << "m_screenPlayWidgets count: " << m_screenPlayWidgets.size() + << "m_unconnectedClients count: " << m_unconnectedClients.size(); + + std::unique_ptr matchingConnection; + for (int i = 0; i < m_unconnectedClients.size(); ++i) { + if (m_unconnectedClients.at(i).get() == connection) { + matchingConnection = std::move(m_unconnectedClients.at(i)); + m_unconnectedClients.erase(m_unconnectedClients.begin() + i); + } + } + + if (!matchingConnection) { + qWarning() << "Unable to match a connection! Aborting!"; + return; + } + + for (int i = 0; i < m_screenPlayWallpapers.size(); ++i) { + if (m_screenPlayWallpapers.at(i)->appID() == matchingConnection->appID()) { + m_screenPlayWallpapers.at(i)->setSDKConnection(std::move(matchingConnection)); return; } } - qWarning() << "No matching connection found!"; - }); - m_clients.append(connection); -} -/*! - \brief Closes all wallpaper connection with the following type: - \list - \li videoWallpaper - \li qmlWallpaper - \li htmlWallpaper - \li godotWallpaper - \endlist -*/ -void ScreenPlayManager::closeAllWallpapers() -{ - if (m_screenPlayWallpapers.empty() && m_activeWallpaperCounter == 0) - return; - - closeConntectionByType(ScreenPlayUtil::getAvailableWallpaper()); - setActiveWallpaperCounter(0); -} - -/*! - \brief Closes all widgets connection with the following type: - \list - \li qmlWidget - \li htmlWidget - \li standaloneWidget - \endlist -*/ -void ScreenPlayManager::closeAllWidgets() -{ - if (m_screenPlayWidgets.empty() && m_activeWidgetsCounter == 0) - return; - - closeConntectionByType(ScreenPlayUtil::getAvailableWidgets()); - setActiveWidgetsCounter(0); -} - -/*! - \brief Closes a connection by type. Used only by closeAllWidgets() and closeAllWallpapers() -*/ -bool ScreenPlayManager::closeConntectionByType(const QStringList& types) -{ - if (m_clients.isEmpty()) - return true; - - for (auto& client : m_clients) { - if (types.contains(client->type(), Qt::CaseInsensitive)) { - client->close(); - if (!m_clients.removeOne(client)) { - return false; + for (int i = 0; i < m_screenPlayWidgets.size(); ++i) { + if (m_screenPlayWidgets.at(i)->appID() == matchingConnection->appID()) { + m_screenPlayWidgets.at(i)->setSDKConnection(std::move(matchingConnection)); + return; } } + + qWarning() << "No matching connection found!"; + }); + m_unconnectedClients.push_back(std::move(connection)); +} + +/*! + \brief Removes a wallpaper from the given appID. Returns true on success. +*/ +bool ScreenPlayManager::removeWallpaper(const QString& appID) +{ + m_screenPlayWallpapers.erase( + std::remove_if( + m_screenPlayWallpapers.begin(), + m_screenPlayWallpapers.end(), + [this, appID](auto& wallpaper) { + if (wallpaper->appID() != appID) { + return false; + } + + qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber(); + + // The MonitorListModel contains a shared_ptr of this object that needs to be removed + // for shared_ptr to release the object. + m_monitorListModel->setWallpaperMonitor({}, wallpaper->screenNumber()); + + decreaseActiveWallpaperCounter(); + + return true; + })); + + if (activeWallpaperCounter() != m_screenPlayWallpapers.length()) { + qWarning() << "activeWallpaperCounter value: " << activeWallpaperCounter() + << "does not match m_screenPlayWallpapers length:" << m_screenPlayWallpapers.length(); + return false; } return true; } /*! - \brief Closes a Wallpaper or Widget connection by the given \a appID. + \brief Removes a Widget from the given appID. Returns true on success. */ -bool ScreenPlayManager::closeConnection(const QString& appID) +bool ScreenPlayManager::removeWidget(const QString& appID) { - if (m_clients.isEmpty()) - return true; + m_screenPlayWidgets.erase( + std::remove_if( + m_screenPlayWidgets.begin(), + m_screenPlayWidgets.end(), + [this, appID](auto& widget) { + if (widget->appID() != appID) { + return false; + } - for (auto& client : m_clients) { - if (client->appID() == appID) { - client->close(); - return m_clients.removeOne(client); - } + qInfo() << "Remove widget "; + + decreaseActiveWidgetsCounter(); + + return true; + })); + + if (activeWidgetsCounter() != m_screenPlayWidgets.length()) { + qWarning() << "activeWallpaperCounter value: " << activeWidgetsCounter() + << "does not match m_screenPlayWallpapers length:" << m_screenPlayWidgets.length(); + return false; } + return false; } /*! \brief Sets a given \a value to a given \a key. The \a appID is used to identify the receiver socket. */ -void ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QString& value) +bool ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QString& value) { - for (const auto& wallpaper : qAsConst(m_screenPlayWallpapers)) { + for (auto& wallpaper : m_screenPlayWallpapers) { if (wallpaper->appID() == appID) { - wallpaper->setWallpaperValue(key, value, true); + return wallpaper->setWallpaperValue(key, value, true); } } + return false; } /*! \brief Saves a given wallpaper \a newProfileObject to a \a profileName. We ignore the profileName argument because we currently only support one profile. Returns \c true if successfuly saved to profiles.json, otherwise \c false. */ -void ScreenPlayManager::saveProfiles() +bool ScreenPlayManager::saveProfiles() { m_saveLimiter.stop(); @@ -520,27 +513,9 @@ void ScreenPlayManager::saveProfiles() profile.insert("version", "1.0.0"); profile.insert("profiles", activeProfileList); - if (Util::writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) + if (Util::writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) { emit profilesSaved(); -} - -/*! - \brief Removes a wallpaper from the given appID. Returns true on success. -*/ -bool ScreenPlayManager::removeWallpaperByAppID(const QString& appID) -{ - for (auto& wallpaper : m_screenPlayWallpapers) { - if (wallpaper->appID() == appID) { - qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber(); - decreaseActiveWallpaperCounter(); - m_screenPlayWallpapers.removeOne(wallpaper); - if (activeWallpaperCounter() != m_screenPlayWallpapers.length()) { - qWarning() << "activeWallpaperCounter value: " << activeWallpaperCounter() - << "does not match m_screenPlayWallpapers length:" << m_screenPlayWallpapers.length(); - return false; - } - return true; - } + return true; } return false; } @@ -548,27 +523,27 @@ bool ScreenPlayManager::removeWallpaperByAppID(const QString& appID) /*! \brief Loads all wallpaper from profiles.json when the version number matches and starts the available wallpaper */ -void ScreenPlayManager::loadProfiles() +bool ScreenPlayManager::loadProfiles() { - auto configObj = ScreenPlayUtil::openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json"); + const auto configObj = ScreenPlayUtil::openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json"); if (!configObj) { qWarning() << "Could not load active profiles at path: " << m_globalVariables->localSettingsPath().toString() + "/profiles.json"; - return; + return false; } std::optional version = ScreenPlayUtil::getVersionNumberFromString(configObj->value("version").toString()); if (version && *version != m_globalVariables->version()) { qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << m_globalVariables->version().toString(); - return; + return false; } QJsonArray activeProfilesTmp = configObj->value("profiles").toArray(); if (activeProfilesTmp.size() > 1) { qWarning() << "We currently only support one profile!"; - return; + return false; } qInfo() << "Loading profiles " << activeProfilesTmp.size(); @@ -579,7 +554,7 @@ void ScreenPlayManager::loadProfiles() if (wallpaper.toObject().value("name").toString() != "default") continue; - for (const QJsonValueRef wallpaper : wallpaper.toObject().value("wallpaper").toArray()) { + for (QJsonValueRef wallpaper : wallpaper.toObject().value("wallpaper").toArray()) { QJsonObject wallpaperObj = wallpaper.toObject(); if (wallpaperObj.empty()) @@ -592,12 +567,12 @@ void ScreenPlayManager::loadProfiles() int value = monitorNumber.toInt(-1); if (value == -1) { qWarning() << "Could not parse monitor number to display content at"; - return; + return false; } if (monitors.contains(value)) { qWarning() << "The monitor: " << value << " is sharing the config multiple times. "; - return; + return false; } monitors.append(value); } @@ -618,8 +593,11 @@ void ScreenPlayManager::loadProfiles() const auto type = QStringToEnum(typeString, InstalledType::InstalledType::VideoWallpaper); const auto fillMode = QStringToEnum(fillModeString, FillMode::FillMode::Cover); - qInfo() << "Start wallpaper from profile:" << type << fillMode << monitors << absolutePath; - createWallpaper(type, fillMode, absolutePath, previewImage, file, monitors, volume, playbackRate, properties, false); + const bool success = createWallpaper(type, fillMode, absolutePath, previewImage, file, monitors, volume, playbackRate, properties, false); + + if (!success) { + qWarning() << "Unable to start Wallpaper! " << type << fillMode << monitors << absolutePath; + } } for (const QJsonValueRef widget : wallpaper.toObject().value("widgets").toArray()) { @@ -637,10 +615,14 @@ void ScreenPlayManager::loadProfiles() const auto type = QStringToEnum(typeString, InstalledType::InstalledType::QMLWidget); const QJsonObject properties = widgetObj.value("properties").toObject(); - qInfo() << "Start widget from profile:" << type << position << absolutePath; - createWidget(type, position, absolutePath, previewImage, properties, false); + const bool success = createWidget(type, position, absolutePath, previewImage, properties, false); + + if (!success) { + qWarning() << "Unable to start Widget! " << type << position << absolutePath; + } } } + return true; } TEST_CASE("Loads profiles.json") @@ -648,5 +630,4 @@ TEST_CASE("Loads profiles.json") GlobalVariables globalVariables; ScreenPlayManager manager; } - } diff --git a/ScreenPlay/src/screenplaymanager.h b/ScreenPlay/src/screenplaymanager.h index 4521bf05..4550d10b 100644 --- a/ScreenPlay/src/screenplaymanager.h +++ b/ScreenPlay/src/screenplaymanager.h @@ -64,23 +64,7 @@ class ScreenPlayManager : public QObject { Q_PROPERTY(int activeWidgetsCounter READ activeWidgetsCounter WRITE setActiveWidgetsCounter NOTIFY activeWidgetsCounterChanged) public: - explicit ScreenPlayManager( - - QObject* parent = nullptr); - - int activeWallpaperCounter() const - { - return m_activeWallpaperCounter; - } - - int activeWidgetsCounter() const - { - return m_activeWidgetsCounter; - } - bool isAnotherScreenPlayInstanceRunning() - { - return m_isAnotherScreenPlayInstanceRunning; - } + explicit ScreenPlayManager(QObject* parent = nullptr); void init( const std::shared_ptr& globalVariables, @@ -88,22 +72,27 @@ public: const std::shared_ptr& telemetry, const std::shared_ptr& settings); + int activeWallpaperCounter() const { return m_activeWallpaperCounter; } + int activeWidgetsCounter() const { return m_activeWidgetsCounter; } + bool isAnotherScreenPlayInstanceRunning() { return m_isAnotherScreenPlayInstanceRunning; } + signals: - void projectSettingsListModelResult(ScreenPlay::ProjectSettingsListModel* li = nullptr); void activeWallpaperCounterChanged(int activeWallpaperCounter); void activeWidgetsCounterChanged(int activeWidgetsCounter); + void monitorConfigurationChanged(); + + void projectSettingsListModelResult(ScreenPlay::ProjectSettingsListModel* li = nullptr); void requestSaveProfiles(); void requestRaise(); void profilesSaved(); - void monitorConfigurationChanged(); void displayErrorPopup(const QString& msg); private slots: - void saveProfiles(); + bool saveProfiles(); public slots: // moc needs full enum namespace info see QTBUG-58454 - void createWallpaper( + bool createWallpaper( const ScreenPlay::InstalledType::InstalledType type, const ScreenPlay::FillMode::FillMode fillMode, const QString& absoluteStoragePath, @@ -115,7 +104,7 @@ public slots: const QJsonObject& properties, const bool saveToProfilesConfigFile); - void createWidget( + bool createWidget( const ScreenPlay::InstalledType::InstalledType type, const QPoint& position, const QString& absoluteStoragePath, @@ -123,22 +112,17 @@ public slots: const QJsonObject& properties, const bool saveToProfilesConfigFile); - void removeAllWallpapers(); - void removeAllWidgets(); + bool removeAllWallpapers(); + bool removeAllWidgets(); bool removeWallpaperAt(const int index); - bool removeApp(const QString& appID); - void requestProjectSettingsAtMonitorIndex(const int index); + bool requestProjectSettingsAtMonitorIndex(const int index); bool setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value); - void setAllWallpaperValue(const QString& key, const QString& value); + bool setAllWallpaperValue(const QString& key, const QString& value); + bool setWallpaperValue(const QString& appID, const QString& key, const QString& value); ScreenPlayWallpaper* getWallpaperByAppID(const QString& appID) const; void newConnection(); - void closeAllWallpapers(); - void closeAllWidgets(); - bool closeConntectionByType(const QStringList& types); - bool closeConnection(const QString& appID); - void setWallpaperValue(const QString& appID, const QString& key, const QString& value); void setActiveWallpaperCounter(int activeWallpaperCounter) { @@ -189,10 +173,10 @@ public slots: } private: - void loadProfiles(); - bool appConnected(const std::shared_ptr& connection); + bool loadProfiles(); bool checkIsAnotherScreenPlayInstanceRunning(); - [[nodiscard]] bool removeWallpaperByAppID(const QString& appID); + bool removeWallpaper(const QString& appID); + bool removeWidget(const QString& appID); private: std::shared_ptr m_globalVariables; @@ -204,7 +188,8 @@ private: QVector> m_screenPlayWallpapers; QVector> m_screenPlayWidgets; - QVector> m_clients; + std::vector> m_unconnectedClients; + int m_activeWallpaperCounter { 0 }; int m_activeWidgetsCounter { 0 }; diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index 3191512b..9f1d17c4 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -10,6 +10,15 @@ namespace ScreenPlay { This class is only for managing the QProcess to an extern ScreenPlayWallpaper! */ +/*! + \brief Destructor for ScreenPlayWallpaper. +*/ +ScreenPlayWallpaper::~ScreenPlayWallpaper() +{ + qInfo() << "Remove wallpaper " << m_appID; + m_connection->close(); +} + /*! \brief Constructor for ScreenPlayWallpaper. */ @@ -77,7 +86,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, tmpScreenNumber = QString::number(m_screenNumber.first()); } - const QStringList proArgs { + m_appArgumentsList = QStringList { tmpScreenNumber, m_absolutePath, QString { "appID=" + m_appID }, @@ -88,8 +97,11 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, // Fixes issue 84 media key overlay " --disable-features=HardwareMediaKeyHandling" }; +} - m_process.setArguments(proArgs); +bool ScreenPlayWallpaper::start() +{ + m_process.setArguments(m_appArgumentsList); m_process.setProgram(m_globalVariables->wallpaperExecutablePath().toString()); // We must start detatched otherwise we would instantly close the process // and would loose the animted fade-out and the background refresh needed @@ -97,10 +109,9 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, const bool success = m_process.startDetached(); qInfo() << "Starting ScreenPlayWallpaper detached: " << (success ? "success" : "failed!"); if (!success) { - qInfo() << m_process.errorString(); - emit requestClose(m_appID); emit error(QString("Could not start Wallpaper: " + m_process.errorString())); } + return success; } /*! @@ -110,7 +121,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector& screenNumber, QJsonObject ScreenPlayWallpaper::getActiveSettingsJson() { QJsonArray screenNumber; - for (const int i : m_screenNumber) { + for (const int i : qAsConst(m_screenNumber)) { screenNumber.append(i); } @@ -157,7 +168,7 @@ void ScreenPlayWallpaper::processError(QProcess::ProcessError error) playbackRate or fillMode. Otherwise it is a simple key, value json pair. */ -void ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save) +bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save) { QJsonObject obj; obj.insert(key, value); @@ -172,20 +183,23 @@ void ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& v setFillMode(QStringToEnum(value, FillMode::FillMode::Cover)); } - m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact)); + const bool success = m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact)); - if (save) + if (save && success) emit requestSave(); + + return success; } /*! - \brief Connects to ScreenPlay. Start a alive ping check for every 16 seconds. + \brief Connects to ScreenPlay. Start a alive ping check for every + GlobalVariables::contentPingAliveIntervalMS seconds. */ -void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr& connection) +void ScreenPlayWallpaper::setSDKConnection(std::unique_ptr connection) { - m_connection = connection; + m_connection = std::move(connection); - QTimer::singleShot(1000, [this]() { + QTimer::singleShot(1000, this, [this]() { if (playbackRate() != 1.0) { setWallpaperValue("playbackRate", QString::number(playbackRate()), false); } diff --git a/ScreenPlay/src/screenplaywallpaper.h b/ScreenPlay/src/screenplaywallpaper.h index 16573aa3..88cc30f5 100644 --- a/ScreenPlay/src/screenplaywallpaper.h +++ b/ScreenPlay/src/screenplaywallpaper.h @@ -68,6 +68,7 @@ class ScreenPlayWallpaper : public QObject { public: ScreenPlayWallpaper() { } + ~ScreenPlayWallpaper(); explicit ScreenPlayWallpaper( const QVector& screenNumber, @@ -82,6 +83,8 @@ public: const bool checkWallpaperVisible, QObject* parent = nullptr); + bool start(); + void replace( const QString& absolutePath, const QString& previewImage, @@ -91,64 +94,31 @@ public: const InstalledType::InstalledType type, const bool checkWallpaperVisible); - void setSDKConnection(const std::shared_ptr& connection); + void setSDKConnection(std::unique_ptr connection); QJsonObject getActiveSettingsJson(); - QVector screenNumber() const - { - return m_screenNumber; - } + QVector screenNumber() const { return m_screenNumber; } - QString previewImage() const - { - return m_previewImage; - } + QString previewImage() const { return m_previewImage; } - QString appID() const - { - return m_appID; - } + QString appID() const { return m_appID; } - InstalledType::InstalledType type() const - { - return m_type; - } + InstalledType::InstalledType type() const { return m_type; } - QString file() const - { - return m_file; - } + QString file() const { return m_file; } - FillMode::FillMode fillMode() const - { - return m_fillMode; - } + FillMode::FillMode fillMode() const { return m_fillMode; } - QString absolutePath() const - { - return m_absolutePath; - } + QString absolutePath() const { return m_absolutePath; } - float volume() const - { - return m_volume; - } + float volume() const { return m_volume; } - bool isLooping() const - { - return m_isLooping; - } + bool isLooping() const { return m_isLooping; } - ProjectSettingsListModel* getProjectSettingsListModel() - { - return &m_projectSettingsListModel; - } + ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; } - float playbackRate() const - { - return m_playbackRate; - } + float playbackRate() const { return m_playbackRate; } signals: void screenNumberChanged(QVector screenNumber); @@ -170,7 +140,7 @@ signals: public slots: void processExit(int exitCode, QProcess::ExitStatus exitStatus); void processError(QProcess::ProcessError error); - void setWallpaperValue(const QString& key, const QString& value, const bool save = false); + bool setWallpaperValue(const QString& key, const QString& value, const bool save = false); void setScreenNumber(QVector screenNumber) { @@ -267,7 +237,7 @@ public slots: private: const std::shared_ptr m_globalVariables; - std::shared_ptr m_connection; + std::unique_ptr m_connection; ProjectSettingsListModel m_projectSettingsListModel; QVector m_screenNumber; @@ -282,5 +252,6 @@ private: bool m_isLooping { true }; float m_playbackRate { 1.0f }; QTimer m_pingAliveTimer; + QStringList m_appArgumentsList; }; } diff --git a/ScreenPlay/src/screenplaywidget.cpp b/ScreenPlay/src/screenplaywidget.cpp index c3f1ce8c..15139398 100644 --- a/ScreenPlay/src/screenplaywidget.cpp +++ b/ScreenPlay/src/screenplaywidget.cpp @@ -48,15 +48,18 @@ ScreenPlayWidget::ScreenPlayWidget( m_projectSettingsListModel.init(type, projectSettingsListModelProperties); } - const QStringList proArgs { + m_appArgumentsList = QStringList { m_absolutePath, QString { "appID=" + m_appID }, QVariant::fromValue(m_type).toString(), QString::number(m_position.x()), QString::number(m_position.y()), }; +} - m_process.setArguments(proArgs); +bool ScreenPlayWidget::start() +{ + m_process.setArguments(m_appArgumentsList); m_process.setProgram(m_globalVariables->widgetExecutablePath().path()); QObject::connect(&m_process, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { @@ -65,18 +68,18 @@ ScreenPlayWidget::ScreenPlayWidget( const bool success = m_process.startDetached(); qInfo() << "Starting ScreenPlayWWidget detached: " << (success ? "success" : "failed!"); if (!success) { - qInfo() << m_process.errorString(); - emit requestClose(m_appID); emit error(QString("Could not start Widget: " + m_process.errorString())); } + return success; } /*! - \brief Connects to ScreenPlay. Start a alive ping check for every 16 seconds. + \brief Connects to ScreenPlay. Start a alive ping check for every + GlobalVariables::contentPingAliveIntervalMS seconds. */ -void ScreenPlayWidget::setSDKConnection(const std::shared_ptr& connection) +void ScreenPlayWidget::setSDKConnection(std::unique_ptr connection) { - m_connection = connection; + m_connection = std::move(connection); qInfo() << "App widget connected!"; QObject::connect(m_connection.get(), &SDKConnection::jsonMessageReceived, this, [this](const QJsonObject obj) { if (obj.value("messageType") == "positionUpdate") { diff --git a/ScreenPlay/src/screenplaywidget.h b/ScreenPlay/src/screenplaywidget.h index 5abc157e..9da54a05 100644 --- a/ScreenPlay/src/screenplaywidget.h +++ b/ScreenPlay/src/screenplaywidget.h @@ -48,6 +48,7 @@ #include "sdkconnection.h" #include +#include namespace ScreenPlay { @@ -68,39 +69,23 @@ public: const QString& previewImage, const QJsonObject& properties, const InstalledType::InstalledType type); + bool start(); + ScreenPlayWidget() { } - QString previewImage() const - { - return m_previewImage; - } + QString previewImage() const { return m_previewImage; } - QPoint position() const - { - return m_position; - } + QPoint position() const { return m_position; } - QString absolutePath() const - { - return m_absolutePath; - } + QString absolutePath() const { return m_absolutePath; } - QString appID() const - { - return m_appID; - } + QString appID() const { return m_appID; } - InstalledType::InstalledType type() const - { - return m_type; - } + InstalledType::InstalledType type() const { return m_type; } - void setSDKConnection(const std::shared_ptr& connection); + void setSDKConnection(std::unique_ptr connection); - ProjectSettingsListModel* getProjectSettingsListModel() - { - return &m_projectSettingsListModel; - } + ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; } public slots: QJsonObject getActiveSettingsJson(); @@ -163,7 +148,7 @@ signals: private: const std::shared_ptr m_globalVariables; - std::shared_ptr m_connection; + std::unique_ptr m_connection; ProjectSettingsListModel m_projectSettingsListModel; QProcess m_process; @@ -173,5 +158,6 @@ private: InstalledType::InstalledType m_type; QString m_absolutePath; QTimer m_pingAliveTimer; + QStringList m_appArgumentsList; }; } diff --git a/ScreenPlay/src/sdkconnection.cpp b/ScreenPlay/src/sdkconnection.cpp index 366f0670..23af48bd 100644 --- a/ScreenPlay/src/sdkconnection.cpp +++ b/ScreenPlay/src/sdkconnection.cpp @@ -88,37 +88,44 @@ void ScreenPlay::SDKConnection::readyRead() /*! \brief Sends a message to the connected socket. */ -void ScreenPlay::SDKConnection::sendMessage(const QByteArray& message) +bool ScreenPlay::SDKConnection::sendMessage(const QByteArray& message) { m_socket->write(message); - m_socket->waitForBytesWritten(); + return m_socket->waitForBytesWritten(); } /*! \brief Closes the socket connection. Before it explicitly sends a quit command to make sure the wallpaper closes (fast). This also requestDecreaseWidgetCount() because Widgets. */ -void ScreenPlay::SDKConnection::close() +bool ScreenPlay::SDKConnection::close() { - qInfo() << "Close " << m_type << m_appID; + qInfo() << "Close " << m_type << m_appID << m_socket->state(); QJsonObject obj; obj.insert("command", QJsonValue("quit")); QByteArray command = QJsonDocument(obj).toJson(); m_socket->write(command); - m_socket->waitForBytesWritten(); + if (!m_socket->waitForBytesWritten()) { + qWarning("Faild to send quit command to app"); + return false; + } if (m_socket->state() == QLocalSocket::ConnectedState) { m_socket->disconnectFromServer(); m_socket->close(); - qDebug() << "### Destroy APPID:\t " << m_appID << " State: " << m_socket->state(); + qInfo() << "### Destroy APPID:\t " << m_appID << " State: " << m_socket->state(); + } else { + qWarning() << "Cannot disconnect app " << m_appID << " with the state:" << m_socket->state(); + return false; } if (m_type.contains("widget", Qt::CaseInsensitive)) { emit requestDecreaseWidgetCount(); } + return true; } } diff --git a/ScreenPlay/src/sdkconnection.h b/ScreenPlay/src/sdkconnection.h index 22d95536..15c669bd 100644 --- a/ScreenPlay/src/sdkconnection.h +++ b/ScreenPlay/src/sdkconnection.h @@ -72,25 +72,13 @@ public: */ explicit SDKConnection(QLocalSocket* socket, QObject* parent = nullptr); - QString appID() const - { - return m_appID; - } + QString appID() const { return m_appID; } - QLocalSocket* socket() const - { - return m_socket; - } + QLocalSocket* socket() const { return m_socket; } - QVector monitor() const - { - return m_monitor; - } + QVector monitor() const { return m_monitor; } - QString type() const - { - return m_type; - } + QString type() const { return m_type; } signals: void requestCloseAt(int at); @@ -105,8 +93,8 @@ signals: public slots: void readyRead(); - void sendMessage(const QByteArray& message); - void close(); + bool sendMessage(const QByteArray& message); + bool close(); void setAppID(QString appID) { diff --git a/ScreenPlay/src/settings.h b/ScreenPlay/src/settings.h index 528b34dc..48c48b27 100644 --- a/ScreenPlay/src/settings.h +++ b/ScreenPlay/src/settings.h @@ -133,84 +133,24 @@ public: }; Q_ENUM(Theme) - bool offlineMode() const - { - return m_offlineMode; - } + bool offlineMode() const { return m_offlineMode; } + bool getOfflineMode() const { return m_offlineMode; } + bool autostart() const { return m_autostart; } + bool highPriorityStart() const { return m_highPriorityStart; } + QString decoder() const { return m_decoder; } + QString gitBuildHash() const { return m_gitBuildHash; } + bool silentStart() const { return m_silentStart; } + bool anonymousTelemetry() const { return m_anonymousTelemetry; } + bool checkWallpaperVisible() const { return m_checkWallpaperVisible; } + ScreenPlay::FillMode::FillMode videoFillMode() const { return m_videoFillMode; } + Language language() const { return m_language; } + QString font() const { return m_font; } + Theme theme() const { return m_theme; } + bool steamVersion() const { return m_steamVersion; } + DesktopEnvironment desktopEnvironment() const { return m_desktopEnvironment; } - bool getOfflineMode() const - { - return m_offlineMode; - } - - bool autostart() const - { - return m_autostart; - } - - bool highPriorityStart() const - { - return m_highPriorityStart; - } - - QString decoder() const - { - return m_decoder; - } - - QString gitBuildHash() const - { - return m_gitBuildHash; - } - - bool silentStart() const - { - return m_silentStart; - } - - bool anonymousTelemetry() const - { - return m_anonymousTelemetry; - } - - bool checkWallpaperVisible() const - { - return m_checkWallpaperVisible; - } - - ScreenPlay::FillMode::FillMode videoFillMode() const - { - return m_videoFillMode; - } - - Language language() const - { - return m_language; - } - -public: void setupLanguage(); - QString font() const - { - return m_font; - } - - Theme theme() const - { - return m_theme; - } - - bool steamVersion() const - { - return m_steamVersion; - } - - DesktopEnvironment desktopEnvironment() const - { - return m_desktopEnvironment; - } - signals: void requestRetranslation(); void resetInstalledListmodel(); diff --git a/ScreenPlay/translations/ScreenPlay_de.ts b/ScreenPlay/translations/ScreenPlay_de.ts index e75107f4..9264248d 100644 --- a/ScreenPlay/translations/ScreenPlay_de.ts +++ b/ScreenPlay/translations/ScreenPlay_de.ts @@ -97,31 +97,31 @@ - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -1168,25 +1168,35 @@ wenn Sie ScreenPlay über Steam! installiert haben Navigation - + All Alles - + Scenes Szenen - + Videos Videos - + Widgets Widgets + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1488,7 +1498,7 @@ wenn Sie ScreenPlay über Steam! installiert haben - + Logs @@ -1556,32 +1566,32 @@ wenn Sie ScreenPlay über Steam! installiert haben Moin, ich bin Elias Steurer, auch bekannt als Kelteseth und ich bin der Entwickler von ScreenPlay. Danke, dass du meine Software nutzt. Du kannst mir hier folgen, um Updates über ScreenPlay zu erhalten: - + Version Version - + ScreenPlay Build Version ScreenPlay-Build-Version - + Open Changelog Changelog öffnen - + Third Party Software Software von Drittanbietern - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay wäre ohne die Arbeit anderer nicht möglich. Ein großes Dankeschön dafür geht an: - + Licenses Lizenzen @@ -1590,27 +1600,27 @@ wenn Sie ScreenPlay über Steam! installiert haben Debugging-Meldungen - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Wenn den ScreenPlay sich falsch verhält, ist hier eine gute Möglichkeit, nach Antworten zu suchen. Hier werden alle Protokolle und Warnungen während der Laufzeit angezeigt. - + Show Logs - + Data Protection Datenschutz - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Wir verwenden deine Daten sehr sorgfältig, um ScreenPlay zu verbessern. Wir verkaufen oder teilen diese (anonymen) Informationen nicht mit anderen! - + Privacy Datenschutz @@ -1693,52 +1703,47 @@ wenn Sie ScreenPlay über Steam! installiert haben Wallpaper erstellen - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2558,105 +2563,115 @@ wenn Sie ScreenPlay über Steam! installiert haben Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2664,7 +2679,7 @@ wenn Sie ScreenPlay über Steam! installiert haben XMLNewsfeed - + News & Patchnotes Neuigkeiten & Patchnotes diff --git a/ScreenPlay/translations/ScreenPlay_en.ts b/ScreenPlay/translations/ScreenPlay_en.ts index 1929bbcb..a6ca65bb 100644 --- a/ScreenPlay/translations/ScreenPlay_en.ts +++ b/ScreenPlay/translations/ScreenPlay_en.ts @@ -73,31 +73,31 @@ Community - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -766,25 +766,35 @@ Navigation - + All - + Scenes - + Videos - + Widgets + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1130,62 +1140,62 @@ - + Version - + ScreenPlay Build Version - + Open Changelog - + Third Party Software - + ScreenPlay would not be possible without the work of others. A big thank you to: - + Licenses - + Logs - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. - + Show Logs - + Data Protection - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! - + Privacy @@ -1256,52 +1266,47 @@ - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2121,105 +2126,115 @@ Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2227,7 +2242,7 @@ XMLNewsfeed - + News & Patchnotes diff --git a/ScreenPlay/translations/ScreenPlay_es.ts b/ScreenPlay/translations/ScreenPlay_es.ts index 45cfc212..87a722f7 100644 --- a/ScreenPlay/translations/ScreenPlay_es.ts +++ b/ScreenPlay/translations/ScreenPlay_es.ts @@ -97,31 +97,31 @@ - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -1148,25 +1148,35 @@ si instaló ScreenPlay vía Steam! Navigation - + All Todos - + Scenes Escenas - + Videos Videos - + Widgets Widgets + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1468,7 +1478,7 @@ si instaló ScreenPlay vía Steam! - + Logs @@ -1536,32 +1546,32 @@ si instaló ScreenPlay vía Steam! Hola, soy Elias Steurer también conocido como Kelteseth y soy el desarrollador de ScreenPlay. Gracias por usar mi software. Puedes seguirme para recibir actualizaciones sobre ScreenPlay aquí: - + Version Versión - + ScreenPlay Build Version Versión de construcción de ScreenPlay - + Open Changelog Registro de cambios abierto - + Third Party Software Software de terceros - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay no sería posible sin el trabajo de otros. Muchas gracias a todos: - + Licenses Licencias @@ -1570,27 +1580,27 @@ si instaló ScreenPlay vía Steam! Mensajes de depuración - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Si su ScreenPlay se comporta mal, esta es una buena manera de buscar respuestas. Esto muestra todos los registros y advertencias durante el tiempo de ejecución. - + Show Logs - + Data Protection Protección de datos - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Utilizamos sus datos con mucho cuidado para mejorar ScreenPlay. No vendemos ni compartimos esta información (anónima) con otros! - + Privacy Privacidad @@ -1673,52 +1683,47 @@ si instaló ScreenPlay vía Steam! Crear un wallpaper - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2538,105 +2543,115 @@ si instaló ScreenPlay vía Steam! Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2644,7 +2659,7 @@ si instaló ScreenPlay vía Steam! XMLNewsfeed - + News & Patchnotes diff --git a/ScreenPlay/translations/ScreenPlay_fr.ts b/ScreenPlay/translations/ScreenPlay_fr.ts index a79cefef..529aa4ef 100644 --- a/ScreenPlay/translations/ScreenPlay_fr.ts +++ b/ScreenPlay/translations/ScreenPlay_fr.ts @@ -97,31 +97,31 @@ - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -1158,25 +1158,35 @@ si vous avez installé ScreenPlay via Steam ! Navigation - + All Tout - + Scenes Scènes - + Videos Vidéos - + Widgets Widgets + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1545,37 +1555,37 @@ si vous avez installé ScreenPlay via Steam ! Bonjour, je suis Elias Steurer, aussi connu sous le nom de Kelteseth, et je suis le développeur de ScreenPlay. Merci d'utiliser mon logiciel. Vous pouvez me suivre pour recevoir des mises à jour sur ScreenPlay ici : - + Version Version - + ScreenPlay Build Version Version de construction de ScreenPlay - + Open Changelog Ouvrir le journal des modifications - + Third Party Software Logiciel tiers - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay ne serait pas possible sans le travail des autres. Un grand merci à : - + Licenses Licences - + Logs @@ -1584,27 +1594,27 @@ si vous avez installé ScreenPlay via Steam ! Messages de débogage - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Si votre ScreenPlay se comporte mal, c'est une bonne façon de chercher des réponses. Ceci montre tous les journaux et les avertissements pendant l'exécution. - + Show Logs - + Data Protection Protection des données - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Nous utilisons vos données avec beaucoup de soin pour améliorer le ScreenPlay. Nous ne vendons ni ne partageons ces informations (anonymes) avec d'autres personnes ! - + Privacy Confidentialité @@ -1687,52 +1697,47 @@ si vous avez installé ScreenPlay via Steam ! Créer un wallpaper - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2552,105 +2557,115 @@ si vous avez installé ScreenPlay via Steam ! Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2658,7 +2673,7 @@ si vous avez installé ScreenPlay via Steam ! XMLNewsfeed - + News & Patchnotes Nouveautées et notes de versions diff --git a/ScreenPlay/translations/ScreenPlay_ko.ts b/ScreenPlay/translations/ScreenPlay_ko.ts index c117eaf2..dd9d13b0 100644 --- a/ScreenPlay/translations/ScreenPlay_ko.ts +++ b/ScreenPlay/translations/ScreenPlay_ko.ts @@ -97,31 +97,31 @@ - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -1085,25 +1085,35 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! Navigation - + All 전체 - + Scenes 화면 - + Videos 비디오 - + Widgets 위젯 + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1405,7 +1415,7 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! - + Logs @@ -1473,32 +1483,32 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! 안녕하세요, ScreenPlay를 개발한, Kelteseth 닉네임을 쓰고 있는 Elias Steurer입니다. 제 소프트웨어를 사용해주셔서 감사합니다. 저를 팔로우하셔서 ScreenPlay의 업데이트 내용을 확인하실 수 있습니다 클릭: - + Version 버전 - + ScreenPlay Build Version ScreenPlay 빌드 버전 - + Open Changelog 변경 이력 열기 - + Third Party Software 타사 소프트웨어 - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay 기여자 여러분의 도움에 의해 완성되었습니다. 여러분께 감사드립니다: - + Licenses 라이선스 @@ -1507,27 +1517,27 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! 디버그 메시지 - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. ScreenPlay가 올바르게 작동하지 않고 있다면, 이것이 해답이 될 수 있습니다. 이것은 런타임동안의 모든 이력과 경고를 포함하고 있습니다. - + Show Logs - + Data Protection 데이터 보호 - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! ScreenPlay 향상을 위해 여러분의 익명 데이터를 신중히 사용합니다. 절대 정보를 팔거나 공유하지 않습니다! - + Privacy 개인 정보 @@ -1610,52 +1620,47 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! 배경화면 만들기 - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2475,105 +2480,115 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2581,7 +2596,7 @@ Steam을 통해 설치하셨을때의 기본 위치입니다! XMLNewsfeed - + News & Patchnotes 뉴스 & 패치노트 diff --git a/ScreenPlay/translations/ScreenPlay_pt_br.qm b/ScreenPlay/translations/ScreenPlay_pt_br.qm index d8d2ffd3..c99aa3f8 100644 Binary files a/ScreenPlay/translations/ScreenPlay_pt_br.qm and b/ScreenPlay/translations/ScreenPlay_pt_br.qm differ diff --git a/ScreenPlay/translations/ScreenPlay_pt_br.ts b/ScreenPlay/translations/ScreenPlay_pt_br.ts index f30667bf..9d1751e8 100644 --- a/ScreenPlay/translations/ScreenPlay_pt_br.ts +++ b/ScreenPlay/translations/ScreenPlay_pt_br.ts @@ -97,31 +97,39 @@ + News + + + + Wiki Wiki - + Forum Forum - + Issue List - + + Contribute + + + Release Notes - Notas de Lançamento + Notas de Lançamento - Contribution Guide - Guia de contribuição + Guia de contribuição - + Steam Workshop Steam Workshop @@ -1148,25 +1156,35 @@ si instaló ScreenPlay vía Steam! Navigation - + All Todos - + Scenes Cenas - + Videos Videos - + Widgets Widgets + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1468,7 +1486,7 @@ si instaló ScreenPlay vía Steam! Nós desativamos a renderização de video (menos o audio!) para melhor performance. Se você tiver problemas você pode desativar isso por aqui. O papel de parede vai precisar ser reiniciado! - + Logs Logs @@ -1536,32 +1554,32 @@ si instaló ScreenPlay vía Steam! Olá, Eu sou o Elias Steurer tambem conhecido como Kelteseth e eu sou desenvolvedor do ScreenPlay. Obrigado por usar meu programa. Você pode me seguir para receber atualizações sobre o ScreenPlay aquí: - + Version Versão - + ScreenPlay Build Version Versão da build do ScreenPlay - + Open Changelog Abrir Changelog - + Third Party Software Software de terceiros - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay não seria possivel sem o trabalho de outras pessoas. Um grande obrigado a você tambêm: - + Licenses Licenças @@ -1570,27 +1588,27 @@ si instaló ScreenPlay vía Steam! Mensagens de depuração - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Se o seu ScreenPlay se comportar mal, esta é uma boa maneira de procurar respostas. Isso mostra todos os logs e avisos durante o tempo de execução - + Show Logs Mostrar logs - + Data Protection Proteção de dados - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Utilizamos seus dados com muito cuidado para melhorar o ScreenPlay. Não vendemos e nem compartilhamos informações (anónima) com outros! - + Privacy Privacidade @@ -1673,52 +1691,55 @@ si instaló ScreenPlay vía Steam! Criar papel de parede - Project size: - Tamanho do projeto + Tamanho do projeto - + MB - + + Size: + + + + No description... Sem descrição... - + Click here if you like the content Clique aqui se você gosta do conteudo - + Click here if you do not like the content Cloque aqui se você não gosta do conteudo - Tags: - Etiquetas: + Etiquetas: - + Subscribtions: - + Open In Steam Abrir na Steam - + Subscribed! - + Subscribe @@ -2538,95 +2559,105 @@ si instaló ScreenPlay vía Steam! Workshop - + Loading Carregando - + Download now! Baixe agora! - + Downloading... Baixando... - + Details Detalhes - + Open In Steam Abrir na Steam - + Search for Wallpaper and Widgets... Procurar por Wallpaper e Widgets - + Open Workshop in Steam Abrir workshop na Steam - + Open GameHub in Steam Abrir Gamehub na Steam - + Ranked By Vote Classificado por voto - + Publication Date Data de publicação - + Ranked By Trend Classificado por tendência - + Favorited By Friends Favoritado por amigos - + Created By Friends Criado por amigos - + Created By Followed Users Criado por usuarios seguidos - + Not Yet Rated Não votado - + Total VotesAsc - + Votes Up Votos acima - + Total Unique Subscriptions + + + Back + Voltar + + + + Forward + + WorkshopItem @@ -2635,12 +2666,12 @@ si instaló ScreenPlay vía Steam! Baixar - + Successfully subscribed to Workshop Item! - + Download complete! Download completado! @@ -2648,7 +2679,7 @@ si instaló ScreenPlay vía Steam! XMLNewsfeed - + News & Patchnotes diff --git a/ScreenPlay/translations/ScreenPlay_ru.ts b/ScreenPlay/translations/ScreenPlay_ru.ts index ef06b3ad..33a2b588 100644 --- a/ScreenPlay/translations/ScreenPlay_ru.ts +++ b/ScreenPlay/translations/ScreenPlay_ru.ts @@ -97,31 +97,31 @@ - Wiki + News + Wiki + + + + Forum - + Issue List - - Release Notes + + Contribute - - Contribution Guide - - - - + Steam Workshop @@ -1163,25 +1163,35 @@ ms), но есть и некоторые проприетарные, такие Navigation - + All Все - + Scenes Сцены - + Videos Видео - + Widgets Виджеты + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1483,7 +1493,7 @@ ms), но есть и некоторые проприетарные, такие - + Logs @@ -1551,32 +1561,32 @@ ms), но есть и некоторые проприетарные, такие Привет, я Elias Steurer, также известный как Kelteseth, и я разработчик ScreenPlay. Спасибо за использование моего программного обеспечения. Вы можете подписаться на меня, чтобы получать обновления о ScreenPlay: - + Version Версия - + ScreenPlay Build Version Версия сборки ScreenPlay - + Open Changelog Открыть журнал изменений - + Third Party Software Стороннее ПО - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay был бы невозможен без работы других. Большое спасибо: - + Licenses Лицензии @@ -1585,27 +1595,27 @@ ms), но есть и некоторые проприетарные, такие Отладочные сообщения - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Если ваш ScreenPlay плохо себя ведет, это хороший способ поиска ответов. Он показывает все журналы и предупреждения во время работы. - + Show Logs - + Data Protection Защита данных - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Мы используем ваши данные очень тщательно, чтобы улучшить ScreenPlay. Мы не продаем и не делимся этой (анонимной) информацией с другими! - + Privacy Конфиденциальность @@ -1688,52 +1698,47 @@ ms), но есть и некоторые проприетарные, такие Создать обои - - Project size: - - - - + MB - + + Size: + + + + No description... - + Click here if you like the content - + Click here if you do not like the content - - Tags: - - - - + Subscribtions: - + Open In Steam - + Subscribed! - + Subscribe @@ -2553,105 +2558,115 @@ ms), но есть и некоторые проприетарные, такие Workshop - + Loading - + Download now! - + Downloading... - + Details - + Open In Steam - + Search for Wallpaper and Widgets... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote - + Publication Date - + Ranked By Trend - + Favorited By Friends - + Created By Friends - + Created By Followed Users - + Not Yet Rated - + Total VotesAsc - + Votes Up - + Total Unique Subscriptions + + + Back + + + + + Forward + + WorkshopItem - + Successfully subscribed to Workshop Item! - + Download complete! @@ -2659,7 +2674,7 @@ ms), но есть и некоторые проприетарные, такие XMLNewsfeed - + News & Patchnotes Список изменений diff --git a/ScreenPlay/translations/ScreenPlay_vi.qm b/ScreenPlay/translations/ScreenPlay_vi.qm index 2f30cbe1..562e6bcd 100644 Binary files a/ScreenPlay/translations/ScreenPlay_vi.qm and b/ScreenPlay/translations/ScreenPlay_vi.qm differ diff --git a/ScreenPlay/translations/ScreenPlay_vi.ts b/ScreenPlay/translations/ScreenPlay_vi.ts index 3b6d8563..eed06554 100644 --- a/ScreenPlay/translations/ScreenPlay_vi.ts +++ b/ScreenPlay/translations/ScreenPlay_vi.ts @@ -73,31 +73,39 @@ Community + News + + + + Wiki Wiki - + Forum Diễn đàn - + Issue List D.Sách Lỗi - + + Contribute + + + Release Notes - Ghi chú bản phát hành + Ghi chú bản phát hành - Contribution Guide - Hướng dẫn đóng góp + Hướng dẫn đóng góp - + Steam Workshop Still workshop. Steam Workshop @@ -955,25 +963,35 @@ Navigation - + All Tất cả - + Scenes Cảnh - + Videos Videos - + Widgets Tiện ích con + + + Install Date Ascending + + + + + Install Date Descending + + Subscribed items: @@ -1327,37 +1345,37 @@ Chào, tôi là Elias Steurer (hay còn được biết đến là Kelteseth) và tôi là nhà phát triển của ScreenPlay. Cảm ơn ban đã sử dụng ứng dụng của tôi. Bạn có thể theo dõi tôi ở đây để nhận tin tức về ScreenPlay: - + Version Phiên bản - + ScreenPlay Build Version Bản dựng của ScreenPlay - + Open Changelog Mở changelog - + Third Party Software Những ứng dụng của bên thứ ba - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay sẽ không thể có được néu như không có việc làm của những người khác. Một sự cảm ơn to lớn cho: - + Licenses Giấy phép - + Logs @@ -1366,27 +1384,27 @@ Các ghi chú gỡ lỗi - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. Nếu ScreenPlay của bạn không hoạt động bình thường thì đây là cách tốt để tìm ra câu trả lời. Cái này sẽ hiện tất cả các ghi chú và cảnh báo trong lúc ứng dụng chạy. - + Show Logs - + Data Protection Bảo vệ dữ liệu - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! Chúng tôi dùng dữ liệu của bạn rất cẩn thận để cải thiện ScreenPlay. Chúng tôi không bán thông tin của bạn với người khác! - + Privacy Quyền riêng tư @@ -1457,52 +1475,55 @@ Chọn hình nền - Project size: - Kích thước dự án: + Kích thước dự án: - + MB MB - + + Size: + + + + No description... Không có mô tả... - + Click here if you like the content Bấm vào đây nếu bạn thích nội dung này - + Click here if you do not like the content Bấm vào đây nếu bạn không thích nội dung này - Tags: - Từ khóa: + Từ khóa: - + Subscribtions: Đăng ký: - + Open In Steam Mở trên Steam - + Subscribed! Đã đăng ký! - + Subscribe Đăng ký @@ -2326,97 +2347,107 @@ Workshop - + Loading Đang tải - + Download now! Tải xuống ngay! - + Downloading... Đang tải xuống... - + Details Chi tiết - + Open In Steam Mở trên Steam - + Search for Wallpaper and Widgets... Tìm hình nền & cảnh... - + Open Workshop in Steam - + Open GameHub in Steam - + Ranked By Vote Xếp hạng bởi số phiếu. - + Publication Date Ngày tải lên - + Ranked By Trend Xếp hạng bởi trend - + Favorited By Friends Được yêu thích bởi bạn bè - + Created By Friends Tạo bởi bạn bè - + Created By Followed Users Tạo bởi người đã theo dỗi - + Not Yet Rated Chưa được xếp hạng - + Total VotesAsc ???? - + Votes Up ????? Số phiếu đang lên cao - + Total Unique Subscriptions Tổng số đăng ký duy nhất + + + Back + Quay lại + + + + Forward + + WorkshopItem @@ -2425,12 +2456,12 @@ Tải xuống - + Successfully subscribed to Workshop Item! Đăng ký thành công mục Workshop! - + Download complete! Tải xuống thành công! @@ -2438,7 +2469,7 @@ XMLNewsfeed - + News & Patchnotes Tin tức & Ghi chú diff --git a/ScreenPlay/translations/ScreenPlay_zh_cn.qm b/ScreenPlay/translations/ScreenPlay_zh_cn.qm index 4d693d64..2adab715 100644 Binary files a/ScreenPlay/translations/ScreenPlay_zh_cn.qm and b/ScreenPlay/translations/ScreenPlay_zh_cn.qm differ diff --git a/ScreenPlay/translations/ScreenPlay_zh_cn.ts b/ScreenPlay/translations/ScreenPlay_zh_cn.ts index 28fbce0f..b1faf657 100644 --- a/ScreenPlay/translations/ScreenPlay_zh_cn.ts +++ b/ScreenPlay/translations/ScreenPlay_zh_cn.ts @@ -73,31 +73,31 @@ Community + News + 新闻 + + + Wiki 维基 - + Forum 论坛 - + Issue List 问题列表 - - Release Notes - 发布日志 + + Contribute + 贡献 - - Contribution Guide - 怎么贡献 - - - + Steam Workshop 创意工坊 @@ -671,7 +671,7 @@ You do not share any rights and nobody is allowed to use or remix it (Not recommended). Can also used to credit work others. - 您不分享任何权限,没有人可以使用或改编它(不推荐)。Can also used to credit work others. + 您不分享任何权限,没有人可以使用或改编它(不推荐)。这也可用于计入他人的作品。 @@ -681,7 +681,7 @@ Your monitor setup changed! Please configure your wallpaper again. 您的显示器设置已更改! - 请再次配置您的壁纸。 + 请重新配置您的壁纸。 @@ -729,25 +729,35 @@ Navigation - + All 全部 - + Scenes 场景 - + Videos 视频 - + Widgets 物件 + + + Install Date Ascending + 安装日期↓ + + + + Install Date Descending + 安装日期↑ + Subscribed items: @@ -1005,7 +1015,7 @@ Portuguese (Brazil) - + 英语(巴西) @@ -1093,62 +1103,62 @@ 您好,我是Elias Steurer,也叫Kelteseth,我是ScreenPlay的开发者。感谢您使用我的软件。您可以在这里关注我,接收ScreenPlay的更新。 - + Version 版本 - + ScreenPlay Build Version ScreenPlay编译版本 - + Open Changelog 打开更改日志。 - + Third Party Software 第三方软件 - + ScreenPlay would not be possible without the work of others. A big thank you to: ScreenPlay离不开一些人的帮助。非常感谢您们: - + Licenses 许可证 - + Logs 日志 - + If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime. 如果您的ScreenPlay出错,这是个很好的查错方式。它显示所有的日志和运行时警告。 - + Show Logs 显示日志 - + Data Protection 数据保护 - + We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others! 我们使用您的数据提升ScreenPlay的体验。我们承诺不出售或分享这些匿名信息! - + Privacy 隐私 @@ -1219,52 +1229,47 @@ 设置壁纸 - - Project size: - 项目大小: - - - + MB 兆字节 - + + Size: + 大小: + + + No description... 没有简介... - + Click here if you like the content 如果您喜欢它,点这里! - + Click here if you do not like the content 如果您不喜欢它,点这里 - - Tags: - 标签: - - - + Subscribtions: 订阅: - + Open In Steam 在Steam打开 - + Subscribed! 已订阅! - + Subscribe 订阅 @@ -2084,109 +2089,115 @@ Workshop - + Loading 加载中 - + Download now! 开始下载! - + Downloading... 下载中... - + Details 查看详情 - + Open In Steam 在Steam打开 - + Search for Wallpaper and Widgets... 搜索壁纸和物件... - + Open Workshop in Steam 在Steam中打开创意工坊 - + Open GameHub in Steam 在Steam中打开游戏社区 - + Ranked By Vote 评分最好 - + Publication Date 发布日期 - + Ranked By Trend 评分趋势 - + Favorited By Friends 好友收藏 - + Created By Friends 好友创建 - + Created By Followed Users 已关注的 - + Not Yet Rated 尚未评分 - + Total VotesAsc 按总票数升序 - + Votes Up 评分上升 - + Total Unique Subscriptions 总订阅量 + + + Back + 返回 + + + + Forward + 分享 + WorkshopItem - Download - 下载 - - - + Successfully subscribed to Workshop Item! 成功订阅创意工坊物品! - + Download complete! 下载完成! @@ -2194,7 +2205,7 @@ XMLNewsfeed - + News & Patchnotes 新闻和更改日志 diff --git a/ScreenPlaySDK/inc/screenplaysdk.h b/ScreenPlaySDK/inc/screenplaysdk.h index 2eca5c6f..11c5ce06 100644 --- a/ScreenPlaySDK/inc/screenplaysdk.h +++ b/ScreenPlaySDK/inc/screenplaysdk.h @@ -85,6 +85,7 @@ public slots: void error(QLocalSocket::LocalSocketError socketError); void redirectMessage(QByteArray& msg); void pingAlive(); + void start(); void setType(QString type) { @@ -136,9 +137,6 @@ signals: const QString type, const bool checkWallpaperVisible); -private: - void init(); - private: QLocalSocket m_socket; diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index 9fa7ad1b..04147e7c 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -6,7 +6,6 @@ static ScreenPlaySDK* global_sdkPtr = nullptr; ScreenPlaySDK::ScreenPlaySDK(QQuickItem* parent) : QQuickItem(parent) { - init(); } ScreenPlaySDK::ScreenPlaySDK( @@ -17,10 +16,9 @@ ScreenPlaySDK::ScreenPlaySDK( , m_type { type } , m_appID { appID } { - init(); } -void ScreenPlaySDK::init() +void ScreenPlaySDK::start() { // Redirect all messages from this to ScreenPlay global_sdkPtr = this; @@ -36,7 +34,7 @@ void ScreenPlaySDK::init() // If the wallpaper never connects it will never get the // disconnect event. We can savely assume no connection will // be made after 1 second timeout. - QTimer::singleShot(1000, [this]() { + QTimer::singleShot(1000, this, [this]() { if (m_socket.state() != QLocalSocket::ConnectedState) { m_socket.disconnectFromServer(); emit sdkDisconnected(); @@ -122,7 +120,7 @@ void ScreenPlaySDK::readyRead() qWarning() << "Command replaced contained bad volume float value: " << volumeParsed; } - qWarning() + qInfo() << type << fillMode << volumeParsed @@ -142,9 +140,7 @@ void ScreenPlaySDK::readyRead() void ScreenPlaySDK::error(QLocalSocket::LocalSocketError socketError) { - if (socketError == QLocalSocket::LocalSocketError::ConnectionRefusedError) { - QCoreApplication::quit(); - } + emit sdkDisconnected(); } void ScreenPlaySDK::redirectMessage(QByteArray& msg) @@ -172,8 +168,8 @@ void ScreenPlaySDK::ScreenPlaySDK::redirectMessageOutputToMainWindow(QtMsgType t return; QByteArray localMsg = msg.toLocal8Bit(); - QByteArray file = "File: " + QByteArray(context.file) + ", "; - QByteArray line = "in line " + QByteArray::number(context.line) + ", "; + localMsg += "\nFile: " + QByteArray(context.file) + ", "; + localMsg += "\nin line " + QByteArray::number(context.line) + ", "; global_sdkPtr->redirectMessage(localMsg); } diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/util.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/util.h index dbb0b4a2..fcd691b2 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/util.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/util.h @@ -63,4 +63,5 @@ QStringList getAvailableTypes(); QStringList getAvailableFillModes(); bool isWallpaper(const ScreenPlay::InstalledType::InstalledType type); bool isWidget(const ScreenPlay::InstalledType::InstalledType type); +std::optional> parseStringToIntegerList(const QString string); } diff --git a/ScreenPlayUtil/src/util.cpp b/ScreenPlayUtil/src/util.cpp index e5f9265b..cd8948b3 100644 --- a/ScreenPlayUtil/src/util.cpp +++ b/ScreenPlayUtil/src/util.cpp @@ -29,6 +29,9 @@ std::optional openJsonFileToObject(const QString& path) return jsonDocument.object(); } +/*! + \brief . +*/ bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate) { QFile configTmp; @@ -248,6 +251,9 @@ QString toLocal(const QString& url) return QUrl(url).toLocalFile(); } +/*! + \brief . +*/ QStringList getAvailableWallpaper() { return { @@ -260,6 +266,9 @@ QStringList getAvailableWallpaper() }; } +/*! + \brief . +*/ QStringList getAvailableWidgets() { return { @@ -268,11 +277,17 @@ QStringList getAvailableWidgets() }; } +/*! + \brief . +*/ QStringList getAvailableTypes() { return { getAvailableWallpaper() + getAvailableWidgets() }; } +/*! + \brief . +*/ bool isWallpaper(const ScreenPlay::InstalledType::InstalledType type) { @@ -286,6 +301,9 @@ bool isWallpaper(const ScreenPlay::InstalledType::InstalledType type) || type == InstalledType::GodotWallpaper); } +/*! + \brief . +*/ bool isWidget(const ScreenPlay::InstalledType::InstalledType type) { @@ -294,10 +312,36 @@ bool isWidget(const ScreenPlay::InstalledType::InstalledType type) return (type == InstalledType::QMLWidget || type == InstalledType::HTMLWidget); } +/*! + \brief See https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit +*/ QStringList getAvailableFillModes() { - // https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit return { "stretch", "fill", "contain", "cover", "scale-down" }; } +/*! + \brief parseIntList parses a list of string separated with a comma + "1,2,3". IMPORTANT: No trailing comma! + */ +std::optional> parseStringToIntegerList(const QString string) +{ + if (string.isEmpty()) + return {}; + + QVector list; + QStringList stringList = string.split(","); + for (const auto& item : stringList) { + bool ok = false; + int val = item.toInt(&ok); + if (!ok) { + qFatal("Could not parse item to Integer!"); + } else { + list.append(val); + } + } + + return list; +} + } diff --git a/ScreenPlayWallpaper/CMakeLists.txt b/ScreenPlayWallpaper/CMakeLists.txt index ffefca00..6eedbcfd 100644 --- a/ScreenPlayWallpaper/CMakeLists.txt +++ b/ScreenPlayWallpaper/CMakeLists.txt @@ -35,6 +35,7 @@ if(WIN32) # Disable console window on Windows # https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true) + target_link_libraries(${PROJECT_NAME} PRIVATE shcore.lib ) endif() if(APPLE) @@ -42,7 +43,8 @@ if(APPLE) target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa") endif() -target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Quick Qt5::Gui Qt5::Widgets Qt5::Core Qt5::WebEngine ScreenPlaySDK ScreenPlayUtil) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Quick Qt5::Gui Qt5::Widgets Qt5::Core Qt5::WebEngine shcore.lib ScreenPlaySDK ScreenPlayUtil) + if(APPLE) diff --git a/ScreenPlayWallpaper/Test.qml b/ScreenPlayWallpaper/Test.qml index 6cca9d96..fd1522fc 100644 --- a/ScreenPlayWallpaper/Test.qml +++ b/ScreenPlayWallpaper/Test.qml @@ -8,6 +8,11 @@ Rectangle { id: root anchors.fill: parent color: Material.color(Material.Grey, Material.Shade800) + border.width: 10 + border.color: "orange" + + signal requestFadeIn + Component.onCompleted: root.requestFadeIn() property int attStrength: 800000 //Emitter @@ -25,7 +30,7 @@ Rectangle { id: ma anchors.fill: parent preventStealing: true - propagateComposedEvents:true + propagateComposedEvents: true hoverEnabled: true Component.onCompleted: { attractor.pointX = parent.width * .5 @@ -34,10 +39,10 @@ Rectangle { onPositionChanged: { setPosition() - } onClicked: { - // setPosition() + + // setPosition() } function setPosition() { attractor.pointX = mouseX - 25 @@ -50,11 +55,9 @@ Rectangle { id: mouseDot property int center: mouseDot.width * .5 width: 10 - y: attractor.pointY - x: attractor.pointX height: width radius: width - + z: 99 color: "orange" } @@ -102,6 +105,21 @@ Rectangle { system: particleSystem opacity: root.imgOpacity } + Text { + id: txtMousePos + property int counter: 0 + text: attractor.pointY + " - " +attractor.pointX + font.pointSize: 32 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + anchors { + horizontalCenter: parent.horizontalCenter + bottom: txtButtonConter.top + bottomMargin: 20 + } + color: "white" + } Text { id: txtButtonConter @@ -125,16 +143,15 @@ Rectangle { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap - anchors.centerIn: parent + anchors.centerIn: parent anchors.margins: 10 color: "white" } - Row { anchors { horizontalCenter: parent.horizontalCenter - top:name.bottom + top: name.bottom topMargin: 20 } spacing: 20 @@ -142,9 +159,9 @@ Rectangle { highlighted: true onClicked: { - focus =false - focus =true - print("Button Clicked!" ) + focus = false + focus = true + print("Button Clicked!") txtButtonConter.counter = txtButtonConter.counter - 1 } text: qsTr("Click me! - 1") @@ -153,24 +170,23 @@ Rectangle { highlighted: true onClicked: { - focus =false - focus =true - print("Button Clicked!" ) + focus = false + focus = true + print("Button Clicked!") txtButtonConter.counter = txtButtonConter.counter } text: qsTr("Click me!") } Button { highlighted: true - focusPolicy: Qt.ClickFocus + focusPolicy: Qt.ClickFocus onClicked: { - print("Button Clicked!" ) + print("Button Clicked!") txtButtonConter.counter = txtButtonConter.counter + 1 } text: qsTr("Click me! +1") } - } WebView { diff --git a/ScreenPlayWallpaper/Wallpaper.qml b/ScreenPlayWallpaper/Wallpaper.qml index e3e509f8..864ab7f2 100644 --- a/ScreenPlayWallpaper/Wallpaper.qml +++ b/ScreenPlayWallpaper/Wallpaper.qml @@ -1,5 +1,6 @@ -import QtQuick 2.14 import QtQml 2.14 +import QtQuick 2.14 +import QtQuick.Controls 2.14 import ScreenPlayWallpaper 1.0 import ScreenPlay.Enums.InstalledType 1.0 import ScreenPlay.Shader 1.0 @@ -27,7 +28,7 @@ Rectangle { function onQmlExit() { if (canFadeByWallpaperFillMode && Wallpaper.canFade) { - imgCover.state = "outExit" + imgCover.state = "exit" } else { Wallpaper.terminate() } @@ -64,7 +65,7 @@ Rectangle { if (oldType === InstalledType.VideoWallpaper) return - imgCover.state = "in" + imgCover.state = "showDefaultBackgroundImage" loader.source = "qrc:/WebView.qml" } } @@ -82,27 +83,28 @@ Rectangle { break case InstalledType.QMLWallpaper: loader.source = Qt.resolvedUrl(Wallpaper.fullContentPath) + fadeIn() break case InstalledType.WebsiteWallpaper: loader.setSource("qrc:/WebsiteWallpaper.qml", { "url": Wallpaper.fullContentPath }) + fadeIn() break case InstalledType.GifWallpaper: loader.setSource("qrc:/GifWallpaper.qml", { "source": Qt.resolvedUrl( Wallpaper.fullContentPath) }) + fadeIn() break } - - fadeIn() } function fadeIn() { Wallpaper.setVisible(true) if (canFadeByWallpaperFillMode && Wallpaper.canFade) { - imgCover.state = "out" + imgCover.state = "hideDefaultBackgroundImage" } else { imgCover.opacity = 0 } @@ -137,35 +139,33 @@ Rectangle { left: parent.left right: parent.right } - state: "in" + state: "showDefaultBackgroundImage" sourceSize.width: Wallpaper.width sourceSize.height: Wallpaper.height source: { if (Qt.platform.os === "windows") { return Qt.resolvedUrl( "file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) - } else { - return "" } } states: [ State { - name: "in" + name: "showDefaultBackgroundImage" PropertyChanges { target: imgCover opacity: 1 } }, State { - name: "out" + name: "hideDefaultBackgroundImage" PropertyChanges { target: imgCover opacity: 0 } }, State { - name: "outExit" + name: "exit" PropertyChanges { target: imgCover opacity: 1 @@ -174,18 +174,24 @@ Rectangle { ] transitions: [ Transition { - from: "out" - to: "in" + from: "showDefaultBackgroundImage" + to: "hideDefaultBackgroundImage" reversible: true - PropertyAnimation { - target: imgCover - duration: 600 - property: "opacity" + + SequentialAnimation { + PauseAnimation { + duration: 100 + } + PropertyAnimation { + target: imgCover + duration: 600 + property: "opacity" + } } }, Transition { - from: "out" - to: "outExit" + from: "hideDefaultBackgroundImage" + to: "exit" reversible: true SequentialAnimation { PropertyAnimation { @@ -234,4 +240,67 @@ Rectangle { } } } + + Pane { + id: debug + visible: Wallpaper.debugMode + enabled: Wallpaper.debugMode + width: parent.width * .3 + height: parent.height * .3 + anchors.centerIn: parent + background: Rectangle { + opacity: .5 + } + + Column { + anchors.fill: parent + anchors.margins: 20 + spacing: 10 + Text { + text: "appID " + Wallpaper.appID + font.pointSize: 14 + } + Text { + text: "basePath " + Wallpaper.basePath + font.pointSize: 14 + } + Text { + text: "fullContentPath " + Wallpaper.fullContentPath + font.pointSize: 14 + } + Text { + text: "fillMode " + Wallpaper.fillMode + font.pointSize: 14 + } + Text { + text: "sdk.type " + Wallpaper.sdk.type + font.pointSize: 14 + } + Text { + text: "sdk.isConnected " + Wallpaper.sdk.isConnected + font.pointSize: 14 + } + Text { + text: "sdk.appID " + Wallpaper.sdk.appID + font.pointSize: 14 + } + Text { + text: "canFadeByWallpaperFillMode " + canFadeByWallpaperFillMode + font.pointSize: 14 + } + Text { + text: "Wallpaper.canFade " + Wallpaper.canFade + font.pointSize: 14 + } + Text { + text: "imgCover.source " + Qt.resolvedUrl( + "file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) + font.pointSize: 14 + } + Text { + text: "imgCover.status " + imgCover.status + font.pointSize: 14 + } + } + } } diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index be88a73c..45690b0c 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -5,6 +5,8 @@ #include #include +#include "ScreenPlayUtil/util.h" + #if defined(Q_OS_WIN) #include "src/winwindow.h" #endif @@ -17,11 +19,9 @@ #include "src/macwindow.h" #endif -#include "screenplaysdk.h" - int main(int argc, char* argv[]) { - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + //QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication app(argc, argv); @@ -32,17 +32,12 @@ int main(int argc, char* argv[]) // If we start with only one argument (app path) // It means we want to test a single wallpaper QStringList argumentList = app.arguments(); + if (argumentList.length() == 1) { - - //Set the monitor number to test - #if defined(Q_OS_WIN) - - WinWindow window1({ 0 }, "test", "appid", "1", "fill", true); - //WinWindow window2({ 1 }, "test", "appid", "1", "fill"); - //WinWindow window3({ 2 }, "test", "appid", "1", "fill"); - - // WinWindow window({ 0 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/qmlParticles", "appid", "1", "fill", true); + WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true); + //WinWindow window2({ 1 }, "test", "appID=xyz", "1", "fill", true, true); + //WinWindow window3({ 2 }, "test", "appID=123", "1", "fill", true,true); #endif #if defined(Q_OS_LINUX) LinuxWindow window({ 0 }, "/home/graphicscore/Desktop/wallpapers/MechaGirl", "appid", "1", "fill", false); @@ -54,48 +49,24 @@ int main(int argc, char* argv[]) return app.exec(); } - // 6 parameter + 1 OS working directory default paramter + // 8 parameter + 1 OS working directory as the first default paramter if (argumentList.length() != 9) { return -3; } - // AppID, Type - ScreenPlaySDK sdk(argumentList.at(3), argumentList.at(6)); + const bool debugMode = false; - QString monitorNumbers = argumentList.at(1); - QStringList activeScreensList = monitorNumbers.split(","); + const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1)); - activeScreensList.removeAll(","); - QVector list; - - if (monitorNumbers.length() == 1) { - bool canParseMonitorNumber = false; - int monitor = monitorNumbers.toInt(&canParseMonitorNumber); - if (!canParseMonitorNumber) { - qFatal("Could not parse monitor id to diplay wallpaper"); - } else { - list.append(monitor); - } - - } else { - - for (const QString& s : activeScreensList) { - bool ok = false; - int val = s.toInt(&ok); - if (!ok) { - qFatal("Could not parse monitor id to diplay wallpaper"); - } else { - list.append(val); - } - } - } - - if (list.empty()) { + if (!activeScreensList.has_value()) return -4; - } - // Args: which monitor, (2) path to project, (3)wallpaper secret to identify the connected socket, (4) volume, (5) fillmode, (6) type, (7) - // See screenplay.h @ScreenPlayWallpaper constructor how the args get created + // See ScreenPlayWallpaper m_appArgumentsList constructor how the args get created + const QString projectFilePath = argumentList.at(2); + const QString appID = argumentList.at(3); + const QString volume = argumentList.at(4); + const QString fillmode = argumentList.at(5); + const QString type = argumentList.at(6); bool okParseCheckWallpaperVisible = false; bool checkWallpaperVisible = argumentList.at(7).toInt(&okParseCheckWallpaperVisible); @@ -105,20 +76,37 @@ int main(int argc, char* argv[]) } #if defined(Q_OS_WIN) - WinWindow window(list, argumentList.at(2), argumentList.at(3), argumentList.at(4), argumentList.at(5), checkWallpaperVisible); - QObject::connect(&sdk, &ScreenPlaySDK::sdkDisconnected, &window, &WinWindow::destroyThis); - QObject::connect(&sdk, &ScreenPlaySDK::incommingMessage, &window, &WinWindow::messageReceived); - QObject::connect(&sdk, &ScreenPlaySDK::replaceWallpaper, &window, &WinWindow::replaceWallpaper); + WinWindow window( + activeScreensList.value(), + projectFilePath, + appID, + volume, + fillmode, + type, + checkWallpaperVisible, + debugMode); #endif #if defined(Q_OS_LINUX) - LinuxWindow window(list, argumentList.at(2), argumentList.at(3), argumentList.at(4), argumentList.at(5), checkWallpaperVisible); + LinuxWindow window( + activeScreensList.value(), + projectPath, + appID, + fillmode, + volume, + checkWallpaperVisible); QObject::connect(&sdk, &ScreenPlaySDK::sdkDisconnected, &window, &LinuxWindow::destroyThis); QObject::connect(&sdk, &ScreenPlaySDK::incommingMessage, &window, &LinuxWindow::messageReceived); #endif #if defined(Q_OS_OSX) - MacWindow window(list, argumentList.at(2), argumentList.at(3), argumentList.at(4), argumentList.at(5)); + MacWindow window( + activeScreensList.value(), + projectPath, + appID, + fillmode, + volume, + checkWallpaperVisible); QObject::connect(&sdk, &ScreenPlaySDK::sdkDisconnected, &window, &MacWindow::destroyThis); QObject::connect(&sdk, &ScreenPlaySDK::incommingMessage, &window, &MacWindow::messageReceived); #endif diff --git a/ScreenPlayWallpaper/src/SPWmainwindow.cpp b/ScreenPlayWallpaper/src/SPWmainwindow.cpp index 23f44d35..92b7cc0a 100644 --- a/ScreenPlayWallpaper/src/SPWmainwindow.cpp +++ b/ScreenPlayWallpaper/src/SPWmainwindow.cpp @@ -158,7 +158,7 @@ MainWindow::MainWindow(int screenAt, QString projectPath, QString id, QString de } }); - QTimer::singleShot(3000, [=]() { + QTimer::singleShot(3000, this, [=]() { ShowWindow(m_hwnd, SW_SHOWNOACTIVATE); }); diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index fb63aae2..788bcbfc 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -6,12 +6,17 @@ BaseWindow::BaseWindow(QObject* parent) } BaseWindow::BaseWindow( - const QString& projectFilePath, const QVector activeScreensList, - const bool checkWallpaperVisible) + const QString& projectFilePath, + const QString& type, + const bool checkWallpaperVisible, + const QString& appID, + const bool debugMode) : QObject(nullptr) , m_checkWallpaperVisible(checkWallpaperVisible) , m_activeScreensList(activeScreensList) + , m_debugMode(debugMode) + , m_sdk(std::make_unique(appID, type)) { QApplication::instance()->installEventFilter(this); @@ -24,6 +29,13 @@ BaseWindow::BaseWindow( qmlRegisterType("ScreenPlay.Wallpaper", 1, 0, "Wallpaper"); + if (!appID.contains("appID=")) { + qInfo() << "Invalid appID: "<< appID; + qFatal("AppID does not contain appID="); + } + + setAppID(appID); + setOSVersion(QSysInfo::productVersion()); if (projectFilePath == "test") { diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index 7a71d765..79c0fa89 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -48,12 +48,22 @@ #include "ScreenPlayUtil/util.h" +#include "screenplaysdk.h" + +#include + class BaseWindow : public QObject { Q_OBJECT public: BaseWindow(QObject* parent = nullptr); - BaseWindow(const QString& projectFilePath, const QVector activeScreensList, const bool checkWallpaperVisible); + BaseWindow( + const QVector activeScreensList, + const QString& projectFilePath, + const QString& type, + const bool checkWallpaperVisible, + const QString& appID, + const bool debugMode); Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) @@ -68,6 +78,7 @@ public: Q_PROPERTY(bool isPlaying READ isPlaying WRITE setIsPlaying NOTIFY isPlayingChanged) Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool canFade READ canFade WRITE setCanFade NOTIFY canFadeChanged) + Q_PROPERTY(bool debugMode READ debugMode WRITE setDebugMode NOTIFY debugModeChanged) // Save performance by checking if the wallpaper is visible (video wallpaper only for now) Q_PROPERTY(bool checkWallpaperVisible READ checkWallpaperVisible WRITE setCheckWallpaperVisible NOTIFY checkWallpaperVisibleChanged) @@ -80,6 +91,8 @@ public: Q_PROPERTY(ScreenPlay::InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(QString OSVersion READ OSVersion WRITE setOSVersion NOTIFY OSVersionChanged) + Q_PROPERTY(ScreenPlaySDK* sdk READ sdk WRITE setSdk NOTIFY sdkChanged) + bool loops() const { return m_loops; } float volume() const { return m_volume; } bool isPlaying() const { return m_isPlaying; } @@ -98,6 +111,8 @@ public: bool checkWallpaperVisible() const { return m_checkWallpaperVisible; } bool visualsPaused() const { return m_visualsPaused; } QString basePath() const { return m_basePath; } + bool debugMode() const { return m_debugMode; } + ScreenPlaySDK* sdk() const { return m_sdk.get(); } signals: void qmlExit(); @@ -124,6 +139,8 @@ signals: void checkWallpaperVisibleChanged(bool checkWallpaperVisible); void visualsPausedChanged(bool visualsPaused); void basePathChanged(QString basePath); + void debugModeChanged(bool debugMode); + void sdkChanged(ScreenPlaySDK* sdk); public slots: virtual void destroyThis() { } @@ -307,6 +324,22 @@ public slots: emit basePathChanged(m_basePath); } + void setDebugMode(bool debugMode) + { + if (m_debugMode == debugMode) + return; + m_debugMode = debugMode; + emit debugModeChanged(debugMode); + } + + void setSdk(ScreenPlaySDK* sdk) + { + if (m_sdk.get() == sdk) + return; + m_sdk.reset(sdk); + emit sdkChanged(sdk); + } + private: void setupLiveReloading(); @@ -335,4 +368,6 @@ private: QFileSystemWatcher m_fileSystemWatcher; QSysInfo m_sysinfo; QString m_basePath; + bool m_debugMode = false; + std::unique_ptr m_sdk; }; diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index f02c03d9..d528f3d9 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -1,6 +1,41 @@ #include "winwindow.h" - +#include "WinUser.h" #include "qqml.h" +#include +#include +#include +#include +#include + +struct WinMonitorStats { + std::vector iMonitors; + std::vector hMonitors; + std::vector hdcMonitors; + std::vector rcMonitors; + std::vector scaleFactor; + std::vector> sizes; + + static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, + LPARAM pData) + { + WinMonitorStats* pThis = reinterpret_cast(pData); + auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID; + GetScaleFactorForMonitor(hMon, &scaleFactor); + + UINT x = 0; + UINT y = 0; + GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y); + pThis->sizes.push_back({ x, y }); + pThis->scaleFactor.push_back(scaleFactor); + pThis->hMonitors.push_back(hMon); + pThis->hdcMonitors.push_back(hdc); + pThis->rcMonitors.push_back(*lprcMonitor); + pThis->iMonitors.push_back(pThis->hdcMonitors.size()); + return TRUE; + } + + WinMonitorStats() { EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); } +}; BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam) { @@ -17,6 +52,7 @@ BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam) HHOOK g_mouseHook; QPoint g_LastMousePosition { 0, 0 }; +QPoint g_globalOffset { 0, 0 }; QQuickView* g_winGlobalHook = nullptr; LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam) @@ -62,12 +98,13 @@ LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam) QApplication::sendEvent(g_winGlobalHook, &event); if (type == QMouseEvent::Type::MouseButtonPress) { - - QTimer::singleShot(100, []() { - auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, Qt::MouseButton::LeftButton, Qt::LeftButton, {}); - QApplication::sendEvent(g_winGlobalHook, &eventRelease); - }); } + QTimer::singleShot(100, [&]() { + //auto eventPress = QMouseEvent(QMouseEvent::Type::MouseButtonPress, g_LastMousePosition, mouseButton, mouseButtons, {}); + //qInfo() << mouseButton << QApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y(); + auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, mouseButton, mouseButtons, {}); + QApplication::sendEvent(g_winGlobalHook, &eventRelease); + }); return CallNextHookEx(g_mouseHook, nCode, wParam, lParam); } @@ -92,25 +129,43 @@ void WinWindow::setupWindowMouseHook() WinWindow::WinWindow( const QVector& activeScreensList, - const QString& projectPath, - const QString& id, + const QString& projectFilePath, + const QString& appID, const QString& volume, const QString& fillmode, - const bool checkWallpaperVisible) - : BaseWindow(projectPath, activeScreensList, checkWallpaperVisible) + const QString& type, + const bool checkWallpaperVisible, + const bool debugMode) + : BaseWindow( + activeScreensList, + projectFilePath, + type, + checkWallpaperVisible, + appID, + debugMode) { + auto* guiAppInst = dynamic_cast(QApplication::instance()); + connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); + connect(sdk(), &ScreenPlaySDK::sdkDisconnected, this, &WinWindow::destroyThis); + connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &WinWindow::messageReceived); + connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &WinWindow::replaceWallpaper); + connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); + + const auto screens = QApplication::screens(); + for (const auto& screen : screens) { + connect(screen, &QScreen::geometryChanged, this, &WinWindow::configureWindowGeometry); + } - qRegisterMetaType(); - qRegisterMetaType(); m_windowsDesktopProperties = std::make_unique(); m_windowHandle = reinterpret_cast(m_window.winId()); - if (!IsWindow(m_windowHandle)) { qFatal("Could not get a valid window handle!"); } - ShowWindow(m_windowHandleWorker, SW_HIDE); - setAppID(id); + qRegisterMetaType(); + qRegisterMetaType(); bool ok = false; float volumeParsed = volume.toFloat(&ok); @@ -121,41 +176,20 @@ WinWindow::WinWindow( setVolume(volumeParsed); setFillMode(fillmode); - if (!searchWorkerWindowToParentTo()) { - qFatal("No worker window found"); - } - - // WARNING: Setting Window flags must be called *here*! - SetWindowLongPtr(m_windowHandle, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT); - SetWindowLongPtr(m_windowHandle, GWL_STYLE, WS_POPUPWINDOW); - - // Windows coordante system begins at 0x0 at the - // main monitors upper left and not at the most left top monitor - calcOffsets(); - - // Ether for one Screen or for all - if ((QApplication::screens().length() == activeScreensList.length()) && (activeScreensList.length() != 1)) { - setupWallpaperForAllScreens(); - } else if (activeScreensList.length() == 1) { - setupWallpaperForOneScreen(activeScreensList.at(0)); - setCanFade(true); - } else if (activeScreensList.length() > 1) { - setupWallpaperForMultipleScreens(activeScreensList); - } - - setWidth(m_window.width()); - setHeight(m_window.height()); - qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); - // Instead of setting "renderType: Text.NativeRendering" every time - // we can set it here once :) - m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); - m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); - m_window.setSource(QUrl("qrc:/Wallpaper.qml")); - m_window.hide(); - - QObject::connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); + configureWindowGeometry(); + bool hasWindowScaling = false; + for (int i = 0; i < screens.count(); i++) { + if (getScaling(i) != 1) { + hasWindowScaling = true; + break; + } + } + if (hasWindowScaling) { + qInfo() << "scaling"; + configureWindowGeometry(); + } // We do not support autopause for multi monitor wallpaper if (this->activeScreensList().length() == 1) { @@ -164,21 +198,22 @@ WinWindow::WinWindow( } } - QTimer::singleShot(1000, [this]() { + QTimer::singleShot(1000, this, [&]() { setupWindowMouseHook(); }); + + sdk()->start(); } void WinWindow::setVisible(bool show) { if (show) { - if (!ShowWindow(m_windowHandle, SW_SHOW)) { + if (!ShowWindow(m_windowHandle, SW_SHOW)) qDebug() << "Cannot set window handle SW_SHOW"; - } + } else { - if (!ShowWindow(m_windowHandle, SW_HIDE)) { + if (!ShowWindow(m_windowHandle, SW_HIDE)) qDebug() << "Cannot set window handle SW_HIDE"; - } } } @@ -187,26 +222,62 @@ void WinWindow::destroyThis() emit qmlExit(); } -void WinWindow::calcOffsets() +struct sEnumInfo { + int iIndex; + HMONITOR hMonitor; +}; + +BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { - for (int i = 0; i < QApplication::screens().count(); i++) { - QScreen* screen = QApplication::screens().at(i); - if (screen->availableGeometry().x() < 0) { - m_windowOffsetX += (screen->availableGeometry().x() * -1); - } - if (screen->availableGeometry().y() < 0) { - m_windowOffsetY += (screen->availableGeometry().y() * -1); - } + auto* info = (sEnumInfo*)dwData; + if (--info->iIndex < 0) { + info->hMonitor = hMonitor; + return FALSE; } + return TRUE; } void WinWindow::setupWallpaperForOneScreen(int activeScreen) { - QScreen* screen = QApplication::screens().at(activeScreen); - QRect screenRect = screen->geometry(); + const QRect screenRect = QApplication::screens().at(activeScreen)->geometry(); - if (!SetWindowPos(m_windowHandle, nullptr, screenRect.x() + m_windowOffsetX - 1, screenRect.y() + m_windowOffsetY - 1, screenRect.width() + 2, screenRect.height() + 2, SWP_HIDEWINDOW)) { - qFatal("Could not set window pos: "); + const float scaling = 1; //getScaling(activeScreen); + for (int i = 0; i < QApplication::screens().count(); i++) { + // qInfo() << i << "scaling " << getScaling(i) << QApplication::screens().at(i)->geometry(); + } + + // qInfo() << activeScreen << "Monitor 0" << getScaling(0) << QApplication::screens().at(0)->geometry(); + // qInfo() << activeScreen << "Monitor 1" << getScaling(1) << QApplication::screens().at(1)->geometry(); + + WinMonitorStats Monitors; + int width = std::abs(Monitors.rcMonitors[activeScreen].right - Monitors.rcMonitors[activeScreen].left); + int height = std::abs(Monitors.rcMonitors[activeScreen].top - Monitors.rcMonitors[activeScreen].bottom); + //qInfo() << "scaling " << scaling << width << height << " activeScreen " << activeScreen; + //qInfo() << "scaling " << scaling << screenRect.width() << screenRect.height() << " activeScreen " << activeScreen; + + const int boderWidth = 2; + const int borderOffset = -1; + // Needs to be set like to this work. I do not know why... + if (!SetWindowPos( + m_windowHandle, + nullptr, + Monitors.rcMonitors[activeScreen].left + borderOffset, + Monitors.rcMonitors[activeScreen].top + borderOffset, + width + boderWidth, + height + boderWidth, + SWP_HIDEWINDOW)) { + qFatal("Could not set window pos"); + } + + if (!SetWindowPos( + m_windowHandle, + nullptr, + screenRect.x() + m_zeroPoint.x() + borderOffset, + screenRect.y() + m_zeroPoint.y() + borderOffset, + screenRect.width() * scaling + boderWidth, + screenRect.height() * scaling + boderWidth, + SWP_HIDEWINDOW)) { + qFatal("Could not set window pos"); } if (SetParent(m_windowHandle, m_windowHandleWorker) == nullptr) { qFatal("Could not attach to parent window"); @@ -252,7 +323,7 @@ void WinWindow::setupWallpaperForMultipleScreens(const QVector& activeScree rect.setX(upperLeftScreen->geometry().x()); rect.setY(upperLeftScreen->geometry().y()); - if (!SetWindowPos(m_windowHandle, nullptr, rect.x() + m_windowOffsetX, rect.y() + m_windowOffsetY, rect.width(), rect.height(), SWP_SHOWWINDOW)) { + if (!SetWindowPos(m_windowHandle, nullptr, rect.x() + m_zeroPoint.x(), rect.y() + m_zeroPoint.y(), rect.width(), rect.height(), SWP_SHOWWINDOW)) { qFatal("Could not set window pos: "); } if (SetParent(m_windowHandle, m_windowHandleWorker) == nullptr) { @@ -271,11 +342,83 @@ bool WinWindow::searchWorkerWindowToParentTo() return EnumWindows(SearchForWorkerWindow, reinterpret_cast(&m_windowHandleWorker)); } -QString printWindowNameByhWnd(HWND hWnd) +float WinWindow::getScaling(const int monitorIndex) { - std::wstring title(GetWindowTextLength(hWnd) + 1, L'\0'); - GetWindowTextW(hWnd, &title[0], title.size()); - return QString::fromStdWString(title); + // screen->logicalDotsPerInch() + // 100% - 96 + // 125% - 120 + // 150% - 144 + // 175% - 168 + // 200% - 192 + QScreen* screen = QApplication::screens().at(monitorIndex); + const int factor = screen->logicalDotsPerInch(); + switch (factor) { + case 96: + return 1; + case 120: + return 1.25; + case 144: + return 1.5; + case 168: + return 1.75; + case 192: + return 2; + case 216: + return 2.25; + case 240: + return 2.5; + case 288: + return 3; + case 336: + return 3.5; + default: + qWarning() << "Monitor with factor: " << factor << " detected! This is not supported!"; + return 1; + } +} + +void WinWindow::configureWindowGeometry() +{ + ShowWindow(m_windowHandle, SW_HIDE); + + if (!searchWorkerWindowToParentTo()) { + qFatal("No worker window found"); + } + + RECT rect {}; + if (!GetWindowRect(m_windowHandleWorker, &rect)) { + qFatal("Unable to get WindoeRect from worker"); + } + + // Windows coordante system begins at 0x0 at the + // main monitors upper left and not at the most left top monitor. + // This can be easily read from the worker window. + m_zeroPoint = { std::abs(rect.left), std::abs(rect.top) }; + g_globalOffset = m_zeroPoint; + + // WARNING: Setting Window flags must be called *here*! + SetWindowLongPtr(m_windowHandle, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT); + SetWindowLongPtr(m_windowHandle, GWL_STYLE, WS_POPUPWINDOW); + + // Ether for one Screen or for all + if ((QApplication::screens().length() == activeScreensList().length()) && (activeScreensList().length() != 1)) { + setupWallpaperForAllScreens(); + } else if (activeScreensList().length() == 1) { + setupWallpaperForOneScreen(activeScreensList().at(0)); + setCanFade(true); + } else if (activeScreensList().length() > 1) { + setupWallpaperForMultipleScreens(activeScreensList()); + } + + setWidth(m_window.width()); + setHeight(m_window.height()); + + // Instead of setting "renderType: Text.NativeRendering" every time + // we can set it here once :) + m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); + m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); + m_window.setSource(QUrl("qrc:/Wallpaper.qml")); + m_window.hide(); } BOOL CALLBACK FindTheDesiredWnd(HWND hWnd, LPARAM lParam) @@ -288,11 +431,6 @@ BOOL CALLBACK FindTheDesiredWnd(HWND hWnd, LPARAM lParam) return true; // keep enumerating } -struct sEnumInfo { - int iIndex = 0; - HMONITOR hMonitor = NULL; -}; - BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { Q_UNUSED(hdcMonitor) diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index b48231d8..c17595a5 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -60,11 +60,12 @@ class WinWindow : public BaseWindow { public: explicit WinWindow( const QVector& activeScreensList, - const QString& projectPath, - const QString& id, + const QString& projectFilePath, + const QString& appID, const QString& volume, - const QString& fillmode, - const bool checkWallpaperVisible); + const QString& fillmode, const QString &type, + const bool checkWallpaperVisible, + const bool debugMode = false); WindowsDesktopProperties* windowsDesktopProperties() const { return m_windowsDesktopProperties.get(); } @@ -93,16 +94,18 @@ private: void setupWallpaperForMultipleScreens(const QVector& activeScreensList); void setupWindowMouseHook(); bool searchWorkerWindowToParentTo(); + void configureWindowGeometry(); + float getScaling(const int monitorIndex); private slots: void checkForFullScreenWindow(); private: - int m_windowOffsetX = 0; - int m_windowOffsetY = 0; + QPoint m_zeroPoint {}; QQuickView m_window; - HWND m_windowHandle; - HWND m_windowHandleWorker; + HWND m_windowHandle {}; + HWND m_windowHandleWorker {}; QTimer m_checkForFullScreenWindowTimer; + QTimer m_reconfigureTimer; std::unique_ptr m_windowsDesktopProperties; }; diff --git a/ScreenPlayWidget/src/widgetwindow.cpp b/ScreenPlayWidget/src/widgetwindow.cpp index 0b73ba00..3ff7675e 100644 --- a/ScreenPlayWidget/src/widgetwindow.cpp +++ b/ScreenPlayWidget/src/widgetwindow.cpp @@ -69,7 +69,7 @@ WidgetWindow::WidgetWindow( m_window.show(); // Do not trigger position changed save reuqest on startup - QTimer::singleShot(1000, [=, this]() { + QTimer::singleShot(1000, this, [=, this]() { // We limit ourself to only update the position every 500ms! auto sendPositionUpdate = [this]() { m_positionMessageLimiter.stop(); diff --git a/Tools/install_dependencies_linux_mac.sh b/Tools/install_dependencies_linux_mac.sh index c2ad318a..2de3c045 100644 --- a/Tools/install_dependencies_linux_mac.sh +++ b/Tools/install_dependencies_linux_mac.sh @@ -5,8 +5,8 @@ cd .. git clone https://github.com/microsoft/vcpkg.git ScreenPlay-vcpkg cd ScreenPlay-vcpkg git pull -# master 25.01.2021 - fc0d6b28006e0607a6b9871641ec48925274e079 -git checkout fc0d6b28006e0607a6b9871641ec48925274e079 +# master 27.03.2021 - 9f6157a +git checkout 9f6157a chmod +x bootstrap-vcpkg.sh ./bootstrap-vcpkg.sh chmod +x vcpkg diff --git a/Tools/install_dependencies_windows.bat b/Tools/install_dependencies_windows.bat index 8bbff678..4de27ec6 100644 --- a/Tools/install_dependencies_windows.bat +++ b/Tools/install_dependencies_windows.bat @@ -5,8 +5,8 @@ cd .. git clone https://github.com/microsoft/vcpkg.git ScreenPlay-vcpkg cd ScreenPlay-vcpkg git pull -rem master 25.01.2021 - fc0d6b28006e0607a6b9871641ec48925274e079 -git checkout fc0d6b28006e0607a6b9871641ec48925274e079 +rem master 27.03.2021 - 9f6157a +git checkout 9f6157a call bootstrap-vcpkg.bat rem Install vcpkg dependencies