1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-03 09:09:48 +02:00

Refactor wallpaper connection

Change sdk connection from shared to unqiue ptr
to make sure to only have one connection alive at
every time. This fixes to removal of wallpaper because
of a bug a shared connection as set in the monitorlistmodel.

The SDK connection is now part of the ScreenPlayWallpaper/Widget.
This commit is contained in:
Elias Steurer 2021-04-18 17:23:21 +02:00
parent 36a59518e9
commit e7f1e61d33
20 changed files with 373 additions and 320 deletions

View File

@ -205,7 +205,7 @@ 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

View File

@ -76,7 +76,6 @@ int main(int argc, char* argv[])
ScreenPlay::App app;
if (app.m_isAnotherScreenPlayInstanceRunning) {
return 0;
} else {

View File

@ -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<ScreenPlayWallpaper>& wallpaper, const QVector<int> monitors)
void MonitorListModel::setWallpaperMonitor(const std::shared_ptr<ScreenPlayWallpaper>& wallpaper, const QVector<int> monitors)
{
for (const int monitor : monitors) {

View File

@ -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<ScreenPlayWallpaper>& wallpaper,
void setWallpaperMonitor(
const std::shared_ptr<ScreenPlayWallpaper>& wallpaper,
const QVector<int> monitors);
std::optional<QString> getAppIDByMonitorIndex(const int index) const;

View File

@ -146,7 +146,7 @@ bool ScreenPlayManager::createWallpaper(
fillMode,
type,
m_settings->checkWallpaperVisible());
m_monitorListModel->setWallpaperActiveMonitor(wallpaper, monitorIndex);
m_monitorListModel->setWallpaperMonitor(wallpaper, monitorIndex);
return true;
}
@ -170,13 +170,13 @@ bool 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;
}
@ -217,7 +217,7 @@ bool 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;
@ -228,72 +228,46 @@ bool ScreenPlayManager::createWidget(
}
/*!
\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<SDKConnection>& 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;
}
for (auto& client : m_screenPlayWallpapers) {
if (removeWallpaper(client->appID())) {
decreaseActiveWallpaperCounter();
}
}
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())) {
decreaseActiveWidgetsCounter();
}
}
emit requestSaveProfiles();
return true;
}
/*!
@ -305,39 +279,16 @@ 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.
*/
@ -372,13 +323,14 @@ bool ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q
*/
void ScreenPlayManager::setAllWallpaperValue(const QString& key, const QString& value)
{
for (const std::shared_ptr<ScreenPlayWallpaper>& uPtrWallpaper : qAsConst(m_screenPlayWallpapers)) {
setWallpaperValue(uPtrWallpaper->appID(), key, value);
for (auto& wallpaper : m_screenPlayWallpapers) {
setWallpaperValue(wallpaper->appID(), key, value);
}
}
/*!
\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
{
@ -395,108 +347,90 @@ ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID
*/
void ScreenPlayManager::newConnection()
{
auto connection = std::make_shared<SDKConnection>(m_server->nextPendingConnection());
auto connection = std::make_unique<SDKConnection>(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<SDKConnection> 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!";
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_clients.append(connection);
m_unconnectedClients.push_back(std::move(connection));
}
/*!
\brief Closes all wallpaper connection with the following type:
\list
\li videoWallpaper
\li qmlWallpaper
\li htmlWallpaper
\li godotWallpaper
\endlist
\brief Removes a wallpaper from the given appID. Returns true on success.
*/
bool ScreenPlayManager::closeAllWallpapers()
bool ScreenPlayManager::removeWallpaper(const QString& appID)
{
if (m_screenPlayWallpapers.empty() && m_activeWallpaperCounter == 0) {
qWarning() << "Cannot close connection on empty client list!";
return true;
}
for (auto& wallpaper : m_screenPlayWallpapers) {
if (wallpaper->appID() == appID) {
if (!closeConntectionByType(ScreenPlayUtil::getAvailableWallpaper())) {
return false;
}
setActiveWallpaperCounter(0);
return true;
}
qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber();
/*!
\brief Closes all widgets connection with the following type:
\list
\li qmlWidget
\li htmlWidget
\li standaloneWidget
\endlist
*/
bool ScreenPlayManager::closeAllWidgets()
{
if (m_screenPlayWidgets.empty() && m_activeWidgetsCounter == 0) {
qWarning() << "Cannot close connection on empty client list!";
return true;
}
// 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());
if (!closeConntectionByType(ScreenPlayUtil::getAvailableWidgets())) {
return false;
}
setActiveWidgetsCounter(0);
return true;
}
/*!
\brief Closes a connection by type. Used only by closeAllWidgets() and closeAllWallpapers()
*/
bool ScreenPlayManager::closeConntectionByType(const QStringList& types)
{
if (m_clients.isEmpty()) {
qWarning() << "Cannot close connection on empty client list!";
return true;
}
for (auto& client : m_clients) {
if (types.contains(client->type(), Qt::CaseInsensitive)) {
if (client->close()) {
decreaseActiveWallpaperCounter();
if (!m_screenPlayWallpapers.removeOne(wallpaper)) {
qWarning() << "Unable to remove Wallpaper from Wallpaper List";
return false;
}
if (!m_clients.removeOne(client)) {
qWarning() << "Cannot close client";
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;
}
/*!
\brief Closes a Wallpaper or Widget connection by the given \a appID.
*/
bool ScreenPlayManager::closeConnection(const QString& appID)
bool ScreenPlayManager::removeWidget(const QString& appID)
{
if (m_clients.isEmpty())
return true;
for (auto& client : m_clients) {
if (client->appID() == appID) {
client->close();
return m_clients.removeOne(client);
}
}
return false;
}
@ -505,7 +439,7 @@ bool ScreenPlayManager::closeConnection(const QString& appID)
*/
void 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);
}
@ -547,27 +481,6 @@ void ScreenPlayManager::saveProfiles()
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 false;
}
/*!
\brief Loads all wallpaper from profiles.json when the version number matches and starts the available wallpaper
*/
@ -602,7 +515,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())
@ -671,5 +584,4 @@ TEST_CASE("Loads profiles.json")
GlobalVariables globalVariables;
ScreenPlayManager manager;
}
}

View File

@ -64,14 +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>& globalVariables,
@ -79,14 +72,19 @@ public:
const std::shared_ptr<GAnalytics>& telemetry,
const std::shared_ptr<Settings>& 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:
@ -114,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 setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value);
void setAllWallpaperValue(const QString& key, const QString& value);
void setWallpaperValue(const QString& appID, const QString& key, const QString& value);
ScreenPlayWallpaper* getWallpaperByAppID(const QString& appID) const;
void newConnection();
bool closeAllWallpapers();
bool 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)
{
@ -181,9 +174,9 @@ public slots:
private:
void loadProfiles();
bool appConnected(const std::shared_ptr<SDKConnection>& connection);
bool checkIsAnotherScreenPlayInstanceRunning();
[[nodiscard]] bool removeWallpaperByAppID(const QString& appID);
bool removeWallpaper(const QString& appID);
bool removeWidget(const QString& appID);
private:
std::shared_ptr<GlobalVariables> m_globalVariables;
@ -195,7 +188,8 @@ private:
QVector<std::shared_ptr<ScreenPlayWallpaper>> m_screenPlayWallpapers;
QVector<std::shared_ptr<ScreenPlayWidget>> m_screenPlayWidgets;
QVector<std::shared_ptr<SDKConnection>> m_clients;
std::vector<std::unique_ptr<SDKConnection>> m_unconnectedClients;
int m_activeWallpaperCounter { 0 };
int m_activeWidgetsCounter { 0 };

View File

@ -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.
*/
@ -112,7 +121,7 @@ bool ScreenPlayWallpaper::start()
QJsonObject ScreenPlayWallpaper::getActiveSettingsJson()
{
QJsonArray screenNumber;
for (const int i : m_screenNumber) {
for (const int i : qAsConst(m_screenNumber)) {
screenNumber.append(i);
}
@ -183,9 +192,9 @@ void ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& v
/*!
\brief Connects to ScreenPlay. Start a alive ping check for every 16 seconds.
*/
void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr<SDKConnection>& connection)
void ScreenPlayWallpaper::setSDKConnection(std::unique_ptr<SDKConnection> connection)
{
m_connection = connection;
m_connection = std::move(connection);
QTimer::singleShot(1000, this, [this]() {
if (playbackRate() != 1.0) {

View File

@ -68,6 +68,7 @@ class ScreenPlayWallpaper : public QObject {
public:
ScreenPlayWallpaper() { }
~ScreenPlayWallpaper();
explicit ScreenPlayWallpaper(
const QVector<int>& screenNumber,
@ -93,7 +94,7 @@ public:
const InstalledType::InstalledType type,
const bool checkWallpaperVisible);
void setSDKConnection(const std::shared_ptr<SDKConnection>& connection);
void setSDKConnection(std::unique_ptr<SDKConnection> connection);
QJsonObject getActiveSettingsJson();
@ -236,7 +237,7 @@ public slots:
private:
const std::shared_ptr<GlobalVariables> m_globalVariables;
std::shared_ptr<SDKConnection> m_connection;
std::unique_ptr<SDKConnection> m_connection;
ProjectSettingsListModel m_projectSettingsListModel;
QVector<int> m_screenNumber;

View File

@ -76,9 +76,9 @@ bool ScreenPlayWidget::start()
/*!
\brief Connects to ScreenPlay. Start a alive ping check for every 16 seconds.
*/
void ScreenPlayWidget::setSDKConnection(const std::shared_ptr<SDKConnection>& connection)
void ScreenPlayWidget::setSDKConnection(std::unique_ptr<SDKConnection> 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") {

View File

@ -48,6 +48,7 @@
#include "sdkconnection.h"
#include <memory>
#include <utility>
namespace ScreenPlay {
@ -82,7 +83,7 @@ public:
InstalledType::InstalledType type() const { return m_type; }
void setSDKConnection(const std::shared_ptr<SDKConnection>& connection);
void setSDKConnection(std::unique_ptr<SDKConnection> connection);
ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; }
@ -147,7 +148,7 @@ signals:
private:
const std::shared_ptr<GlobalVariables> m_globalVariables;
std::shared_ptr<SDKConnection> m_connection;
std::unique_ptr<SDKConnection> m_connection;
ProjectSettingsListModel m_projectSettingsListModel;
QProcess m_process;

View File

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

View File

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

View File

@ -63,4 +63,5 @@ QStringList getAvailableTypes();
QStringList getAvailableFillModes();
bool isWallpaper(const ScreenPlay::InstalledType::InstalledType type);
bool isWidget(const ScreenPlay::InstalledType::InstalledType type);
std::optional<QVector<int>> parseStringToIntegerList(const QString string);
}

View File

@ -29,6 +29,9 @@ std::optional<QJsonObject> 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<QVector<int>> parseStringToIntegerList(const QString string)
{
if (string.isEmpty())
return {};
QVector<int> 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;
}
}

View File

@ -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
@ -234,4 +235,50 @@ 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
}
}
}
}

View File

@ -5,6 +5,8 @@
#include <QtGlobal>
#include <QtWebEngine>
#include "ScreenPlayUtil/util.h"
#if defined(Q_OS_WIN)
#include "src/winwindow.h"
#endif
@ -17,8 +19,6 @@
#include "src/macwindow.h"
#endif
#include "screenplaysdk.h"
int main(int argc, char* argv[])
{
//QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -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({ 1 }, "test", "appid", "1", "fill", true);
//WinWindow window2({ 1 }, "test", "appid", "1", "fill", true);
//WinWindow window3({ 2 }, "test", "appid", "1", "fill", true);
// 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 = true;
QString monitorNumbers = argumentList.at(1);
QStringList activeScreensList = monitorNumbers.split(",");
const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1));
activeScreensList.removeAll(",");
QVector<int> 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

View File

@ -6,12 +6,17 @@ BaseWindow::BaseWindow(QObject* parent)
}
BaseWindow::BaseWindow(
const QString& projectFilePath,
const QVector<int> 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<ScreenPlaySDK>(appID, type))
{
QApplication::instance()->installEventFilter(this);
@ -24,6 +29,13 @@ BaseWindow::BaseWindow(
qmlRegisterType<BaseWindow>("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") {

View File

@ -48,12 +48,22 @@
#include "ScreenPlayUtil/util.h"
#include "screenplaysdk.h"
#include <memory>
class BaseWindow : public QObject {
Q_OBJECT
public:
BaseWindow(QObject* parent = nullptr);
BaseWindow(const QString& projectFilePath, const QVector<int> activeScreensList, const bool checkWallpaperVisible);
BaseWindow(
const QVector<int> 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<ScreenPlaySDK> m_sdk;
};

View File

@ -99,11 +99,11 @@ LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
if (type == QMouseEvent::Type::MouseButtonPress) {
}
QTimer::singleShot(100, [&]() {
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, {});
//qInfo() << mouseButton << QApplication::sendEvent(g_winGlobalHook, &eventRelease);
QApplication::sendEvent(g_winGlobalHook, &eventRelease);
});
return CallNextHookEx(g_mouseHook, nCode, wParam, lParam);
@ -129,20 +129,33 @@ void WinWindow::setupWindowMouseHook()
WinWindow::WinWindow(
const QVector<int>& 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*>(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);
for (auto screen : QApplication::screens()) {
const auto screens = QApplication::screens();
for (const auto& screen : screens) {
connect(screen, &QScreen::geometryChanged, this, &WinWindow::configureWindowGeometry);
}
@ -154,8 +167,6 @@ WinWindow::WinWindow(
qRegisterMetaType<WindowsDesktopProperties*>();
qRegisterMetaType<WinWindow*>();
setAppID(id);
bool ok = false;
float volumeParsed = volume.toFloat(&ok);
if (!ok) {
@ -169,7 +180,7 @@ WinWindow::WinWindow(
configureWindowGeometry();
bool hasWindowScaling = false;
for (int i = 0; i < QApplication::screens().count(); i++) {
for (int i = 0; i < screens.count(); i++) {
if (getScaling(i) != 1) {
hasWindowScaling = true;
break;
@ -180,8 +191,6 @@ WinWindow::WinWindow(
configureWindowGeometry();
}
QObject::connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow);
// We do not support autopause for multi monitor wallpaper
if (this->activeScreensList().length() == 1) {
if (checkWallpaperVisible) {
@ -192,6 +201,8 @@ WinWindow::WinWindow(
QTimer::singleShot(1000, this, [&]() {
setupWindowMouseHook();
});
sdk()->start();
}
void WinWindow::setVisible(bool show)
@ -232,26 +243,28 @@ void WinWindow::setupWallpaperForOneScreen(int activeScreen)
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() << 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();
// 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;
//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,
Monitors.rcMonitors[activeScreen].top,
width,
height,
Monitors.rcMonitors[activeScreen].left + borderOffset,
Monitors.rcMonitors[activeScreen].top + borderOffset,
width + boderWidth,
height + boderWidth,
SWP_HIDEWINDOW)) {
qFatal("Could not set window pos");
}
@ -259,10 +272,10 @@ void WinWindow::setupWallpaperForOneScreen(int activeScreen)
if (!SetWindowPos(
m_windowHandle,
nullptr,
screenRect.x() + m_zeroPoint.x(),
screenRect.y() + m_zeroPoint.y(),
screenRect.width() * scaling,
screenRect.height() * scaling,
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");
}

View File

@ -60,11 +60,12 @@ class WinWindow : public BaseWindow {
public:
explicit WinWindow(
const QVector<int>& 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(); }