1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-25 04:02:50 +01:00

Merge commit 'db4a7c7391f0a8dc80a7c9b282b4a531efc6454c' into qt6-kde

This commit is contained in:
Elias Steurer 2021-11-14 19:14:43 +01:00
commit 20fa5de37d
50 changed files with 227 additions and 5744 deletions

View File

@ -9,7 +9,7 @@ function(qt_update_translations SOURCE_PATH TS_FILES)
foreach(_ts_file ${TS_FILES})
message(STATUS "Update Translation: ${_ts_file}")
execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET)
execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -locations none -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET)
execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file} OUTPUT_QUIET)
endforeach()

View File

@ -56,7 +56,7 @@ execute_process(
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
add_compile_definitions(COMPILE_INFO="${BUILD_DATE} + ${GIT_COMMIT_HASH}")
add_compile_definitions(COMPILE_INFO="Build Date: ${BUILD_DATE}. Git Hash: ${GIT_COMMIT_HASH}. ")
add_compile_definitions(SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_compile_definitions(SCREENPLAY_STEAM="${SCREENPLAY_STEAM}")
@ -76,6 +76,9 @@ add_subdirectory(CMake)
if(${SCREENPLAY_STEAM})
add_subdirectory(ScreenPlayWorkshop)
else()
# Only add target SteamSDKQtEnums
add_subdirectory(ScreenPlayWorkshop/SteamSDK)
endif()
if(WIN32)

View File

@ -5,7 +5,7 @@
``` bash
git clone --recursive https://gitlab.com/kelteseth/ScreenPlay.git ScreenPlay
```
4. Download the latest __Qt 5.15.x__ for you platform. Earlier versions are not supported!
4. Download the latest __Qt 6.2.x__ for you platform. Earlier versions are not supported!
1. [Install instructions Windows](#windows)
1. [Install instructions Linux](#linux)
1. [Install instructions MacOSX](#macosx)
@ -15,10 +15,9 @@ cd Tools
py setup.py
```
* This will install these dependencies via __vcpkg__
* openSSL 1.1.1d
* openSSL
* sentry-native
* doctest
* benchmark
* infoware
<div>
@ -26,7 +25,7 @@ py setup.py
</div>
5. Open __QtCreator__ and open the settings `Tools -> Options`
6. Clone an existing kit like `Qt 6.2.0 MSVC2019 64bit` and add `ScreenPlay` to the new kit name
6. Clone an existing kit like `Qt 6.2.1 MSVC2019 64bit` and add `ScreenPlay` to the new kit name
5. Edit CMake variables amd add CMAKE_TOOLCHAIN_FILE and VCPKG_TARGET_TRIPLET
* `Kits -> <Your_Kit> -> CMake Configuration`
@ -54,9 +53,9 @@ VCPKG_TARGET_TRIPLET:STRING=x64-osx
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool
- Select the following features to install:
- Qt 6.2.0
- Qt 6.2.1
- MSVC 2019 64-bit
- ALL Additional Libraries
- **ALL Additional Libraries**
- Qt Quick 3d
- Qt 5 Compatibility Module
- Qt Shader Tools
@ -80,9 +79,9 @@ sudo zypper install -t pattern devel_basis
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool
- Select the following features to install:
- Qt 6.2.0
- Qt 6.2.1
- GCC
- ALL Additional Libraries
- **ALL Additional Libraries**
- Qt Quick 3d
- Qt 5 Compatibility Module
- Qt Shader Tools
@ -95,9 +94,9 @@ sudo zypper install -t pattern devel_basis
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool
- Select the following features to install:
- Qt 6.2.0
- Qt 6.2.1
- Qt WebEngine
- ALL Additional Libraries
- **ALL Additional Libraries**
- Qt Quick 3d
- Qt 5 Compatibility Module
- Qt Shader Tools

View File

@ -1,15 +1,19 @@
# Overview
ScreenPlay consists of 5 projects:
1. **ScreenPlay**
* The main ScreenPlay App UI with Create, Installed, Community and Settings
2. **ScreenPlaySDK**
* A SDK used internally in the ScreenPlayWallpaper and ScreenPlayWidget to talk to the main ScreenPlay app via QLocalsockets (Windows Pipes and Unix sockets)
3. **ScreenPlaySysInfo**
* A qml plugin to read CPU, GPU, Network and all sort of statisitcs
4. **ScreenPlayWallpaper**
ScreenPlay consists of 7 projects:
1. **ScreenPlay executable**
* The main ScreenPlay App UI with Create, Installed, Community and Settings.
2. **ScreenPlayWallpaper executable**
* The Wallpaper executable that is used for displaying a single wallpaper. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp.
5. **ScreenPlayWidget**
* The Widget executable that is used for displaying a single widget. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp .
3. **ScreenPlayWidget executable**
* The Widget executable that is used for displaying a single widget. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp.
4. **ScreenPlayUtil lib**
* Util function, like project.json loading, that are needed in ScreenPlay and Workshop plugin.
5. **ScreenPlaySDK lLib**
* A SDK used internally in the ScreenPlayWallpaper and ScreenPlayWidget to talk to the main ScreenPlay app via QLocalsockets (Windows Pipes and Unix sockets).
6. **ScreenPlaySysInfo lib**
* A qml plugin to read CPU, GPU, Network and all sort of statisitcs.
7. **ScreenPlayWorkshop plugin**
* The Steam workshop plugin that is loaded at runtime.
![ProjectOverview.png](ProjectOverview.png)

View File

@ -206,7 +206,8 @@ target_link_libraries(
Qt6::Svg
Qt6::WebEngineQuick
Qt6::WebEngineCore
${LibArchive_LIBRARIES})
${LibArchive_LIBRARIES}
SteamSDKQtEnums)
if(${TESTS_ENABLED})
add_executable(tst_ScreenPlay tests/tst_main.cpp)

View File

@ -1,5 +1,7 @@
#include "app.h"
#include "steam/steam_qt_enums_generated.h"
namespace ScreenPlay {
/*!
\module ScreenPlay
@ -96,6 +98,16 @@ App::App()
qRegisterMetaType<MonitorListModel*>();
qRegisterMetaType<ProfileListModel*>();
// TODO: This is a workaround because I don't know how to
// init this in the ScreenPlayWorkshop plugin.
// Move to workshop plugin.
qmlRegisterUncreatableMetaObject(ScreenPlayWorkshopSteamEnums::staticMetaObject,
"WorkshopEnums",
1, 0,
"SteamEnums",
"Error: only enums");
// Registers the enums from globalvariables.
// Apparently this is the only way for qml to work
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/

View File

@ -478,7 +478,7 @@ Item {
SettingsButton {
icon.source: "qrc:/assets/icons/icon_launch.svg"
headline: qsTr("Version")
description: qsTr("ScreenPlay Build Version ") + ScreenPlay.settings.gitBuildHash
description: qsTr("ScreenPlay Build Version \n") + ScreenPlay.settings.gitBuildHash
buttonText: qsTr("Open Changelog")
onButtonPressed: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay/-/releases")
}

View File

@ -1,6 +1,5 @@
import QtQuick
import Qt5Compat.GraphicalEffects
import Workshop 1.0
Rectangle {
id: root

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import Workshop 1.0
import WorkshopEnums 1.0
import ScreenPlay 1.0
import "upload/"

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import Workshop 1.0
import WorkshopEnums 1.0
import ScreenPlay 1.0
import "upload/"
import "../Common" as Common

View File

@ -4,7 +4,8 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Controls.Material.impl
import Workshop
import Workshop 1.0
import WorkshopEnums 1.0
Page {

View File

@ -175,6 +175,11 @@ void ScreenPlayWallpaper::processError(QProcess::ProcessError error)
*/
bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save)
{
if (!m_connection) {
qWarning() << "Cannot set value for unconnected wallpaper!";
return false;
}
QJsonObject obj;
obj.insert(key, value);

View File

@ -101,7 +101,8 @@ Settings::Settings(const std::shared_ptr<GlobalVariables>& globalVariables,
initInstalledPath();
setupWidgetAndWindowPaths();
setGitBuildHash(COMPILE_INFO);
const QString qtVersion = QString("Qt Version: %1.%2.%3").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH);
setGitBuildHash(COMPILE_INFO + qtVersion);
setSteamVersion(!(QString(SCREENPLAY_STEAM).compare("OFF", Qt::CaseInsensitive) ? false : true));
}
@ -194,7 +195,7 @@ void Settings::restoreDefault(const QString& appConfigLocation, const QString& s
void Settings::initInstalledPath()
{
//If empty use steam workshop location
// If empty use steam workshop location
if (QString(m_qSettings.value("ScreenPlayContentPath").toString()).isEmpty()) {
/*
@ -267,8 +268,12 @@ bool Settings::retranslateUI()
QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString());
QFile tsFile;
if (tsFile.exists(":/translations/ScreenPlay_" + langCode + ".qm")) {
m_translator.load(":/translations/ScreenPlay_" + langCode + ".qm");
const QString qmPath = ":/translations/ScreenPlay_" + langCode + ".qm";
if (tsFile.exists(qmPath)) {
if (!m_translator.load(qmPath)) {
qWarning() << "Unable to load translation file: " << qmPath;
return false;
}
auto* app = static_cast<QApplication*>(QApplication::instance());
app->installTranslator(&m_translator);
emit requestRetranslation();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,3 +26,8 @@ target_include_directories(
PRIVATE src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core)
if(WIN32)
# Used for query windows monitor data
target_link_libraries(${PROJECT_NAME} PUBLIC shcore.lib)
endif()

View File

@ -33,6 +33,17 @@
****************************************************************************/
#pragma once
#include <QtGlobal>
#if defined(Q_OS_WIN)
// Must be first!
#include <qt_windows.h>
#include "WinUser.h"
#include <ShellScalingApi.h>
#endif
#include "ScreenPlayUtil/contenttypes.h"
#include <QJsonArray>
#include <QJsonObject>
@ -41,6 +52,37 @@
#include <optional>
namespace ScreenPlayUtil {
#if defined(Q_OS_WIN)
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(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); }
};
#endif
QJsonArray fillArray(const QVector<QString>& items);
ScreenPlay::SearchType::SearchType getSearchTypeFromInstalledType(const ScreenPlay::InstalledType::InstalledType type);
std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromString(const QString& type);

View File

@ -233,7 +233,7 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
{
using ScreenPlay::InstalledType::InstalledType;
if (type.endsWith("Wallpaper")) {
if (type.endsWith("Wallpaper", Qt::CaseInsensitive)) {
if (type.startsWith("video", Qt::CaseInsensitive)) {
return InstalledType::VideoWallpaper;
}
@ -254,7 +254,7 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
}
}
if (type.endsWith("Widget")) {
if (type.endsWith("Widget", Qt::CaseInsensitive)) {
if (type.startsWith("qml", Qt::CaseInsensitive)) {
return InstalledType::QMLWidget;
}
@ -266,28 +266,27 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
return std::nullopt;
}
/*!
\brief Maps the video codec type from a QString to an enum. Used for parsing the project.json.
*/
std::optional<ScreenPlay::VideoCodec::VideoCodec> getVideoCodecFromString(const QString &type)
std::optional<ScreenPlay::VideoCodec::VideoCodec> getVideoCodecFromString(const QString& type)
{
if(type.isEmpty())
if (type.isEmpty())
return std::nullopt;
if(type.contains("vp8",Qt::CaseInsensitive))
if (type.contains("vp8", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::VP8;
if(type.contains("vp9",Qt::CaseInsensitive))
if (type.contains("vp9", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::VP9;
if(type.contains("av1",Qt::CaseInsensitive))
if (type.contains("av1", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::AV1;
if(type.contains("h264",Qt::CaseInsensitive))
if (type.contains("h264", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::H264;
if(type.contains("h265",Qt::CaseInsensitive))
if (type.contains("h265", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::H264;
return std::nullopt;
@ -395,5 +394,4 @@ std::optional<QVector<int>> parseStringToIntegerList(const QString string)
return list;
}
}

View File

@ -39,7 +39,7 @@ set(SOURCES ${SOURCES} main.cpp src/basewindow.cpp)
set(HEADER ${HEADER} src/basewindow.h)
set(QML # cmake-format: sortable
qml/GifWallpaper.qml qml/Test.qml qml/Wallpaper.qml qml/WebsiteWallpaper.qml qml/WebView.qml qml/MultimediaView.qml qml/MultimediaWebView.qml)
qml/GifWallpaper.qml qml/Test.qml qml/Wallpaper.qml qml/WebsiteWallpaper.qml qml/MultimediaView.qml qml/MultimediaWebView.qml)
qt_add_resources(RESOURCES Resources.qrc)
@ -83,6 +83,5 @@ 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)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/index.html ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/index.html COPYONLY)
endif()

View File

@ -6,7 +6,7 @@ Item {
id: root
anchors.fill: parent
property bool loops: Wallpaper.loops
property bool isWindows: Qt.platform === "windows"
property bool isWindows: Qt.platform.os === "windows"
signal requestFadeIn
MediaPlayer {

View File

@ -17,17 +17,24 @@ Rectangle {
if (Wallpaper.videoCodec === VideoCodec.Unknown) {
Wallpaper.terminate()
}
// macOS only supports h264 via the native Qt MM
if (Qt.platform === "osx" && (Wallpaper.videoCodec === VideoCodec.VP8
if (Qt.platform.os === "osx") {
if ((Wallpaper.videoCodec === VideoCodec.VP8
|| Wallpaper.videoCodec === VideoCodec.VP9)) {
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaWebView.qml"
} else {
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaView.qml"
}
}
if (Qt.platform.os === "windows") {
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaView.qml"
}
fadeIn()
break
case InstalledType.HTMLWallpaper:
loader.setSource("qrc:/ScreenPlayWallpaper/qml/WebView.qml", {
loader.setSource("qrc:/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", {
"url": Qt.resolvedUrl(
Wallpaper.projectSourceFileAbsolute)
})
@ -100,7 +107,7 @@ Rectangle {
}
// This function only gets called here (the same function
// is inside the WebView.qml) when the previous Wallpaper type
// is inside the MultimediaWebView.qml) when the previous Wallpaper type
// was not a video
function onReloadVideo(oldType) {
// We need to check if the old type

View File

@ -1,154 +0,0 @@
import QtQuick
import QtWebEngine
import ScreenPlay.Enums.InstalledType 1.0
import ScreenPlayWallpaper 1.0
Item {
id: root
property alias url: webView.url
signal requestFadeIn
function getSetVideoCommand() {
// TODO 30:
// Currently wont work. Commit anyways til QtCreator and Qt work with js template literals
var src = ""
src += "var videoPlayer = document.getElementById('videoPlayer');"
src += "var videoSource = document.getElementById('videoSource');"
src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';"
src += "videoPlayer.load();"
src += "videoPlayer.volume = " + Wallpaper.volume + ";"
src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');"
src += "videoPlayer.play();"
return src
}
Component.onCompleted: {
WebEngine.settings.localContentCanAccessFileUrls = true
WebEngine.settings.localContentCanAccessRemoteUrls = true
WebEngine.settings.allowRunningInsecureContent = true
WebEngine.settings.accelerated2dCanvasEnabled = true
WebEngine.settings.javascriptCanOpenWindows = false
WebEngine.settings.showScrollBars = false
WebEngine.settings.playbackRequiresUserGesture = false
WebEngine.settings.focusOnNavigationEnabled = true
}
WebEngineView {
id: webView
anchors.fill: parent
url: "qrc:/ScreenPlayWallpaper/index.html"
backgroundColor: "transparent"
onJavaScriptConsoleMessage:(lineNumber, message)=> print(lineNumber, message)
onLoadProgressChanged: {
if ((loadProgress === 100)) {
if (Wallpaper.type === InstalledType.VideoWallpaper)
webView.runJavaScript(root.getSetVideoCommand(),
function (result) {
requestFadeIn()
})
else
requestFadeIn()
}
}
}
Text {
id: txtVisualsPaused
text: qsTr("If you can read this, then the VisualsPaused optimization does not work on your system. You can fix this by disable this in: \n Settings -> Perfromance -> Pause wallpaper video rendering while another app is in the foreground ")
font.pointSize: 32
visible: false
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors.centerIn: parent
width: parent.width * 0.8
color: "white"
}
Timer {
id: timerCover
interval: 300
onTriggered: {
webView.visible = !Wallpaper.visualsPaused
txtVisualsPaused.visible = Wallpaper.visualsPaused
}
}
Connections {
function onReloadVideo(oldType) {
webView.runJavaScript(root.getSetVideoCommand())
}
function onQmlExit() {
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
}
function onMutedChanged(muted) {
if (muted)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
else
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";")
}
function onFillModeChanged(fillMode) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');")
}
function onLoopsChanged(loops) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";")
}
function onVolumeChanged(volume) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";")
}
function onCurrentTimeChanged(currentTime) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = "
+ currentTime + " * videoPlayer.duration;")
}
function onPlaybackRateChanged(playbackRate) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";")
}
function onVisualsPausedChanged(visualsPaused) {
if (visualsPaused) {
// Wait until Wallpaper animation is finsihed
timerCover.restart()
} else {
webView.visible = true
txtVisualsPaused.visible = false
}
}
function onIsPlayingChanged(isPlaying) {
if (webView.loadProgress === 100) {
if (isPlaying)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();")
else
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();")
}
}
target: Wallpaper
}
}

View File

@ -24,7 +24,7 @@ Item {
id: webView
anchors.fill: parent
url: root.url
url: Qt.resolvedUrl(root.url)
onJavaScriptConsoleMessage: print(lineNumber, message)
onLoadProgressChanged: {
if ((loadProgress === 100))

View File

@ -1,41 +1,8 @@
#include "winwindow.h"
#include "WinUser.h"
#include "qqml.h"
#include <ShellScalingApi.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <windows.h>
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(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); }
};
/*!
\brief Searches for the worker window for our window to parent to.
@ -107,8 +74,8 @@ LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
if (type == QMouseEvent::Type::MouseButtonPress) {
}
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 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);
});
@ -224,17 +191,6 @@ WinWindow::WinWindow(
qmlRegisterSingletonInstance<WinWindow>("ScreenPlayWallpaper", 1, 0, "Wallpaper", this);
configureWindowGeometry();
bool hasWindowScaling = false;
for (int i = 0; i < screens.count(); i++) {
if (getScaling(i) != 1) {
hasWindowScaling = true;
break;
}
}
if (hasWindowScaling) {
qInfo() << "Monitor with scaling detected!";
configureWindowGeometry();
}
// We do not support autopause for multi monitor wallpaper
if (this->activeScreensList().length() == 1) {
@ -296,46 +252,28 @@ BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMo
*/
void WinWindow::setupWallpaperForOneScreen(int activeScreen)
{
const QRect screenRect = QApplication::screens().at(activeScreen)->geometry();
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 float scaling = getScaling(activeScreen);
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)) {
ScreenPlayUtil::WinMonitorStats Monitors;
const int width = std::abs(Monitors.rcMonitors[activeScreen].right - Monitors.rcMonitors[activeScreen].left);
const int height = std::abs(Monitors.rcMonitors[activeScreen].top - Monitors.rcMonitors[activeScreen].bottom);
const int x = Monitors.rcMonitors[activeScreen].left + m_zeroPoint.x() + borderOffset;
const int y = Monitors.rcMonitors[activeScreen].top + m_zeroPoint.y() + borderOffset;
qInfo() << QString("Setup window activeScreen: %1 scaling: %2 x: %3 y: %4 width: %5 height: %6").arg(activeScreen).arg(scaling).arg(x).arg(y).arg(width).arg(height);
{
// Must be called twice for some reason when window has scaling...
if (!SetWindowPos(m_windowHandle, nullptr, x, y, width, height, 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)) {
if (!SetWindowPos(m_windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
qFatal("Could not set window pos");
}
}
if (SetParent(m_windowHandle, m_windowHandleWorker) == nullptr) {
qFatal("Could not attach to parent window");
@ -407,44 +345,48 @@ bool WinWindow::searchWorkerWindowToParentTo()
}
/*!
\brief Reads the logicalDotsPerInch and mapps them to scaling factors.
\brief Reads the physicalDotsPerInch and mapps them to scaling factors.
This is needed to detect if the user has different monitors with
different scaling factors.
screen->logicalDotsPerInch()
100% -> 96 -> 1
screen->physicalDotsPerInch()
100% -> 109 -> 1
125% -> 120 -> 1.25
150% -> 144 -> 1.5
150% -> 161 -> 1.5
...
*/
float WinWindow::getScaling(const int monitorIndex)
{
QScreen* screen = QApplication::screens().at(monitorIndex);
const int factor = screen->logicalDotsPerInch();
const int factor = screen->physicalDotsPerInch();
switch (factor) {
case 96:
case 72:
return 1;
case 120:
return 1.25;
case 144:
case 107:
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;
case 109:
return 1;
case 161:
return 1;
default:
qWarning() << "Monitor with factor: " << factor << " detected! This is not supported!";
return 1;
}
}
/*!
\brief Returns true of at least one monitor has active scaling enabled.
*/
bool WinWindow::hasWindowScaling()
{
const auto screens = QApplication::screens();
for (int i = 0; i < screens.count(); i++) {
if (getScaling(i) != 1) {
return true;
}
}
return false;
}
/*!
\brief Sets the size and the parent to the worker handle to be displayed behind the
@ -452,7 +394,7 @@ float WinWindow::getScaling(const int monitorIndex)
*/
void WinWindow::configureWindowGeometry()
{
ShowWindow(m_windowHandle, SW_HIDE);
setVisible(false);
if (!searchWorkerWindowToParentTo()) {
qFatal("No worker window found");

View File

@ -96,6 +96,7 @@ private:
bool searchWorkerWindowToParentTo();
void configureWindowGeometry();
float getScaling(const int monitorIndex);
bool hasWindowScaling();
private slots:
void checkForFullScreenWindow();

View File

@ -1,4 +1,4 @@
project(workshopplugin LANGUAGES CXX)
project(ScreenPlayWorkshop LANGUAGES CXX)
add_subdirectory(SteamSDK)
@ -16,7 +16,6 @@ set(SOURCES
src/steamworkshopitem.cpp
src/workshop.cpp
src/installedlistmodel.cpp
src/screenplayworkshop_plugin.cpp
src/steamworkshop.cpp
src/steamworkshoplistmodel.cpp
src/steamaccount.cpp
@ -31,55 +30,35 @@ set(HEADER
src/workshop.h
src/workshopitem.h
src/installedlistmodel.h
src/screenplayworkshop_plugin.h
src/steamworkshop.h
src/steamaccount.h
src/steamqmlimageprovider.h)
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER})
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/workshop)
file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set(STEAM_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/SteamSDK/redistributable_bin/")
if(WIN32)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/win64/steam_api64.lib")
set(STEAM_BIN "${STEAM_LIB_PATH}/win64/steam_api64.dll")
elseif(APPLE)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/osx/libsteam_api.dylib")
set(STEAM_BIN ${STEAM_LIB})
elseif(UNIX)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/linux64/libsteam_api.so")
set(STEAM_BIN ${STEAM_LIB})
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick ${STEAM_LIB} ScreenPlayUtil SteamSDK)
qt_add_qml_module(
${PROJECT_NAME}
OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR}
URI "Workshop"
SOURCES ${SOURCES} ${HEADER}
VERSION
1.0)
if(APPLE)
set(workshop_install_dir ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop)
add_custom_target(
build-time-make-directory
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${workshop_install_dir})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying workshop plugin into ScreenPlay.app bundle"
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/Workshop/libworkshopplugin.dylib ${workshop_install_dir})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying steam library into ScreenPlay.app bundle"
COMMAND ${CMAKE_COMMAND} -E copy ${STEAM_BIN} ${workshop_install_dir})
if(${SCREENPLAY_STEAM})
add_custom_command(
TARGET ${PROJECT_NAME}
@ -87,11 +66,24 @@ if(APPLE)
COMMENT "Copying steam_appid.txt into ScreenPlay.app bundle. This is for development only!"
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/)
endif()
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying libsteam_api.dylib into ScreenPlay.app bundle."
COMMAND ${CMAKE_COMMAND} -E copy ${STEAM_LIB}
${WORKSHOP_PLUGIN_DIR})
endif()
else()
if(${SCREENPLAY_STEAM})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt COPYONLY)
configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY)
endif()
endif()
# Needed by the automatic generated target missing includes
# https://github.com/qt/qtdeclarative/blob/7a7064e14f094e843e1ee832cc927e86f887621a/src/qml/Qt6QmlMacros.cmake#L2042
target_include_directories(${PROJECT_NAME} PUBLIC src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick ${STEAM_LIB} ScreenPlayUtil SteamSDK SteamSDKQtEnums)

View File

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

View File

@ -19,6 +19,7 @@
#include <QVariantList>
#include <QVector>
#include <QtConcurrent/QtConcurrent>
#include <QtQml>
#include "ScreenPlayUtil/projectfile.h"
#include "ScreenPlayUtil/util.h"
@ -33,6 +34,7 @@ namespace ScreenPlayWorkshop {
class InstalledListModel : public QAbstractListModel {
Q_OBJECT
QML_NAMED_ELEMENT(InstalledListModel)
Q_PROPERTY(QUrl absoluteStoragePath READ absoluteStoragePath WRITE setabsoluteStoragePath NOTIFY absoluteStoragePathChanged)
public:

View File

@ -1,19 +0,0 @@
#include "screenplayworkshop_plugin.h"
void ScreenPlayWorkshopPlugin::registerTypes(const char* uri)
{
qRegisterMetaType<ScreenPlayWorkshop::SteamQMLImageProvider*>("SteamQMLImageProvider*");
qmlRegisterType<ScreenPlayWorkshop::SteamQMLImageProvider>("Workshop", 1, 0, "SteamImage");
qmlRegisterUncreatableMetaObject(ScreenPlayWorkshopSteamEnums::staticMetaObject,
"Workshop",
1, 0,
"SteamEnums",
"Error: only enums");
qRegisterMetaType<ScreenPlayWorkshop::SteamAccount*>("SteamAccount*");
qRegisterMetaType<ScreenPlayWorkshop::InstalledListModel*>("InstalledListModel*");
qmlRegisterType<ScreenPlayWorkshop::SteamWorkshop>("Workshop", 1, 0, "SteamWorkshop");
qmlRegisterType<ScreenPlayWorkshop::Workshop>("Workshop", 1, 0, "ScreenPlayWorkshop");
}

View File

@ -1,21 +0,0 @@
#pragma once
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
#include <QSettings>
#include <QtQml>
#include "steam/steam_qt_enums_generated.h"
#include "workshop.h"
#include "steamqmlimageprovider.h"
class ScreenPlayWorkshopPlugin : public QQmlExtensionPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
void registerTypes(const char* uri) override;
};

View File

@ -7,6 +7,7 @@
#include <QString>
#include <QTimer>
#include <QtGlobal>
#include <QtQml>
#include <memory>
#include <steam/steam_api.h>
@ -15,7 +16,7 @@ namespace ScreenPlayWorkshop {
class SteamAccount : public QObject {
Q_OBJECT
QML_NAMED_ELEMENT(SteamAccount)
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
Q_PROPERTY(quint32 accountID READ accountID WRITE setAccountID NOTIFY accountIDChanged)
Q_PROPERTY(QImage avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)

View File

@ -5,10 +5,12 @@
#include <QSGNode>
#include <QSGSimpleTextureNode>
#include <QSGTexture>
#include <QtQml>
namespace ScreenPlayWorkshop {
class SteamQMLImageProvider : public QQuickItem {
Q_OBJECT
QML_NAMED_ELEMENT(SteamImage)
public:
SteamQMLImageProvider(QQuickItem* parent);
@ -28,7 +30,6 @@ public:
node->setRect(boundingRect());
return node;
}
public slots:
void setImage(QImage image)
{

View File

@ -13,6 +13,7 @@
#include <QTimer>
#include <QUrl>
#include <QtConcurrent/QtConcurrent>
#include <QtQml>
// Steam
#include "cstring"
@ -40,6 +41,7 @@ struct SteamItemUpdate {
class SteamWorkshop : public QObject {
Q_OBJECT
QML_NAMED_ELEMENT(SteamWorkshop)
Q_PROPERTY(bool online READ online WRITE setOnline NOTIFY onlineChanged)
Q_PROPERTY(unsigned long long itemProcessed READ itemProcessed WRITE setItemProcessed NOTIFY itemProcessedChanged)
Q_PROPERTY(unsigned long long bytesTotal READ bytesTotal WRITE setBytesTotal NOTIFY bytesTotalChanged)

View File

@ -14,7 +14,7 @@ namespace ScreenPlayWorkshop {
class Workshop : public QQuickItem {
Q_OBJECT
QML_NAMED_ELEMENT(ScreenPlayWorkshop)
Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel NOTIFY installedListModelChanged)
Q_PROPERTY(SteamWorkshop* steamWorkshop READ steamWorkshop NOTIFY steamWorkshopChanged)

View File

@ -45,7 +45,7 @@ if not args.build_type:
print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True")
sys.exit(1)
qt_version = "6.2.0"
qt_version = "6.2.1"
steam_build = "OFF"
if args.steam_build:
if args.steam_build: