1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-14 22:42:34 +02:00

Refactor widget removal/restore

This commit is contained in:
Elias Steurer 2021-05-16 11:57:50 +02:00
parent a78a48bb2e
commit e54e0c2acb
14 changed files with 87 additions and 101 deletions

View File

@ -197,7 +197,7 @@ bool ScreenPlayManager::createWidget(
const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile();
if (path.isEmpty()) {
qWarning() << "Path is empty, Abort! String: " << absoluteStoragePath;
qWarning() << "Path is empty, Abort! Path: " << absoluteStoragePath;
return false;
}
@ -254,13 +254,19 @@ bool ScreenPlayManager::removeAllWallpapers()
*/
bool ScreenPlayManager::removeAllWidgets()
{
if (m_screenPlayWallpapers.empty()) {
qWarning() << "Trying to remove all Widgets while m_screenPlayWallpapers is not empty. Count: " << m_screenPlayWallpapers.size();
if (m_screenPlayWidgets.empty()) {
qWarning() << "Trying to remove all Widgets while m_screenPlayWidgets is not empty. Count: " << m_screenPlayWidgets.size();
return false;
}
for (auto& client : m_screenPlayWallpapers) {
if (!removeWidget(client->appID())) {
QStringList appIDs;
// Do not remove items from the vector you iterate on.
for (auto& client : m_screenPlayWidgets) {
appIDs.append(client->appID());
}
for (const auto& appID : appIDs) {
if (!removeWidget(appID)) {
return false;
}
}
@ -348,10 +354,8 @@ ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID
*/
void ScreenPlayManager::newConnection()
{
qInfo() << "[1/3] SDKConnection incomming";
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 SDKConnection to the
@ -362,11 +366,6 @@ void ScreenPlayManager::newConnection()
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) {
@ -394,7 +393,10 @@ void ScreenPlayManager::newConnection()
}
}
qWarning() << "No matching connection found!";
qWarning() << "No matching connection found!"
<< "m_screenPlayWallpapers count: " << m_screenPlayWallpapers.size()
<< "m_screenPlayWidgets count: " << m_screenPlayWidgets.size()
<< "m_unconnectedClients count: " << m_unconnectedClients.size();
});
m_unconnectedClients.push_back(std::move(connection));
}
@ -444,10 +446,11 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
m_screenPlayWidgets.end(),
[this, appID](auto& widget) {
if (widget->appID() != appID) {
qInfo() << "No match " << widget->appID();
return false;
}
qInfo() << "Remove widget ";
qInfo() << "Remove widget " << appID;
decreaseActiveWidgetsCounter();
@ -455,12 +458,12 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
}));
if (activeWidgetsCounter() != m_screenPlayWidgets.length()) {
qWarning() << "activeWallpaperCounter value: " << activeWidgetsCounter()
<< "does not match m_screenPlayWallpapers length:" << m_screenPlayWidgets.length();
qWarning() << "activeWidgetsCounter value: " << activeWidgetsCounter()
<< "does not match m_screenPlayWidgets length:" << m_screenPlayWidgets.length();
return false;
}
return false;
return true;
}
/*!

View File

@ -47,28 +47,25 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
, m_volume { volume }
, m_playbackRate { playbackRate }
{
{
// If
QJsonObject projectSettingsListModelProperties;
if (type == InstalledType::InstalledType::VideoWallpaper) {
projectSettingsListModelProperties.insert("volume", m_volume);
projectSettingsListModelProperties.insert("playbackRate", m_playbackRate);
} else {
if (properties.isEmpty()) {
auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json");
if (!obj)
return;
QJsonObject projectSettingsListModelProperties;
if (type == InstalledType::InstalledType::VideoWallpaper) {
projectSettingsListModelProperties.insert("volume", m_volume);
projectSettingsListModelProperties.insert("playbackRate", m_playbackRate);
} else {
if (properties.isEmpty()) {
if (auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json")) {
if (obj->contains("properties"))
projectSettingsListModelProperties = obj->value("properties").toObject();
} else {
projectSettingsListModelProperties = properties;
}
} else {
projectSettingsListModelProperties = properties;
}
m_projectSettingsListModel.init(type, projectSettingsListModelProperties);
}
if (!projectSettingsListModelProperties.isEmpty())
m_projectSettingsListModel.init(type, projectSettingsListModelProperties);
QObject::connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &ScreenPlayWallpaper::processExit);
QObject::connect(&m_process, &QProcess::errorOccurred, this, &ScreenPlayWallpaper::processError);
@ -198,6 +195,7 @@ bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& v
void ScreenPlayWallpaper::setSDKConnection(std::unique_ptr<SDKConnection> connection)
{
m_connection = std::move(connection);
qInfo() << "[3/3] SDKConnection (Wallpaper) saved!";
QTimer::singleShot(1000, this, [this]() {
if (playbackRate() != 1.0) {

View File

@ -55,7 +55,6 @@ class ScreenPlayWallpaper : public QObject {
Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
Q_PROPERTY(float playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
Q_PROPERTY(bool isLooping READ isLooping WRITE setIsLooping NOTIFY isLoopingChanged)
Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged)
@ -99,25 +98,15 @@ public:
QJsonObject getActiveSettingsJson();
QVector<int> screenNumber() const { return m_screenNumber; }
QString previewImage() const { return m_previewImage; }
QString appID() const { return m_appID; }
InstalledType::InstalledType type() const { return m_type; }
QString file() const { return m_file; }
FillMode::FillMode fillMode() const { return m_fillMode; }
QString absolutePath() const { return m_absolutePath; }
float volume() const { return m_volume; }
bool isLooping() const { return m_isLooping; }
ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; }
float playbackRate() const { return m_playbackRate; }
signals:

View File

@ -29,25 +29,21 @@ ScreenPlayWidget::ScreenPlayWidget(
, m_type { type }
, m_absolutePath { absolutePath }
{
{
// If
QJsonObject projectSettingsListModelProperties;
if (properties.isEmpty()) {
auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json");
if (!obj)
return;
QJsonObject projectSettingsListModelProperties;
if (!obj->contains("properties"))
return;
projectSettingsListModelProperties = obj->value("properties").toObject();
} else {
projectSettingsListModelProperties = properties;
if (properties.isEmpty()) {
if (auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json")) {
if (obj->contains("properties"))
projectSettingsListModelProperties = obj->value("properties").toObject();
}
m_projectSettingsListModel.init(type, projectSettingsListModelProperties);
} else {
projectSettingsListModelProperties = properties;
}
if (!projectSettingsListModelProperties.isEmpty())
m_projectSettingsListModel.init(type, projectSettingsListModelProperties);
m_appArgumentsList = QStringList {
m_absolutePath,
QString { "appID=" + m_appID },
@ -60,19 +56,25 @@ ScreenPlayWidget::ScreenPlayWidget(
bool ScreenPlayWidget::start()
{
m_process.setArguments(m_appArgumentsList);
m_process.setProgram(m_globalVariables->widgetExecutablePath().path());
m_process.setProgram(m_globalVariables->widgetExecutablePath().toString());
QObject::connect(&m_process, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) {
qDebug() << "error: " << error;
});
const bool success = m_process.startDetached();
qInfo() << "Starting ScreenPlayWWidget detached: " << (success ? "success" : "failed!");
qInfo() << "Starting ScreenPlayWidget detached: " << (success ? "success" : "failed!");
if (!success) {
emit error(QString("Could not start Widget: " + m_process.errorString()));
}
return success;
}
ScreenPlayWidget::~ScreenPlayWidget()
{
qInfo() << "Remove widget " << m_appID;
m_connection->close();
}
/*!
\brief Connects to ScreenPlay. Start a alive ping check for every
GlobalVariables::contentPingAliveIntervalMS seconds.
@ -80,11 +82,13 @@ bool ScreenPlayWidget::start()
void ScreenPlayWidget::setSDKConnection(std::unique_ptr<SDKConnection> connection)
{
m_connection = std::move(connection);
qInfo() << "App widget connected!";
qInfo() << "[3/3] SDKConnected (Widged) saved!";
QObject::connect(m_connection.get(), &SDKConnection::requestDecreaseWidgetCount, this, [this]() { emit requestClose(appID()); });
QObject::connect(m_connection.get(), &SDKConnection::jsonMessageReceived, this, [this](const QJsonObject obj) {
if (obj.value("messageType") == "positionUpdate") {
setPosition({ obj.value("positionX").toInt(0), obj.value("positionY").toInt(0) });
emit requestSave();
return;
}
});

View File

@ -62,7 +62,8 @@ class ScreenPlayWidget : public QObject {
Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
public:
explicit ScreenPlayWidget(const QString& appID,
explicit ScreenPlayWidget(
const QString& appID,
const std::shared_ptr<GlobalVariables>& globalVariables,
const QPoint& position,
const QString& absolutePath,
@ -72,15 +73,13 @@ public:
bool start();
ScreenPlayWidget() { }
~ScreenPlayWidget();
QString previewImage() const { return m_previewImage; }
QPoint position() const { return m_position; }
QString absolutePath() const { return m_absolutePath; }
QString appID() const { return m_appID; }
InstalledType::InstalledType type() const { return m_type; }
void setSDKConnection(std::unique_ptr<SDKConnection> connection);
@ -90,6 +89,7 @@ public:
public slots:
QJsonObject getActiveSettingsJson();
void setPreviewImage(QString previewImage)
{
if (m_previewImage == previewImage)

View File

@ -16,7 +16,6 @@ namespace ScreenPlay {
ScreenPlay::SDKConnection::SDKConnection(QLocalSocket* socket, QObject* parent)
: QObject(parent)
{
m_socket = socket;
connect(m_socket, &QLocalSocket::readyRead, this, &SDKConnection::readyRead);
}
@ -60,7 +59,7 @@ void ScreenPlay::SDKConnection::readyRead()
qCritical() << "Wallpaper type not found. Expected: " << ScreenPlayUtil::getAvailableTypes() << " got: " << msg;
}
qInfo() << "New connection" << m_appID << msg;
qInfo() << "[2/3] SDKConnection parsed with type: " << m_type << " connected with AppID:" << m_appID;
emit appConnected(this);
@ -96,7 +95,7 @@ bool ScreenPlay::SDKConnection::sendMessage(const QByteArray& message)
/*!
\brief Closes the socket connection. Before it explicitly sends a quit command to make sure
the wallpaper closes (fast). This also requestDecreaseWidgetCount() because Widgets.
the wallpaper closes (fast).
*/
bool ScreenPlay::SDKConnection::close()
{
@ -122,10 +121,6 @@ bool ScreenPlay::SDKConnection::close()
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;
}
}

View File

@ -73,11 +73,8 @@ public:
explicit SDKConnection(QLocalSocket* socket, QObject* parent = nullptr);
QString appID() const { return m_appID; }
QLocalSocket* socket() const { return m_socket; }
QVector<int> monitor() const { return m_monitor; }
QString type() const { return m_type; }
signals:

View File

@ -145,4 +145,5 @@ private:
QString m_appID;
QTimer m_pingAliveTimer;
QTimer m_firstConnectionTimer;
};

View File

@ -40,21 +40,10 @@ void ScreenPlaySDK::start()
connect(&m_socket, &QLocalSocket::connected, this, &ScreenPlaySDK::connected);
connect(&m_socket, &QLocalSocket::disconnected, this, &ScreenPlaySDK::disconnected);
connect(&m_socket, &QLocalSocket::readyRead, this, &ScreenPlaySDK::readyRead);
connect(&m_socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), this, &ScreenPlaySDK::error);
connect(&m_firstConnectionTimer, &QTimer::timeout, this, &ScreenPlaySDK::disconnected);
// When we do not establish a connection in the first 5 seconds we abort.
m_firstConnectionTimer.start(5000);
m_socket.connectToServer();
// 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, [this]() {
if (m_socket.state() != QLocalSocket::ConnectedState) {
m_socket.disconnectFromServer();
emit sdkDisconnected();
}
QObject::connect(&m_pingAliveTimer, &QTimer::timeout, this, &ScreenPlaySDK::pingAlive);
m_pingAliveTimer.start(1000);
});
}
ScreenPlaySDK::~ScreenPlaySDK()
@ -71,9 +60,17 @@ void ScreenPlaySDK::sendMessage(const QJsonObject& obj)
void ScreenPlaySDK::connected()
{
m_firstConnectionTimer.stop();
QByteArray welcomeMessage = QString(m_appID + "," + m_type).toUtf8();
m_socket.write(welcomeMessage);
m_socket.waitForBytesWritten();
if (!m_socket.waitForBytesWritten()) {
disconnected();
return;
}
QObject::connect(&m_pingAliveTimer, &QTimer::timeout, this, &ScreenPlaySDK::pingAlive);
m_pingAliveTimer.start(1000);
setIsConnected(true);
emit sdkConnected();

View File

@ -17,6 +17,9 @@ RAM::RAM(QObject* parent)
m_updateTimer.start(m_tickRate);
}
/*!
* \brief RAM::update
*/
void RAM::update()
{
//Get values from system

View File

@ -32,8 +32,8 @@ int main(int argc, char* argv[])
// For testing purposes when starting the ScreenPlayWallpaper directly.
if (argumentList.length() == 1) {
#if defined(Q_OS_WIN)
// WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true);
WinWindow window1({ 0 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/_tmp_171806", "appID=test", "1", "fill", "videoWallpaper", true, true);
WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true);
//WinWindow window1({ 0 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/_tmp_171806", "appID=test", "1", "fill", "videoWallpaper", true, true);
#elif defined(Q_OS_LINUX)
LinuxWindow window({ 0 }, "test", "appid", "1", "fill", false);
#elif defined(Q_OS_OSX)

View File

@ -376,11 +376,11 @@ private:
int m_height { 0 };
QVector<int> m_activeScreensList;
QFileSystemWatcher m_fileSystemWatcher;
QTimer m_liveReloadLimiter;
QSysInfo m_sysinfo;
bool m_debugMode = false;
std::unique_ptr<ScreenPlaySDK> m_sdk;
QString m_contentBasePath;
QTimer m_liveReloadLimiter;
QString m_projectPath;
QString m_projectSourceFile;
QUrl m_projectSourceFileAbsolute;

View File

@ -510,6 +510,7 @@ int GetMonitorIndex(HMONITOR hMonitor)
return info.iIndex;
}
/*!
\brief This method is called via a fixed interval to detect if a window completely
covers a monitor. If then sets visualPaused for QML to pause the content.

View File

@ -37,13 +37,7 @@ WidgetWindow::WidgetWindow(
"InstalledType",
"Error: only enums");
m_sdk = std::make_unique<ScreenPlaySDK>(appID, type);
QObject::connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WidgetWindow::qmlExit);
QObject::connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &WidgetWindow::messageReceived);
Qt::WindowFlags flags = m_window.flags();
m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::BypassWindowManagerHint | Qt::SplashScreen);
m_window.setColor(Qt::transparent);
@ -81,9 +75,13 @@ WidgetWindow::WidgetWindow(
m_window.setPosition(m_position);
m_window.show();
// Do not trigger position changed save reuqest on startup
// Debug mode means we directly start the ScreenPlayWallpaper for easy debugging.
// This means we do not have a running ScreenPlay instance to connect to.
if (!m_debugMode) {
QObject::connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WidgetWindow::qmlExit);
QObject::connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &WidgetWindow::messageReceived);
sdk()->start();
// Do not trigger position changed save reuqest on startup
QTimer::singleShot(1000, this, [=, this]() {
// We limit ourself to only update the position every 500ms!
auto sendPositionUpdate = [this]() {