From c5fc23d6bed86dd91c53cc4d923bacba87fbea47 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 9 Sep 2022 21:07:04 +0200 Subject: [PATCH 01/35] GlosSITarget: Log full target.json --- GlosSITarget/Settings.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index 6b80fd0..23e71b8 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -146,7 +146,8 @@ inline void Parse(std::wstring arg1) json_file.close(); - spdlog::debug(L"Read config file \"{}\"", path.wstring()); + // c++ is stupid... + spdlog::debug(L"Read config file \"{}\"; config: {}", path.wstring(), std::filesystem::path(json.dump()).wstring()); if (launch.launch) { launch.isUWP = checkIsUwp(launch.launchPath); From 431053e735981b2a539b333c7f3bf13ef399690c Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Sun, 11 Sep 2022 23:37:40 +0200 Subject: [PATCH 02/35] Update Clang-format files --- GlosSIConfig/.clang-format | 1 + GlosSITarget/.clang-format | 1 + GlosSITarget/TargetWindow.cpp | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/GlosSIConfig/.clang-format b/GlosSIConfig/.clang-format index dc813fd..7cc5c0d 100644 --- a/GlosSIConfig/.clang-format +++ b/GlosSIConfig/.clang-format @@ -1,4 +1,5 @@ UseTab: false +BasedOnStyle: LLVM IndentWidth: 4 BreakBeforeBraces: "Stroustrup" AllowShortIfStatementsOnASingleLine: false diff --git a/GlosSITarget/.clang-format b/GlosSITarget/.clang-format index b5e5b98..1c78926 100644 --- a/GlosSITarget/.clang-format +++ b/GlosSITarget/.clang-format @@ -1,3 +1,4 @@ +BasedOnStyle: LLVM UseTab: false IndentWidth: 4 BreakBeforeBraces: "Stroustrup" diff --git a/GlosSITarget/TargetWindow.cpp b/GlosSITarget/TargetWindow.cpp index f2eb178..119c5fd 100644 --- a/GlosSITarget/TargetWindow.cpp +++ b/GlosSITarget/TargetWindow.cpp @@ -254,8 +254,11 @@ void TargetWindow::createWindow(bool window_mode) #ifdef _WIN32 // For some completely odd reason, the Background becomes black when enabled dpi-awareness and making the window desktop-size. // Scaling down by 1px each direction is barely noticeable and works. + + // Due to some other issue, the (Steam) overlay might get blurred when doing this + // as a workaround, start in full size, and scale down later... spdlog::info("Creating Overlay window (Borderless Fullscreen)..."); - window_.create(sf::VideoMode(desktop_mode.width - 1, desktop_mode.height - 1, 32), "GlosSITarget", sf::Style::None); + window_.create(sf::VideoMode(desktop_mode.width -1, desktop_mode.height -1, 32), "GlosSITarget", sf::Style::None); #else window_.create(desktop_mode, "GlosSITarget", sf::Style::None); #endif @@ -320,6 +323,9 @@ void TargetWindow::createWindow(bool window_mode) else { spdlog::warn("Not applying too low screen scale setting"); } + + // window_.setSize({desktop_mode.width - 1, desktop_mode.height - 1 }); + on_window_changed_(); #ifdef _WIN32 From 14e4662df72f6d4756dc1a8142fea3fb07687f3d Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Sun, 11 Sep 2022 23:38:01 +0200 Subject: [PATCH 03/35] Add "couldn't detect Steam"-dialog --- GlosSIConfig/GlosSIConfig.vcxproj | 1 + GlosSIConfig/GlosSIConfig.vcxproj.filters | 3 + GlosSIConfig/Resource.rc | 52 ++++++++++++- GlosSIConfig/UIModel.cpp | 51 ++++++++++--- GlosSIConfig/UIModel.h | 2 + GlosSIConfig/qml.qrc | 1 + GlosSIConfig/qml/SteamNotFoundDialog.qml | 92 +++++++++++++++++++++++ GlosSIConfig/qml/main.qml | 10 +++ 8 files changed, 196 insertions(+), 16 deletions(-) create mode 100644 GlosSIConfig/qml/SteamNotFoundDialog.qml diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj index 2033835..c573119 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj +++ b/GlosSIConfig/GlosSIConfig.vcxproj @@ -144,6 +144,7 @@ + diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters index e1d59d1..b9af58c 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj.filters +++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters @@ -65,6 +65,9 @@ + + qml + diff --git a/GlosSIConfig/Resource.rc b/GlosSIConfig/Resource.rc index ee15a05..9b95676 100644 --- a/GlosSIConfig/Resource.rc +++ b/GlosSIConfig/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,8,003002880001 - PRODUCTVERSION 0,0,8,003002880001 + FILEVERSION 0,0,8,102000500230 + PRODUCTVERSION 0,0,8,102000500230 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - Config" - VALUE "FileVersion", "0.0.8.0-3-g288bba1" + VALUE "FileVersion", "0.0.8.1-2-gc5fc23d" VALUE "InternalName", "GlosSIConfig" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.8.0-3-g288bba1" + VALUE "ProductVersion", "0.0.8.1-2-gc5fc23d" END END BLOCK "VarFileInfo" @@ -756,6 +756,50 @@ IDI_ICON1 ICON "..\GloSC_Icon.ico" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index a1c2451..212bb4c 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -367,12 +367,20 @@ void UIModel::writeTarget(const QJsonObject& json, const QString& name) std::filesystem::path UIModel::getSteamPath() const { + try { #ifdef _WIN32 - // TODO: check if keys/value exist - // steam should always be open and have written reg values... - winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"}; - const auto res = key.GetStringValue(L"SteamPath"); - return res; + // TODO: check if keys/value exist + // steam should always be open and have written reg values... + winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"}; + if (!key.IsValid()) { + return ""; + } + const auto res = key.GetStringValue(L"SteamPath"); + return res; + } + catch (...) { + return ""; + } #else return L""; // TODO LINUX #endif @@ -381,19 +389,38 @@ std::filesystem::path UIModel::getSteamPath() const std::wstring UIModel::getSteamUserId() const { #ifdef _WIN32 - // TODO: check if keys/value exist - // steam should always be open and have written reg values... - winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"}; - const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser")); - if (res == L"0") { - qDebug() << "Steam not open?"; + try { + // TODO: check if keys/value exist + // steam should always be open and have written reg values... + winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"}; + if (!key.IsValid()) { + return L"0"; + } + const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser")); + if (res == L"0") { + qDebug() << "Steam not open?"; + } + return res; + } catch(...) { + return L"0"; } - return res; #else return L""; // TODO LINUX #endif } +bool UIModel::foundSteam() const +{ + if (getSteamPath() == "" || getSteamUserId() == L"0") { + return false; + } + const std::filesystem::path user_config_dir = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId(); + if (!std::filesystem::exists(user_config_dir)) { + return false; + } + return true; +} + void UIModel::parseShortcutVDF() { const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + shortcutsfile_.toStdWString(); diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h index d9c1595..d17e231 100644 --- a/GlosSIConfig/UIModel.h +++ b/GlosSIConfig/UIModel.h @@ -27,6 +27,7 @@ class UIModel : public QObject { Q_PROPERTY(bool hasAcrlyicEffect READ hasAcrylicEffect NOTIFY acrylicChanged) Q_PROPERTY(QVariantList targetList READ getTargetList NOTIFY targetListChanged) Q_PROPERTY(QVariantList uwpList READ uwpApps CONSTANT) + Q_PROPERTY(bool foundSteam READ foundSteam CONSTANT) public: UIModel(); @@ -68,6 +69,7 @@ class UIModel : public QObject { std::filesystem::path getSteamPath() const; std::wstring getSteamUserId() const; + bool foundSteam() const; void parseShortcutVDF(); QString shortcutsfile_ = "/config/shortcuts.vdf"; QString user_data_path_ = "/userdata/"; diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc index 80ff2b9..28a36de 100644 --- a/GlosSIConfig/qml.qrc +++ b/GlosSIConfig/qml.qrc @@ -15,5 +15,6 @@ noise.png GloSC_Icon_small.png svg/help_outline_white_24dp.svg + qml/SteamNotFoundDialog.qml diff --git a/GlosSIConfig/qml/SteamNotFoundDialog.qml b/GlosSIConfig/qml/SteamNotFoundDialog.qml new file mode 100644 index 0000000..3b254e6 --- /dev/null +++ b/GlosSIConfig/qml/SteamNotFoundDialog.qml @@ -0,0 +1,92 @@ +/* +Copyright 2021-2022 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import QtQuick 6.2 +import QtQuick.Controls 6.2 +import QtQuick.Layouts 6.2 +import QtQuick.Controls.Material 6.2 + +Dialog { + id: dlg + anchors.centerIn: parent + + signal confirmed(var param) + + visible: false + modal: true + dim: true + parent: Overlay.overlay + Overlay.modal: Rectangle { + color: Qt.rgba(0,0,0,0.4) + opacity: backdropOpacity + Behavior on opacity { + NumberAnimation { + duration: 300 + } + } + } + property real backdropOpacity: 1.0 + + enter: Transition { + NumberAnimation{target: content; property: "y"; from: parent.height; to: 16; duration: 300; easing.type: Easing.OutQuad } + NumberAnimation{target: background; property: "y"; from: parent.height; to: 0; duration: 300; easing.type: Easing.OutQuad } + NumberAnimation{target: dlg; property: "backdropOpacity"; from: 0; to: 1; duration: 300; easing.type: Easing.OutQuad } + } + + exit: Transition { + NumberAnimation{target: content; property: "y"; from: 16; to: parent.height; duration: 300; easing.type: Easing.InQuad } + NumberAnimation{target: background; property: "y"; from: 0; to: parent.height; duration: 300; easing.type: Easing.InQuad } + NumberAnimation{target: dlg; property: "backdropOpacity"; from: 1; to: 0; duration: 300; easing.type: Easing.InQuad } + } + + background: RPane { + id: background + radius: 4 + Material.elevation: 64 + bgOpacity: 0.97 + } + + contentItem: Item { + id: content + clip: true + Column { + spacing: 4 + bottomPadding: 24 + Label { + id: titlelabel + text: qsTr("Could not detect Steam") + font.pixelSize: 24 + font.bold: true + } + Item { + height: 24 + } + Label { + text: qsTr("Please make sure that Steam is running and you are logged in.") + wrapMode: Text.WordWrap + width: parent.width + } + + Button { + anchors.right: parent.right + anchors.top: listview.bottom + anchors.topMargin: 16 + anchors.rightMargin: 2 + text: qsTr("Ok") + onClicked: dlg.close() + } + } + } +} \ No newline at end of file diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml index 3322295..fb22b24 100644 --- a/GlosSIConfig/qml/main.qml +++ b/GlosSIConfig/qml/main.qml @@ -45,6 +45,12 @@ Window { property bool steamShortcutsChanged: false + Component.onCompleted: function() { + if (!uiModel.foundSteam) { + steamNotFoundDialog.open(); + } + } + Image { anchors.top: parent.top anchors.left: parent.left @@ -55,6 +61,10 @@ Window { opacity: 0.033 } + SteamNotFoundDialog { + id: steamNotFoundDialog + } + InfoDialog { id: steamChangedDialog titleText: qsTr("Attention!") From 40390b568d97fca3ec135d9c9c8beb3dae49af32 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Sun, 11 Sep 2022 23:41:29 +0200 Subject: [PATCH 04/35] Add extra log msg if shortcuts.vdf doesn't exist --- GlosSIConfig/UIModel.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index 212bb4c..bda74a0 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -424,6 +424,11 @@ bool UIModel::foundSteam() const void UIModel::parseShortcutVDF() { const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + shortcutsfile_.toStdWString(); + if (!std::filesystem::exists(config_path)) { + qDebug() << "Shortcuts file does not exist."; + return; + } + try { shortcuts_vdf_ = VDFParser::Parser::parseShortcuts(config_path, qDebug()); } From 7208d7e036e0f17a00cc86ef157bd1d77339237c Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Mon, 12 Sep 2022 00:21:25 +0200 Subject: [PATCH 05/35] Add dialog/functionality to inform user on "SteamController_XBoxSupport" --- GlosSIConfig/GlosSIConfig.vcxproj | 1 + GlosSIConfig/GlosSIConfig.vcxproj.filters | 3 + GlosSIConfig/Resource.rc | 80 ++++++++++++- GlosSIConfig/UIModel.cpp | 76 ++++++++++++ GlosSIConfig/UIModel.h | 6 + GlosSIConfig/qml.qrc | 1 + .../qml/SteamInputXboxDisabledDialog.qml | 111 ++++++++++++++++++ GlosSIConfig/qml/main.qml | 8 ++ 8 files changed, 282 insertions(+), 4 deletions(-) create mode 100644 GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj index c573119..816dbf2 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj +++ b/GlosSIConfig/GlosSIConfig.vcxproj @@ -137,6 +137,7 @@ + diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters index b9af58c..757008d 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj.filters +++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters @@ -68,6 +68,9 @@ qml + + qml + diff --git a/GlosSIConfig/Resource.rc b/GlosSIConfig/Resource.rc index 9b95676..0c465db 100644 --- a/GlosSIConfig/Resource.rc +++ b/GlosSIConfig/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,8,102000500230 - PRODUCTVERSION 0,0,8,102000500230 + FILEVERSION 0,0,8,105004039005 + PRODUCTVERSION 0,0,8,105004039005 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - Config" - VALUE "FileVersion", "0.0.8.1-2-gc5fc23d" + VALUE "FileVersion", "0.0.8.1-5-g40390b5" VALUE "InternalName", "GlosSIConfig" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.8.1-2-gc5fc23d" + VALUE "ProductVersion", "0.0.8.1-5-g40390b5" END END BLOCK "VarFileInfo" @@ -800,6 +800,78 @@ IDI_ICON1 ICON "..\GloSC_Icon.ico" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index bda74a0..b0bce26 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -237,6 +237,46 @@ QVariantMap UIModel::manualProps(QVariant shortcut) return res; } +void UIModel::enableSteamInputXboxSupport() +{ + if (foundSteam()) { + const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + user_config_file_.toStdWString(); + if (!std::filesystem::exists(config_path)) { + qDebug() << "localconfig.vdf does not exist."; + } + QFile file(config_path); + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { + QTextStream in(&file); + QStringList lines; + QString line = in.readLine(); + // simple approach is enough... + while (!in.atEnd()) { + if (line.contains("SteamController_XBoxSupport")) { + if (line.contains("1")) { + qDebug() << "\"SteamController_XBoxSupport\" is already enabled! aborting write..."; + file.close(); + return; + } + qDebug() << "found \"SteamController_XBoxSupport\" line, replacing value..."; + line.replace("0", "1"); + } + lines.push_back(line); + line = in.readLine(); + } + file.close(); + QFile updatedFile(config_path); + if (updatedFile.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { + qDebug() << "writing localconfig.vdf..."; + QTextStream out(&updatedFile); + for (const auto& l : lines) { + out << l << "\n"; + } + } + updatedFile.close(); + } + } +} + #ifdef _WIN32 QVariantList UIModel::uwpApps() { @@ -436,3 +476,39 @@ void UIModel::parseShortcutVDF() qDebug() << "Error parsing VDF: " << e.what(); } } + +bool UIModel::isSteamInputXboxSupportEnabled() const +{ + // return true as default to not bug the user in error cases. + if (foundSteam()) { + const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + user_config_file_.toStdWString(); + if (!std::filesystem::exists(config_path)) { + qDebug() << "localconfig.vdf does not exist."; + return true; + } + QFile file(config_path); + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { + QTextStream in(&file); + QString line = in.readLine(); + // simple, regex approach should be enough... + while (!in.atEnd()) { + if (line.contains("SteamController_XBoxSupport")) { + file.close(); + if (line.contains("1")) { + qDebug() << "\"SteamController_XBoxSupport\" is enabled!"; + return true; + } + qDebug() << "\"SteamController_XBoxSupport\" is disabled!"; + return false; + } + line = in.readLine(); + } + qDebug() << "couldn't find \"SteamController_XBoxSupport\" in localconfig.vdf"; + file.close(); + } + else { + qDebug() << "could not open localconfig.vdf"; + } + } + return true; +} diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h index d17e231..38b6007 100644 --- a/GlosSIConfig/UIModel.h +++ b/GlosSIConfig/UIModel.h @@ -28,6 +28,7 @@ class UIModel : public QObject { Q_PROPERTY(QVariantList targetList READ getTargetList NOTIFY targetListChanged) Q_PROPERTY(QVariantList uwpList READ uwpApps CONSTANT) Q_PROPERTY(bool foundSteam READ foundSteam CONSTANT) + Q_PROPERTY(bool steamInputXboxSupportEnabled READ isSteamInputXboxSupportEnabled CONSTANT) public: UIModel(); @@ -42,6 +43,7 @@ class UIModel : public QObject { bool addToSteam(const QString& name, const QString& shortcutspath, bool from_cmd = false); Q_INVOKABLE bool removeFromSteam(const QString& name, const QString& shortcutspath, bool from_cmd = false); Q_INVOKABLE QVariantMap manualProps(QVariant shortcut); + Q_INVOKABLE void enableSteamInputXboxSupport(); #ifdef _WIN32 Q_INVOKABLE QVariantList uwpApps(); #endif @@ -71,7 +73,11 @@ class UIModel : public QObject { std::wstring getSteamUserId() const; bool foundSteam() const; void parseShortcutVDF(); + + bool isSteamInputXboxSupportEnabled() const; + QString shortcutsfile_ = "/config/shortcuts.vdf"; + QString user_config_file_ = "/config/localconfig.vdf"; QString user_data_path_ = "/userdata/"; QVariantList targets_; diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc index 28a36de..b626964 100644 --- a/GlosSIConfig/qml.qrc +++ b/GlosSIConfig/qml.qrc @@ -16,5 +16,6 @@ GloSC_Icon_small.png svg/help_outline_white_24dp.svg qml/SteamNotFoundDialog.qml + qml/SteamInputXboxDisabledDialog.qml diff --git a/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml new file mode 100644 index 0000000..7c4e9f0 --- /dev/null +++ b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml @@ -0,0 +1,111 @@ +/* +Copyright 2021-2022 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import QtQuick 6.2 +import QtQuick.Controls 6.2 +import QtQuick.Layouts 6.2 +import QtQuick.Controls.Material 6.2 + +Dialog { + id: dlg + anchors.centerIn: parent + + signal confirmed(var param) + + visible: false + modal: true + dim: true + parent: Overlay.overlay + Overlay.modal: Rectangle { + color: Qt.rgba(0,0,0,0.4) + opacity: backdropOpacity + Behavior on opacity { + NumberAnimation { + duration: 300 + } + } + } + property real backdropOpacity: 1.0 + + enter: Transition { + NumberAnimation{target: content; property: "y"; from: parent.height; to: 16; duration: 300; easing.type: Easing.OutQuad } + NumberAnimation{target: background; property: "y"; from: parent.height; to: 0; duration: 300; easing.type: Easing.OutQuad } + NumberAnimation{target: dlg; property: "backdropOpacity"; from: 0; to: 1; duration: 300; easing.type: Easing.OutQuad } + } + + exit: Transition { + NumberAnimation{target: content; property: "y"; from: 16; to: parent.height; duration: 300; easing.type: Easing.InQuad } + NumberAnimation{target: background; property: "y"; from: 0; to: parent.height; duration: 300; easing.type: Easing.InQuad } + NumberAnimation{target: dlg; property: "backdropOpacity"; from: 1; to: 0; duration: 300; easing.type: Easing.InQuad } + } + + background: RPane { + id: background + radius: 4 + Material.elevation: 64 + bgOpacity: 0.97 + } + + contentItem: Item { + id: content + clip: true + Column { + spacing: 4 + bottomPadding: 96 + Label { + id: titlelabel + text: qsTr("Steam Input Xbox support disabled") + font.pixelSize: 24 + font.bold: true + } + Item { + height: 32 + } + Label { + text: qsTr("Please enable \"Xbox configuration support\" in Steams controller settings.\n\nGlosSI cannot function properly with this setting disabled\n\nEnable now?") + wrapMode: Text.WordWrap + width: parent.width + } + Row { + anchors.right: parent.right + anchors.topMargin: 16 + anchors.rightMargin: 2 + spacing: 8 + Button { + id: noBtn + text: qsTr("No") + onClicked: dlg.close() + } + Button { + id: yesBtn + text: qsTr("Yes") + onClicked: function() { + uiModel.enableSteamInputXboxSupport(); + dlg.close(); + steamChangedDialog2.open(); + } + } + } + } + InfoDialog { + id: steamChangedDialog2 + titleText: qsTr("Attention!") + text: qsTr("Please restart Steam to reload your changes!") + onConfirmed: function (callback) { + callback(); + } + } + } +} \ No newline at end of file diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml index fb22b24..9b141e0 100644 --- a/GlosSIConfig/qml/main.qml +++ b/GlosSIConfig/qml/main.qml @@ -48,6 +48,10 @@ Window { Component.onCompleted: function() { if (!uiModel.foundSteam) { steamNotFoundDialog.open(); + return; + } + if (!uiModel.steamInputXboxSupportEnabled) { + steamXboxDisabledDialog.open(); } } @@ -64,6 +68,10 @@ Window { SteamNotFoundDialog { id: steamNotFoundDialog } + SteamInputXboxDisabledDialog { + id: steamXboxDisabledDialog + } + InfoDialog { id: steamChangedDialog From 0139ba78b6bce2a04eb7c785537ba092b3c1cd52 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Sun, 18 Sep 2022 19:08:59 +0200 Subject: [PATCH 06/35] Dummycommit --- GlosSITarget/Resource.rc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/GlosSITarget/Resource.rc b/GlosSITarget/Resource.rc index e37e0b4..88b5f35 100644 --- a/GlosSITarget/Resource.rc +++ b/GlosSITarget/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,7,1018000020006 - PRODUCTVERSION 0,0,7,1018000020006 + FILEVERSION 0,0,8,102000500230 + PRODUCTVERSION 0,0,8,102000500230 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - SteamTarget" - VALUE "FileVersion", "0.0.7.1-18-g0f2bac6" + VALUE "FileVersion", "0.0.8.1-2-gc5fc23d" VALUE "InternalName", "GlosSITarget" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSITarget.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.7.1-18-g0f2bac6" + VALUE "ProductVersion", "0.0.8.1-2-gc5fc23d" END END BLOCK "VarFileInfo" @@ -171,6 +171,22 @@ IDI_ICON1 ICON "GloSC_Icon.ico" + + + + + + + + + + + + + + + + From 3f992c811c3c884708aed7e352e7827b1c502cc9 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Mon, 19 Sep 2022 19:59:10 +0200 Subject: [PATCH 07/35] GlosSIConfig: More help texts / declutter UI --- GlosSIConfig/qml/ShortcutProps.qml | 113 +++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 32 deletions(-) diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index 14ba84c..9f34bc5 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -406,9 +406,11 @@ Item { onClicked: () => { helpInfoDialog.titleText = qsTr("Emulate DS4") helpInfoDialog.text = - qsTr("Instead of X360 Pad") + qsTr("Emulates a DS4 instead of X360 Pad") + "\n" - + qsTr("Disable \"Playstation Configuration support\" in Steam") + qsTr("for usage with, for example, PSNow") + + "\n" + + qsTr("If enabled you have to disable \"Playstation Configuration support\" in Steam") helpInfoDialog.open() } width: 48 @@ -441,6 +443,26 @@ Item { to: 4 onValueChanged: shortcutInfo.maxControllers = value } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Max. emulated controllers") + helpInfoDialog.text = + qsTr("GlosSI will only provide [NUMBER] of controllers") + + "\n" + + qsTr("Required to set to actually connected controller count when using \"real devuce IDs\" ") + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } } } } @@ -453,41 +475,68 @@ Item { Column { spacing: 2 width: parent.width - CheckBox { - id: windowMode - text: qsTr("Steam/GlosSI overlay as separate window") - checked: shortcutInfo.windowMode - onCheckedChanged: shortcutInfo.windowMode = checked - } - Label { - text: qsTr("Doesn't show overlay on top, but as separate window") - wrapMode: Text.WordWrap - width: parent.width - leftPadding: 32 - topPadding: -8 - } - Label { - text: qsTr("Use if blackscreen-issues are encountered.") - wrapMode: Text.WordWrap - width: parent.width - leftPadding: 32 + Row { + CheckBox { + id: windowMode + text: qsTr("Steam/GlosSI overlay as separate window") + checked: shortcutInfo.windowMode + onCheckedChanged: shortcutInfo.windowMode = checked + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Steam/GlosSI overlay as separate window") + helpInfoDialog.text = + qsTr("Doesn't show overlay on top, but as separate window") + + "\n" + + qsTr("Use if blackscreen-issues are encountered.") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } } Item { width: 1 height: 4 } - CheckBox { - id: disableOverlayCheckbox - text: qsTr("Disable Steam/GlosSI overlay") - checked: shortcutInfo.disableOverlay - onCheckedChanged: shortcutInfo.disableOverlay = checked - } - Label { - text: qsTr("Only controller emulation - No extra window") - wrapMode: Text.WordWrap - width: parent.width - leftPadding: 32 - topPadding: -8 + + Row { + CheckBox { + id: disableOverlayCheckbox + text: qsTr("Disable Steam/GlosSI overlay") + checked: shortcutInfo.disableOverlay + onCheckedChanged: shortcutInfo.disableOverlay = checked + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Disable Steam/GlosSI overlay") + helpInfoDialog.text = + qsTr("Only controller emulation - No extra window") + + "\n" + + qsTr("Might help with Steam remote play.") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } } } } From 34fa783d09b53b2c9e139ecaa273866eafdffb39 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 14:29:47 +0200 Subject: [PATCH 08/35] GlosSITarget: Overlay: Add button to store shortcut-settings from target --- GlosSITarget/Overlay.cpp | 15 +++++++++++++++ GlosSITarget/Overlay.h | 1 + GlosSITarget/Settings.h | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index d317175..f7c6538 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -21,6 +21,7 @@ limitations under the License. #include #include "Roboto.h" +#include "Settings.h" Overlay::Overlay( sf::RenderWindow& window, @@ -166,6 +167,7 @@ void Overlay::update() } closeOverlayButton(); + saveSettingsButton(); } ImGui::SFML::Render(window_); @@ -306,3 +308,16 @@ bool Overlay::closeButton() const ImGui::PopStyleVar(); return false; } + +void Overlay::saveSettingsButton() const +{ + if (Settings::settings_path_ != "") { + ImGui::SetNextWindowPos({(window_.getSize().x - ImGui::GetWindowWidth()) / 2, (window_.getSize().y - ImGui::GetWindowHeight()) / 2}, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSizeConstraints({192, 96}, {512, 512}); + ImGui::Begin("Shortcut settings"); + if (ImGui::Button("Save settings", {256, 32})) { + Settings::StoreSettings(); + } + ImGui::End(); + } +} diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h index 46cda4f..0e97ffa 100644 --- a/GlosSITarget/Overlay.h +++ b/GlosSITarget/Overlay.h @@ -50,6 +50,7 @@ class Overlay { void showLogs(); bool closeOverlayButton() const; [[nodiscard]] bool closeButton() const; + void saveSettingsButton() const; bool force_enable_ = false; bool log_expanded_ = true; diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index 23e71b8..3b771f9 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -52,6 +52,8 @@ inline struct Controller { bool emulateDS4 = false; } controller; +inline std::filesystem::path settings_path_ = ""; + inline bool checkIsUwp(const std::wstring& launch_path) { if (launch_path.find(L"://") != std::wstring::npos) { @@ -87,6 +89,7 @@ inline void Parse(std::wstring arg1) spdlog::error(L"Couldn't open settings file {}", path.wstring()); return; } + settings_path_ = path; const auto json = nlohmann::json::parse(json_file); if (json["version"] != 1) { // TODO: versioning stuff spdlog::warn("Config version doesn't match application version."); @@ -102,10 +105,10 @@ inline void Parse(std::wstring arg1) value = object[key]; } catch (const nlohmann::json::exception& e) { - spdlog::error("Err parsing \"{}\"; {}", key, e.what()); + spdlog::warn("Err parsing \"{}\"; {}", key, e.what()); } catch (const std::exception& e) { - spdlog::error("Err parsing \"{}\"; {}", key, e.what()); + spdlog::warn("Err parsing \"{}\"; {}", key, e.what()); } }; @@ -154,4 +157,33 @@ inline void Parse(std::wstring arg1) } } +inline void StoreSettings() +{ + nlohmann::json json; + json["version"] = 1; + json["launch"]["launch"] = launch.launch; + json["launch"]["launchPath"] = std::wstring_convert>().to_bytes(launch.launchPath); + json["launch"]["launchAppArgs"] = std::wstring_convert>().to_bytes(launch.launchAppArgs); + json["launch"]["closeOnExit"] = launch.closeOnExit; + json["launch"]["waitForChildProcs"] = launch.waitForChildProcs; + json["devices"]["hideDevices"] = devices.hideDevices; + json["devices"]["realDeviceIds"] = devices.realDeviceIds; + json["window"]["windowMode"] = window.windowMode; + json["window"]["maxFps"] = window.maxFps; + json["window"]["scale"] = window.scale; + json["window"]["disableOverlay"] = window.disableOverlay; + json["controller"]["maxControllers"] = controller.maxControllers; + json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig; + json["controller"]["emulateDS4"] = controller.emulateDS4; + + std::ofstream json_file; + json_file.open(settings_path_); + if (!json_file.is_open()) { + spdlog::error(L"Couldn't open settings file {}", settings_path_.wstring()); + return; + } + json_file << json.dump(4); + json_file.close(); +} + } // namespace Settings From f70cbdbe926ba56e37f3cd4869599c3d02053fc6 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:00:50 +0200 Subject: [PATCH 09/35] GlosSITarget: more and extended logging --- GlosSITarget/HidHide.cpp | 15 +++++++++++++++ GlosSITarget/Settings.h | 15 +++++++++++++++ GlosSITarget/SteamOverlayDetector.cpp | 7 +++++++ GlosSITarget/TargetWindow.cpp | 9 +++++++++ 4 files changed, 46 insertions(+) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index 52bf1bf..89be22b 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -102,6 +102,9 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) whitelist.push_back(path); } } + if (Settings::extendedLogging) { + std::ranges::for_each(whitelist, [](const auto& exe) { spdlog::debug(L"Whitelisted executable: {}", exe); }); + } setAppWhiteList(whitelist); avail_devices_ = GetHidDeviceList(); @@ -127,6 +130,9 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) setBlacklistDevices(blacklisted_devices_); setActive(true); spdlog::info("Hid Gaming Devices; Enabling Overlay element..."); + if (Settings::extendedLogging) { + std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + } enableOverlayElement(); } closeCtrlDevice(); @@ -186,6 +192,9 @@ void HidHide::enableOverlayElement() if (window_has_focus && (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_)) { openCtrlDevice(); bool hidehide_state_store = hidhide_active_; + if (Settings::extendedLogging) { + spdlog::debug("Refreshing HID devices"); + } if (hidhide_active_) { setActive(false); } @@ -224,6 +233,9 @@ void HidHide::enableOverlayElement() blacklisted_devices_.end()); } setBlacklistDevices(blacklisted_devices_); + if (Settings::extendedLogging) { + std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + } closeCtrlDevice(); } }); @@ -316,6 +328,9 @@ void HidHide::setActive(bool active) return; } hidhide_active_ = active; + if (Settings::extendedLogging) { + spdlog::debug("HidHide State set to {}", active); + } } DWORD HidHide::getRequiredOutputBufferSize(IOCTL_TYPE type) const diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index 3b771f9..e62f395 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -52,6 +52,8 @@ inline struct Controller { bool emulateDS4 = false; } controller; +inline bool extendedLogging = true; + inline std::filesystem::path settings_path_ = ""; inline bool checkIsUwp(const std::wstring& launch_path) @@ -147,6 +149,17 @@ inline void Parse(std::wstring arg1) safeParseValue(controllerConf, "emulateDS4", controller.emulateDS4); } + try { + if (auto extlog = json["extendedLogging"]; extlog.is_boolean()) { + extendedLogging = extlog; + } + } + catch (...) + { + } + + + json_file.close(); // c++ is stupid... @@ -176,6 +189,8 @@ inline void StoreSettings() json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig; json["controller"]["emulateDS4"] = controller.emulateDS4; + json["extendedLogging"] = extendedLogging; + std::ofstream json_file; json_file.open(settings_path_); if (!json_file.is_open()) { diff --git a/GlosSITarget/SteamOverlayDetector.cpp b/GlosSITarget/SteamOverlayDetector.cpp index 003a1e6..a7e52a2 100644 --- a/GlosSITarget/SteamOverlayDetector.cpp +++ b/GlosSITarget/SteamOverlayDetector.cpp @@ -17,6 +17,8 @@ limitations under the License. #include +#include "Settings.h" + #ifdef _WIN32 #define NOMINMAX #include @@ -44,6 +46,11 @@ void SteamOverlayDetector::update() // okey to use nullptr as hwnd. get EVERY message if (PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) { // filter out some messages as not all get altered by steam... + + if (Settings::extendedLogging && msg.message != 512) { + spdlog::trace("PeekMessage: Window msg: {}", msg.message); + } + if (msg.message < 1000 && msg.message > 0) { return; } diff --git a/GlosSITarget/TargetWindow.cpp b/GlosSITarget/TargetWindow.cpp index 119c5fd..b411af6 100644 --- a/GlosSITarget/TargetWindow.cpp +++ b/GlosSITarget/TargetWindow.cpp @@ -259,12 +259,21 @@ void TargetWindow::createWindow(bool window_mode) // as a workaround, start in full size, and scale down later... spdlog::info("Creating Overlay window (Borderless Fullscreen)..."); window_.create(sf::VideoMode(desktop_mode.width -1, desktop_mode.height -1, 32), "GlosSITarget", sf::Style::None); + + // get size of all monitors combined + const auto screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + const auto screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + spdlog::debug("Full screen size: {}x{}", screenWidth, screenHeight); + + spdlog::debug("Primary monitor size: {}x{}", desktop_mode.width, desktop_mode.height); + #else window_.create(desktop_mode, "GlosSITarget", sf::Style::None); #endif windowed_ = false; } window_.setActive(true); + spdlog::debug("Window position: {}x{}", window_.getPosition().x, window_.getPosition().y); #ifdef _WIN32 HWND hwnd = window_.getSystemHandle(); From a337c0e5a10965ae65c31bb1166869138dce2dd0 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:02:22 +0200 Subject: [PATCH 10/35] GlosSITarget: Only refresh hidHide list if windows is actually open --- GlosSITarget/HidHide.cpp | 95 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index 89be22b..447808a 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -189,61 +189,62 @@ void HidHide::UnPatchHook(const std::string& name, HMODULE module) void HidHide::enableOverlayElement() { Overlay::AddOverlayElem([this](bool window_has_focus) { - if (window_has_focus && (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_)) { - openCtrlDevice(); - bool hidehide_state_store = hidhide_active_; - if (Settings::extendedLogging) { - spdlog::debug("Refreshing HID devices"); - } - if (hidhide_active_) { - setActive(false); - } - avail_devices_ = GetHidDeviceList(); - blacklisted_devices_ = getBlackListDevices(); - if (hidehide_state_store) { - setActive(true); - } - closeCtrlDevice(); - overlay_elem_clock_.restart(); - } ImGui::SetNextWindowPos({650, 100}, ImGuiCond_FirstUseEver); ImGui::SetNextWindowSizeConstraints({400, 270}, {1000, 1000}); - ImGui::Begin("Hidden Devices"); - ImGui::BeginChild("Inner", {0.f, ImGui::GetItemRectSize().y - 64}, true); - std::ranges::for_each(avail_devices_, [this](const auto& device) { - std::string label = (std::string(device.name.begin(), std::ranges::find(device.name, L'\0')) + "##" + std::string(device.device_instance_path.begin(), device.device_instance_path.end())); - const auto findDeviceFn = [&device](const auto& blackdev) { - return device.device_instance_path == blackdev || device.base_container_device_instance_path == blackdev; - }; - bool hidden = std::ranges::find_if(blacklisted_devices_, findDeviceFn) != blacklisted_devices_.end(); - if (ImGui::Checkbox(label.data(), &hidden)) { + if (ImGui::Begin("Hidden Devices")) { + if (window_has_focus && (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_)) { openCtrlDevice(); - if (hidden) { - if (std::ranges::none_of(blacklisted_devices_, findDeviceFn)) { - if (!device.device_instance_path.empty()) { - blacklisted_devices_.push_back(device.device_instance_path); - } - if (!device.device_instance_path.empty()) { - blacklisted_devices_.push_back(device.base_container_device_instance_path); - } - } + bool hidehide_state_store = hidhide_active_; + if (Settings::extendedLogging) { + spdlog::debug("Refreshing HID devices"); } - else { - blacklisted_devices_.erase(std::ranges::remove_if(blacklisted_devices_, findDeviceFn).begin(), - blacklisted_devices_.end()); + if (hidhide_active_) { + setActive(false); } - setBlacklistDevices(blacklisted_devices_); - if (Settings::extendedLogging) { - std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + avail_devices_ = GetHidDeviceList(); + blacklisted_devices_ = getBlackListDevices(); + if (hidehide_state_store) { + setActive(true); } closeCtrlDevice(); + overlay_elem_clock_.restart(); + } + ImGui::BeginChild("Inner", {0.f, ImGui::GetItemRectSize().y - 64}, true); + std::ranges::for_each(avail_devices_, [this](const auto& device) { + std::string label = (std::string(device.name.begin(), std::ranges::find(device.name, L'\0')) + "##" + std::string(device.device_instance_path.begin(), device.device_instance_path.end())); + const auto findDeviceFn = [&device](const auto& blackdev) { + return device.device_instance_path == blackdev || device.base_container_device_instance_path == blackdev; + }; + bool hidden = std::ranges::find_if(blacklisted_devices_, findDeviceFn) != blacklisted_devices_.end(); + if (ImGui::Checkbox(label.data(), &hidden)) { + openCtrlDevice(); + if (hidden) { + if (std::ranges::none_of(blacklisted_devices_, findDeviceFn)) { + if (!device.device_instance_path.empty()) { + blacklisted_devices_.push_back(device.device_instance_path); + } + if (!device.device_instance_path.empty()) { + blacklisted_devices_.push_back(device.base_container_device_instance_path); + } + } + } + else { + blacklisted_devices_.erase(std::ranges::remove_if(blacklisted_devices_, findDeviceFn).begin(), + blacklisted_devices_.end()); + } + setBlacklistDevices(blacklisted_devices_); + if (Settings::extendedLogging) { + std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + } + closeCtrlDevice(); + } + }); + ImGui::EndChild(); + if (ImGui::Checkbox("Devices Hidden", &hidhide_active_)) { + openCtrlDevice(); + setActive(hidhide_active_); + closeCtrlDevice(); } - }); - ImGui::EndChild(); - if (ImGui::Checkbox("Devices Hidden", &hidhide_active_)) { - openCtrlDevice(); - setActive(hidhide_active_); - closeCtrlDevice(); } ImGui::End(); }); From 7e0e3fa1432bdb1409af076ca5b3ebf55618b61f Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:07:52 +0200 Subject: [PATCH 11/35] Default "MaxControllers" to 1 (most common use case) --- GlosSIConfig/qml/ShortcutProps.qml | 4 ++-- GlosSITarget/Settings.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index 9f34bc5..889bc99 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -42,7 +42,7 @@ Item { maxFps: null, scale: null, icon: null, - maxControllers: 4, + maxControllers: 1, disableOverlay: false, realDeviceIds: false, allowDesktopConfig: false, @@ -63,7 +63,7 @@ Item { maxFps: null, scale: null, icon: null, - maxControllers: 4, + maxControllers: 1, disableOverlay: false, realDeviceIds: false, allowDesktopConfig: false, diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index e62f395..ffbc2a1 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -47,7 +47,7 @@ inline struct Window { } window; inline struct Controller { - int maxControllers = 4; + int maxControllers = 1; bool allowDesktopConfig = false; bool emulateDS4 = false; } controller; From 46c7980fe08e09ccb21aef18269cfc87be60d19a Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:08:22 +0200 Subject: [PATCH 12/35] InputRedirector: Log VID/PID --- GlosSITarget/InputRedirector.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GlosSITarget/InputRedirector.cpp b/GlosSITarget/InputRedirector.cpp index 2645b10..c379e8a 100644 --- a/GlosSITarget/InputRedirector.cpp +++ b/GlosSITarget/InputRedirector.cpp @@ -178,7 +178,11 @@ void InputRedirector::runLoop() } } if (target_add_res == VIGEM_ERROR_NONE) { - spdlog::info("Plugged in controller {}, {}", i, vigem_target_get_index(vt_pad_[i])); + spdlog::info("Plugged in controller {}, {}; VID: {:x}; PID: {:x}", + i, + vigem_target_get_index(vt_pad_[i]), + vigem_target_get_vid(vt_pad_[i]), + vigem_target_get_pid(vt_pad_[i])); if (Settings::controller.emulateDS4) { const auto callback_register_res = vigem_target_ds4_register_notification( From 3619c53ad74e2060905c7cc2e4242951c9ebb5a0 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:18:40 +0200 Subject: [PATCH 13/35] OverlayDetector: filter out more msg in extended logs --- GlosSITarget/SteamOverlayDetector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GlosSITarget/SteamOverlayDetector.cpp b/GlosSITarget/SteamOverlayDetector.cpp index a7e52a2..12fdf86 100644 --- a/GlosSITarget/SteamOverlayDetector.cpp +++ b/GlosSITarget/SteamOverlayDetector.cpp @@ -47,7 +47,7 @@ void SteamOverlayDetector::update() if (PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) { // filter out some messages as not all get altered by steam... - if (Settings::extendedLogging && msg.message != 512) { + if (Settings::extendedLogging && msg.message != 512 && msg.message != 5374) { spdlog::trace("PeekMessage: Window msg: {}", msg.message); } From 4ca497f306bdfcb40e4e13072dce485fed3f7ed9 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:19:01 +0200 Subject: [PATCH 14/35] HideHide: set extended logs (applist /devices blacklist) to trace --- GlosSITarget/HidHide.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index 447808a..bc6a3e4 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -103,7 +103,9 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) } } if (Settings::extendedLogging) { - std::ranges::for_each(whitelist, [](const auto& exe) { spdlog::debug(L"Whitelisted executable: {}", exe); }); + std::ranges::for_each(whitelist, [](const auto& exe) { + spdlog::trace(L"Whitelisted executable: {}", exe); + }); } setAppWhiteList(whitelist); @@ -131,7 +133,9 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) setActive(true); spdlog::info("Hid Gaming Devices; Enabling Overlay element..."); if (Settings::extendedLogging) { - std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { + spdlog::trace(L"Blacklisted device: {}", dev); + }); } enableOverlayElement(); } @@ -234,7 +238,9 @@ void HidHide::enableOverlayElement() } setBlacklistDevices(blacklisted_devices_); if (Settings::extendedLogging) { - std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { spdlog::debug(L"Blacklisted device: {}", dev); }); + std::ranges::for_each(blacklisted_devices_, [](const auto& dev) { + spdlog::trace(L"Blacklisted device: {}", dev); + }); } closeCtrlDevice(); } From 9c12fd6febeb54ebebbccdde1d46c0206f662b20 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:25:12 +0200 Subject: [PATCH 15/35] Change/Fix use real vid/pid feature --- GlosSITarget/InputRedirector.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/GlosSITarget/InputRedirector.cpp b/GlosSITarget/InputRedirector.cpp index c379e8a..b4bf106 100644 --- a/GlosSITarget/InputRedirector.cpp +++ b/GlosSITarget/InputRedirector.cpp @@ -163,7 +163,10 @@ void InputRedirector::runLoop() // Multiple controllers can be worked around with by setting max count. if (!use_real_vid_pid_) { vigem_target_set_vid(vt_pad_[i], 0x28de); //VALVE_DIRECTINPUT_GAMEPAD_VID - // vigem_target_set_pid(vt_pad_[i], 0x11FF); //VALVE_DIRECTINPUT_GAMEPAD_PID + vigem_target_set_pid(vt_pad_[i], 0x11FF); //VALVE_DIRECTINPUT_GAMEPAD_PID + } else { + vigem_target_set_vid(vt_pad_[i], 0x045E); // MICROSOFT + vigem_target_set_pid(vt_pad_[i], 0x028E); // XBOX 360 Controller } // TODO: MAYBE!: In a future version, use something like OpenXInput //and filter out emulated controllers to support a greater amount of controllers simultaneously From 42bd2cba8166643477122f66c7c6c2d5cdd115a5 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:43:37 +0200 Subject: [PATCH 16/35] Block window refocusing if handle == nullptr --- GlosSITarget/SteamTarget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp index b11a51a..89feee7 100644 --- a/GlosSITarget/SteamTarget.cpp +++ b/GlosSITarget/SteamTarget.cpp @@ -181,6 +181,9 @@ void SteamTarget::toggleGlossiOverlay() void SteamTarget::focusWindow(WindowHandle hndl) { + if (reinterpret_cast(hndl) == 0) { + return; + } #ifdef _WIN32 if (hndl == target_window_handle_) { spdlog::debug("Bring own window to foreground"); From 3c1587b5ed78bc07d5e43105a0ead44cd0dca78e Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 20 Sep 2022 20:53:40 +0200 Subject: [PATCH 17/35] Add logging to UWPOverlay enabler --- .../UWPOverlayEnablerDLL.vcxproj | 6 ++- UWPOverlayEnablerDLL/dllmain.cpp | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj index 9d0ad5a..34e5567 100644 --- a/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj +++ b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj @@ -78,11 +78,11 @@ true - ..\deps\subhook;$(IncludePath) + ..\deps\subhook;..\deps\spdlog\include;$(IncludePath) false - ..\deps\subhook;$(IncludePath) + ..\deps\subhook;..\deps\spdlog\include;$(IncludePath) @@ -126,6 +126,7 @@ true NotUsing pch.h + stdcpp20 Windows @@ -143,6 +144,7 @@ true NotUsing pch.h + stdcpp20 Windows diff --git a/UWPOverlayEnablerDLL/dllmain.cpp b/UWPOverlayEnablerDLL/dllmain.cpp index fe4dd04..1ce6e6a 100644 --- a/UWPOverlayEnablerDLL/dllmain.cpp +++ b/UWPOverlayEnablerDLL/dllmain.cpp @@ -47,8 +47,14 @@ There are two (known to me, at time of writing) ways to get a working overlay fo #define SUBHOOK_STATIC #include +#include #include +#include +#include +#include + + enum ZBID { ZBID_DEFAULT = 0, @@ -85,13 +91,16 @@ BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand) const auto glossi_hwnd = FindWindowA(nullptr, "GlosSITarget"); if (glossi_hwnd) { + spdlog::info("Found GlosSI Window"); // Most window bands don't really seem to work. // However, notification and system_tools does! // use system tools, as that allows the steam overlay to be interacted with // without UWP apps minimizing SetWindowBand(glossi_hwnd, nullptr, ZBID_SYSTEM_TOOLS); allow_exit = true; + spdlog::info("Set GlosSI Window Band to ZBID_SYSTEM_TOOLS"); } + spdlog::info("Calling original"); return SetWindowBand(hWnd, hwndInsertAfter, dwBand); } @@ -102,7 +111,10 @@ DWORD WINAPI WaitThread(HMODULE hModule) Sleep(10); } if (SetWindowBandHook.IsInstalled()) + { + spdlog::debug("Uninstalling SetWindowBand hook"); SetWindowBandHook.Remove(); + } FreeLibraryAndExitThread(hModule, 0); } @@ -113,17 +125,47 @@ BOOL APIENTRY DllMain( HMODULE hModule, { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { + + auto path = std::filesystem::temp_directory_path() + .parent_path() + .parent_path() + .parent_path(); + + path /= "Roaming"; + path /= "GlosSI"; + if (!std::filesystem::exists(path)) + std::filesystem::create_directories(path); + path /= "UWPOverlayEnabler.log"; + const auto file_sink = std::make_shared(path.string(), true); + std::vector sinks{ file_sink }; + auto logger = std::make_shared("log", sinks.begin(), sinks.end()); + logger->set_level(spdlog::level::trace); + logger->flush_on(spdlog::level::trace); + spdlog::set_default_logger(logger); + + spdlog::info("UWPOverlayEnabler loaded"); + const auto hpath = LoadLibrary(L"user32.dll"); if (hpath) { + spdlog::debug("Loaded user32.dll"); + spdlog::debug("Installing SetWindowBand hook"); SetWindowBand = reinterpret_cast(GetProcAddress(hpath, "SetWindowBand")); SetWindowBandHook.Install(GetProcAddress(hpath, "SetWindowBand"), &SetGlosSIWindowBand, subhook::HookFlags::HookFlag64BitOffset); + spdlog::debug("Creating wait thread"); CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)WaitThread, hModule, 0, nullptr)); + } else + { + spdlog::error("Loaded user32.dll"); } } else if (ul_reason_for_call == DLL_PROCESS_DETACH) { + spdlog::info("unloading UWPOverlayEnabler"); if (SetWindowBandHook.IsInstalled()) + { + spdlog::debug("Uninstalling SetWindowBand hook"); SetWindowBandHook.Remove(); + } } return TRUE; } From 7c706945bc43dd104d12bd076733acfc043ac06b Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Thu, 22 Sep 2022 20:44:56 +0200 Subject: [PATCH 18/35] Fix potential settings crash on launch --- GlosSITarget/Settings.h | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index ffbc2a1..b4eb6fd 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -92,14 +92,8 @@ inline void Parse(std::wstring arg1) return; } settings_path_ = path; - const auto json = nlohmann::json::parse(json_file); - if (json["version"] != 1) { // TODO: versioning stuff - spdlog::warn("Config version doesn't match application version."); - } - - // TODO: make this as much generic as fits in about the same amount of code if one would parse every value separately. - auto safeParseValue = [](const auto& object, const auto& key, auto& value) { + auto safeParseValue = [](const auto& object, const auto& key, auto& value) { try { if (object.is_null() || object.empty() || object.at(key).empty() || object.at(key).is_null()) { return; @@ -123,6 +117,15 @@ inline void Parse(std::wstring arg1) } }; + const auto json = nlohmann::json::parse(json_file); + int version; + safeParseValue(json, "version" ,version); + if (version != 1) { // TODO: versioning stuff + spdlog::warn("Config version doesn't match application version."); + } + + // TODO: make this as much generic as fits in about the same amount of code if one would parse every value separately. + if (auto launchconf = json["launch"]; launchconf.is_object()) { safeParseValue(launchconf, "launch", launch.launch); safeWStringParse(launchconf, "launchPath", launch.launchPath); @@ -149,16 +152,7 @@ inline void Parse(std::wstring arg1) safeParseValue(controllerConf, "emulateDS4", controller.emulateDS4); } - try { - if (auto extlog = json["extendedLogging"]; extlog.is_boolean()) { - extendedLogging = extlog; - } - } - catch (...) - { - } - - + safeParseValue(json, "extendedLogging", extendedLogging); json_file.close(); From 40c1b01f4dff0ee0e7a01e79724ff253650b11bd Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Thu, 22 Sep 2022 22:10:37 +0200 Subject: [PATCH 19/35] Don't show "popup" log window anymore if no warnings or worse present (20s after launch) --- GlosSITarget/Overlay.cpp | 12 +++++++++--- GlosSITarget/Overlay.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index f7c6538..b1cadcd 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -208,14 +208,16 @@ void Overlay::showLogs() if (!enabled_ && !log_expanded_) { return; } + bool logs_contain_warn_or_worse = false; if (enabled_) { logs = LOG_MSGS_; } else { std::ranges::copy_if(LOG_MSGS_, std::back_inserter(logs), - [](const auto& log) { - return ( + [&logs_contain_warn_or_worse](const auto& log) { + + const auto res = ( log.time.time_since_epoch() + std::chrono::seconds( LOG_RETENTION_TIME_) > std::chrono::system_clock::now().time_since_epoch()) @@ -223,9 +225,13 @@ void Overlay::showLogs() && (log.level > spdlog::level::debug) #endif ; + if (res && log.level > spdlog::level::warn) { + logs_contain_warn_or_worse = true; + } + return res; }); } - if (logs.empty()) + if (logs.empty() || ( !enabled_ && !logs_contain_warn_or_worse && time_since_start_clock_.getElapsedTime().asSeconds() > HIDE_NORMAL_LOGS_AFTER_S)) return; ImGui::SetNextWindowSizeConstraints({150, 150}, {1000, window_.getSize().y - 250.f}); if (!enabled_) { diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h index 0e97ffa..b971bfa 100644 --- a/GlosSITarget/Overlay.h +++ b/GlosSITarget/Overlay.h @@ -53,6 +53,7 @@ class Overlay { void saveSettingsButton() const; bool force_enable_ = false; bool log_expanded_ = true; + sf::Clock time_since_start_clock_; struct Log { std::chrono::system_clock::time_point time; @@ -61,6 +62,7 @@ class Overlay { }; static inline std::vector LOG_MSGS_; static constexpr int LOG_RETENTION_TIME_ = 5; + static constexpr int HIDE_NORMAL_LOGS_AFTER_S = 20; static inline int overlay_element_id_ = 0; static inline std::map> OVERLAY_ELEMS_; From 891a5a296944ea0950465513c26fce0655d649d3 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 01:24:28 +0200 Subject: [PATCH 20/35] Update shortcuts_vdf submodule; Fixes no SteamOverlay showing up --- deps/Shortcuts_VDF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/Shortcuts_VDF b/deps/Shortcuts_VDF index 2816b31..59108a7 160000 --- a/deps/Shortcuts_VDF +++ b/deps/Shortcuts_VDF @@ -1 +1 @@ -Subproject commit 2816b31c8e777c2920e1f0881ce10c5c66e30c63 +Subproject commit 59108a7f9a938911e1cc237003a396c886be85f8 From 028b18deb6d70200ca1c91ff999891a871ff4d36 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 12:00:58 +0200 Subject: [PATCH 21/35] Default extendedLogging to false --- GlosSITarget/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index b4eb6fd..9e25bc9 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -52,7 +52,7 @@ inline struct Controller { bool emulateDS4 = false; } controller; -inline bool extendedLogging = true; +inline bool extendedLogging = false; inline std::filesystem::path settings_path_ = ""; From 54e6bf610bf69d6444d6025e73ee3951ec683be4 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 12:48:13 +0200 Subject: [PATCH 22/35] GlosSIConfig: Refactor reading/writing target configs --- GlosSIConfig/UIModel.cpp | 79 ++++------------ GlosSIConfig/UIModel.h | 32 +++---- GlosSIConfig/qml/ShortcutProps.qml | 142 ++++++++++++++--------------- 3 files changed, 103 insertions(+), 150 deletions(-) diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index b0bce26..f75ac62 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -39,16 +39,16 @@ UIModel::UIModel() : QObject(nullptr) std::filesystem::create_directories(path); config_path_ = path; - config_dir_name_ = QString::fromStdWString((path /= "Targets").wstring().data()); + config_dir_name_ = QString::fromStdWString((path /= "Targets").wstring()); if (!std::filesystem::exists(path)) std::filesystem::create_directories(path); parseShortcutVDF(); - readConfigs(); + readTargetConfigs(); } -void UIModel::readConfigs() +void UIModel::readTargetConfigs() { QDir dir(config_dir_name_); auto entries = dir.entryList(QDir::Files, QDir::SortFlag::Name); @@ -68,29 +68,13 @@ void UIModel::readConfigs() const auto data = file.readAll(); file.close(); const auto jsondoc = QJsonDocument::fromJson(data); - const auto filejson = jsondoc.object(); - - QJsonObject json; - json["version"] = filejson["version"]; - json["icon"] = filejson["icon"]; - json["launch"] = filejson["launch"]["launch"]; - json["launchPath"] = filejson["launch"]["launchPath"]; - json["launchAppArgs"] = filejson["launch"]["launchAppArgs"]; - json["closeOnExit"] = filejson["launch"]["closeOnExit"]; - json["waitForChildProcs"] = filejson["launch"]["waitForChildProcs"]; - json["hideDevices"] = filejson["devices"]["hideDevices"]; - json["realDeviceIds"] = filejson["devices"]["realDeviceIds"]; - json["windowMode"] = filejson["window"]["windowMode"]; - json["maxFps"] = filejson["window"]["maxFps"]; - json["scale"] = filejson["window"]["scale"]; - json["disableOverlay"] = filejson["window"]["disableOverlay"]; - json["maxControllers"] = filejson["controller"]["maxControllers"]; - json["allowDesktopConfig"] = filejson["controller"]["allowDesktopConfig"]; - json["emulateDS4"] = filejson["controller"]["emulateDS4"]; - - json["name"] = filejson.contains("name") ? filejson["name"] : QString(name).replace(QRegularExpression("\\.json"), ""); - - targets_.append(json.toVariantMap()); + auto filejson = jsondoc.object(); + + filejson["name"] = filejson.contains("name") + ? filejson["name"].toString() + : QString(name).replace(QRegularExpression("\\.json"), ""); + + targets_.append(filejson.toVariantMap()); }); emit targetListChanged(); @@ -359,49 +343,22 @@ void UIModel::setAcrylicEffect(bool has_acrylic_affect) emit acrylicChanged(); } -void UIModel::writeTarget(const QJsonObject& json, const QString& name) +void UIModel::writeTarget(const QJsonObject& json, const QString& name) const { auto path = config_path_; path /= config_dir_name_.toStdWString(); path /= (QString(name).replace(QRegularExpression("[\\\\/:*?\"<>|]"), "") + ".json").toStdWString(); QFile file(path); if (!file.open(QIODevice::Text | QIODevice::ReadWrite)) { - // meh + qDebug() << "Couldn't open file for writing: " << path; return; } - QJsonObject fileJson; - fileJson["version"] = json["version"]; - fileJson["icon"] = json["icon"]; - fileJson["name"] = json["name"]; - - QJsonObject launchObject; - launchObject["launch"] = json["launch"]; - launchObject["launchPath"] = json["launchPath"]; - launchObject["launchAppArgs"] = json["launchAppArgs"]; - launchObject["closeOnExit"] = json["closeOnExit"]; - launchObject["waitForChildProcs"] = json["waitForChildProcs"]; - fileJson["launch"] = launchObject; - - QJsonObject devicesObject; - devicesObject["hideDevices"] = json["hideDevices"]; - devicesObject["realDeviceIds"] = json["realDeviceIds"]; - fileJson["devices"] = devicesObject; - - QJsonObject windowObject; - windowObject["windowMode"] = json["windowMode"]; - windowObject["maxFps"] = json["maxFps"]; - windowObject["scale"] = json["scale"]; - windowObject["disableOverlay"] = json["disableOverlay"]; - fileJson["window"] = windowObject; - - QJsonObject controllerObject; - controllerObject["maxControllers"] = json["maxControllers"]; - controllerObject["allowDesktopConfig"] = json["allowDesktopConfig"]; - controllerObject["emulateDS4"] = json["emulateDS4"]; - fileJson["controller"] = controllerObject; - - auto wtf = QString(QJsonDocument(fileJson).toJson(QJsonDocument::Indented)).toStdString(); - file.write(wtf.data()); + + file.write( + QString(QJsonDocument(json).toJson(QJsonDocument::Indented)) + .toStdString() + .data() + ); file.close(); } diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h index 38b6007..4ec241a 100644 --- a/GlosSIConfig/UIModel.h +++ b/GlosSIConfig/UIModel.h @@ -33,7 +33,7 @@ class UIModel : public QObject { public: UIModel(); - Q_INVOKABLE void readConfigs(); + Q_INVOKABLE void readTargetConfigs(); Q_INVOKABLE QVariantList getTargetList() const; Q_INVOKABLE void addTarget(QVariant shortcut); Q_INVOKABLE void updateTarget(int index, QVariant shortcut); @@ -64,17 +64,15 @@ class UIModel : public QObject { void targetListChanged(); private: +#ifdef _WIN32 + bool is_windows_ = true; +#else + bool is_windows_ = false; +#endif + bool has_acrylic_affect_ = false; + std::filesystem::path config_path_; QString config_dir_name_; - - void writeTarget(const QJsonObject& json, const QString& name); - - std::filesystem::path getSteamPath() const; - std::wstring getSteamUserId() const; - bool foundSteam() const; - void parseShortcutVDF(); - - bool isSteamInputXboxSupportEnabled() const; QString shortcutsfile_ = "/config/shortcuts.vdf"; QString user_config_file_ = "/config/localconfig.vdf"; @@ -83,11 +81,13 @@ class UIModel : public QObject { QVariantList targets_; std::vector shortcuts_vdf_; + + void writeTarget(const QJsonObject& json, const QString& name) const; -#ifdef _WIN32 - bool is_windows_ = true; -#else - bool is_windows_ = false; -#endif - bool has_acrylic_affect_ = false; + std::filesystem::path getSteamPath() const; + std::wstring getSteamUserId() const; + bool foundSteam() const; + void parseShortcutVDF(); + + bool isSteamInputXboxSupportEnabled() const; }; diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index 889bc99..e6f0029 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -29,62 +29,58 @@ Item { signal cancel() signal done(var shortcut) - property var shortcutInfo: ({ - version: 1, - name: null, - launch: false, - launchPath: null, - launchAppArgs: null, - closeOnExit: true, - waitForChildProcs: true, - hideDevices: true, - windowMode: false, - maxFps: null, - scale: null, - icon: null, - maxControllers: 1, - disableOverlay: false, - realDeviceIds: false, - allowDesktopConfig: false, - emulateDS4: false, - }) + property var shortcutInfo: ({}) function resetInfo() { shortcutInfo = ({ - version: 1, - name: null, - launch: false, - launchPath: null, - launchAppArgs: null, - closeOnExit: true, - waitForChildProcs: true, - hideDevices: true, - windowMode: false, - maxFps: null, - scale: null, - icon: null, - maxControllers: 1, - disableOverlay: false, - realDeviceIds: false, - allowDesktopConfig: false, - emulateDS4: false, + "controller": { + "maxControllers": 1, + "emulateDS4": false, + "allowDesktopConfig": false + }, + "devices": { + "hideDevices": true, + "realDeviceIds": false + }, + "icon": null, + "launch": { + "closeOnExit": true, + "launch": false, + "launchAppArgs": null, + "launchPath": null, + "waitForChildProcs": true + }, + "name": null, + "version": 1, + "window": { + "disableOverlay": false, + "maxFps": null, + "scale": null, + "windowMode": false + }, + "extendedLogging": false }) } + + Component.onCompleted: function() { + resetInfo() + } onShortcutInfoChanged: function() { nameInput.text = shortcutInfo.name || "" - launchApp.checked = shortcutInfo.launch || false - pathInput.text = shortcutInfo.launchPath || "" - argsInput.text = shortcutInfo.launchAppArgs || "" - closeOnExit.checked = shortcutInfo.closeOnExit || false - waitForChildren.checked = shortcutInfo.waitForChildProcs - hideDevices.checked = shortcutInfo.hideDevices || false - windowMode.checked = shortcutInfo.windowMode || false - maxControllersSpinBox.value = shortcutInfo.maxControllers - disableOverlayCheckbox.checked = shortcutInfo.disableOverlay || false - realDeviceIds.checked = shortcutInfo.realDeviceIds || false - allowDesktopConfig.checked = shortcutInfo.allowDesktopConfig || false - emulateDS4.checked = shortcutInfo.emulateDS4 || false + extendedLogging.checked = shortcutInfo.extendedLogging + launchApp.checked = shortcutInfo.launch.launch + pathInput.text = shortcutInfo.launch.launchPath || "" + argsInput.text = shortcutInfo.launch.launchAppArgs || "" + closeOnExit.checked = shortcutInfo.launch.closeOnExit + waitForChildren.checked = shortcutInfo.launch.waitForChildProcs + hideDevices.checked = shortcutInfo.devices.hideDevices + realDeviceIds.checked = shortcutInfo.devices.realDeviceIds + windowMode.checked = shortcutInfo.window.windowMode + disableOverlayCheckbox.checked = shortcutInfo.window.disableOverlay + maxControllersSpinBox.value = shortcutInfo.controller.maxControllers + allowDesktopConfig.checked = shortcutInfo.controller.allowDesktopConfig + emulateDS4.checked = shortcutInfo.controller.emulateDS4 } Flickable { @@ -159,9 +155,9 @@ Item { CheckBox { id: launchApp text: qsTr("Launch app") - checked: shortcutInfo.launch + checked: shortcutInfo.launch.launch onCheckedChanged: function() { - shortcutInfo.launch = checked + shortcutInfo.launch.launch = checked if (checked) { closeOnExit.enabled = true; if (closeOnExit.checked) { @@ -181,9 +177,9 @@ Item { CheckBox { id: closeOnExit text: qsTr("Close when launched app quits") - checked: shortcutInfo.closeOnExit + checked: shortcutInfo.launch.closeOnExit onCheckedChanged: function() { - shortcutInfo.closeOnExit = checked + shortcutInfo.launch.closeOnExit = checked if (checked) { waitForChildren.enabled = true; } else { @@ -201,9 +197,9 @@ Item { CheckBox { id: waitForChildren text: qsTr("Wait for child processes") - checked: shortcutInfo.waitForChildProcs + checked: shortcutInfo.launch.waitForChildProcs onCheckedChanged: function(){ - shortcutInfo.waitForChildProcs = checked + shortcutInfo.launch.waitForChildProcs = checked } } } @@ -212,9 +208,9 @@ Item { CheckBox { id: allowDesktopConfig text: qsTr("Allow desktop-config") - checked: shortcutInfo.allowDesktopConfig + checked: shortcutInfo.controller.allowDesktopConfig onCheckedChanged: function(){ - shortcutInfo.allowDesktopConfig = checked + shortcutInfo.controller.allowDesktopConfig = checked } } Label { @@ -238,7 +234,7 @@ Item { ? shortcutInfo.icon.endsWith(".exe") ? "image://exe/" + shortcutInfo.icon : "file:///" + shortcutInfo.icon - : null + : '' Layout.preferredWidth: 48 Layout.preferredHeight: 48 visible: shortcutInfo.icon @@ -267,8 +263,8 @@ Item { id: pathInput placeholderText: qsTr("...") enabled: launchApp.checked - text: shortcutInfo.launchPath || "" - onTextChanged: shortcutInfo.launchPath = text + text: shortcutInfo.launch.launchPath || "" + onTextChanged: shortcutInfo.launch.launchPath = text } } Button { @@ -304,8 +300,8 @@ Item { anchors.topMargin: 4 id: argsInput enabled: launchApp.checked - text: shortcutInfo.launchAppArgs - onTextChanged: shortcutInfo.launchAppArgs = text + text: shortcutInfo.launch.launchAppArgs + onTextChanged: shortcutInfo.launch.launchAppArgs = text } } } @@ -333,8 +329,8 @@ Item { CheckBox { id: hideDevices text: qsTr("Hide (Real) Controllers") - checked: shortcutInfo.hideDevices - onCheckedChanged: shortcutInfo.hideDevices = checked + checked: shortcutInfo.devices.hideDevices + onCheckedChanged: shortcutInfo.devices.hideDevices = checked } RoundButton { onClicked: () => { @@ -366,8 +362,8 @@ Item { CheckBox { id: realDeviceIds text: qsTr("Use real device (USB)-IDs") - checked: shortcutInfo.realDeviceIds - onCheckedChanged: shortcutInfo.realDeviceIds = checked + checked: shortcutInfo.devices.realDeviceIds + onCheckedChanged: shortcutInfo.devices.realDeviceIds = checked } RoundButton { onClicked: () => { @@ -399,8 +395,8 @@ Item { CheckBox { id: emulateDS4 text: qsTr("Emulate DS4") - checked: shortcutInfo.emulateDS4 - onCheckedChanged: shortcutInfo.emulateDS4 = checked + checked: shortcutInfo.controller.emulateDS4 || false + onCheckedChanged: shortcutInfo.controller.emulateDS4 = checked } RoundButton { onClicked: () => { @@ -438,10 +434,10 @@ Item { SpinBox { id: maxControllersSpinBox width: 128 - value: 4 + value: shortcutInfo.controller.maxControllers from: 0 to: 4 - onValueChanged: shortcutInfo.maxControllers = value + onValueChanged: shortcutInfo.controller.maxControllers = value } RoundButton { onClicked: () => { @@ -479,8 +475,8 @@ Item { CheckBox { id: windowMode text: qsTr("Steam/GlosSI overlay as separate window") - checked: shortcutInfo.windowMode - onCheckedChanged: shortcutInfo.windowMode = checked + checked: shortcutInfo.window.windowMode + onCheckedChanged: shortcutInfo.window.windowMode = checked } RoundButton { onClicked: () => { @@ -513,8 +509,8 @@ Item { CheckBox { id: disableOverlayCheckbox text: qsTr("Disable Steam/GlosSI overlay") - checked: shortcutInfo.disableOverlay - onCheckedChanged: shortcutInfo.disableOverlay = checked + checked: shortcutInfo.window.disableOverlay + onCheckedChanged: shortcutInfo.window.disableOverlay = checked } RoundButton { onClicked: () => { From 00e9bbe48517e9073a6376b1f4bec69215164892 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 13:42:44 +0200 Subject: [PATCH 23/35] GlosSIConfig: Move settings to collapsible card --- GlosSIConfig/GlosSIConfig.vcxproj | 1 + GlosSIConfig/GlosSIConfig.vcxproj.filters | 3 + GlosSIConfig/Resource.rc | 228 ++++++++++- GlosSIConfig/qml.qrc | 2 + GlosSIConfig/qml/CollapsiblePane.qml | 96 +++++ GlosSIConfig/qml/ShortcutProps.qml | 399 ++++++++++---------- GlosSIConfig/svg/expand_more_white_24dp.svg | 1 + 7 files changed, 531 insertions(+), 199 deletions(-) create mode 100644 GlosSIConfig/qml/CollapsiblePane.qml create mode 100644 GlosSIConfig/svg/expand_more_white_24dp.svg diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj index 816dbf2..025235d 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj +++ b/GlosSIConfig/GlosSIConfig.vcxproj @@ -137,6 +137,7 @@ + diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters index 757008d..4b2ed94 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj.filters +++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters @@ -71,6 +71,9 @@ qml + + qml + diff --git a/GlosSIConfig/Resource.rc b/GlosSIConfig/Resource.rc index 0c465db..315c1a0 100644 --- a/GlosSIConfig/Resource.rc +++ b/GlosSIConfig/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,8,105004039005 - PRODUCTVERSION 0,0,8,105004039005 + FILEVERSION 0,0,8,1023005406006 + PRODUCTVERSION 0,0,8,1023005406006 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - Config" - VALUE "FileVersion", "0.0.8.1-5-g40390b5" + VALUE "FileVersion", "0.0.8.1-23-g54e6bf6" VALUE "InternalName", "GlosSIConfig" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.8.1-5-g40390b5" + VALUE "ProductVersion", "0.0.8.1-23-g54e6bf6" END END BLOCK "VarFileInfo" @@ -872,6 +872,226 @@ IDI_ICON1 ICON "..\GloSC_Icon.ico" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc index b626964..b273ad9 100644 --- a/GlosSIConfig/qml.qrc +++ b/GlosSIConfig/qml.qrc @@ -17,5 +17,7 @@ svg/help_outline_white_24dp.svg qml/SteamNotFoundDialog.qml qml/SteamInputXboxDisabledDialog.qml + qml/CollapsiblePane.qml + svg/expand_more_white_24dp.svg diff --git a/GlosSIConfig/qml/CollapsiblePane.qml b/GlosSIConfig/qml/CollapsiblePane.qml new file mode 100644 index 0000000..c5273e4 --- /dev/null +++ b/GlosSIConfig/qml/CollapsiblePane.qml @@ -0,0 +1,96 @@ +/* +Copyright 2021-2022 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import QtQuick 2.9 +import QtQuick.Controls 2.9 +import QtQuick.Controls.Material 2.9 +import QtQuick.Controls.Material.impl 2.9 + + +RPane { + property alias title: paneTitle.text + width: parent.width + + property alias content: ldr.sourceComponent + clip: true + height: paneTitle.height + collapseColumn.spacing + property bool collapsed: true + id: collapsePane + + Behavior on height { + NumberAnimation { + duration: 300 + easing.type: Easing.InOutQuad + } + } + + Column { + id: collapseColumn + width: parent.width + spacing: 16 + Item { + width: parent.width + height: paneTitle.height + Label { + id: paneTitle + anchors.left: parent.left + anchors.leftMargin: 4 + font.bold: true + font.pixelSize: 24 + anchors.top: parent.top + anchors.topMargin: -2 + } + RoundButton { + width: 48 + height: 48 + Material.elevation: 0 + anchors.rightMargin: 0 + anchors.top: parent.top + anchors.topMargin: -12 + onClicked: function(){ + collapsed = !collapsed; + if (collapsed) { + collapsePane.height = paneTitle.height + collapseColumn.spacing + } else { + collapsePane.height = paneTitle.height + collapseColumn.spacing * 3 + ldr.item.height + } + } + Image { + id: arrowImg + anchors.centerIn: parent + source: "qrc:/svg/expand_more_white_24dp.svg" + width: 24 + height: 24 + transform: Rotation{ + angle: collapsed ? 0 : 180 + origin.x: arrowImg.width/2 + origin.y: arrowImg.height/2 + Behavior on angle { + NumberAnimation { + duration: 125 + easing.type: Easing.InOutQuad + } + } + } + } + anchors.right: parent.right + } + } + Loader { + id: ldr + width: parent.width + } + } +} diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index e6f0029..d787be0 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -311,232 +311,241 @@ Item { width: 1 height: 8 } - Row { - spacing: 16 - width: parent.width - RPane { - width: parent.width / 2 - 8 - height: 264 - radius: 4 - Material.elevation: 32 - bgOpacity: 0.97 + CollapsiblePane { + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + title: qsTr("Advanced") + content: Row { + spacing: 16 + width: parent.width - Column { - spacing: 2 - width: parent.width - Row { - CheckBox { - id: hideDevices - text: qsTr("Hide (Real) Controllers") - checked: shortcutInfo.devices.hideDevices - onCheckedChanged: shortcutInfo.devices.hideDevices = checked - } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Hide (Real) Controllers") - helpInfoDialog.text = - qsTr("Hides real game controllers from the system\nThis may prevent doubled inputs") - + "\n" - + qsTr("You can change this setting and which devices are hidden in the GlosSI overlay") - - helpInfoDialog.open() + RPane { + width: parent.width / 2 - 8 + height: 264 + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + + Column { + spacing: 2 + width: parent.width + Row { + CheckBox { + id: hideDevices + text: qsTr("Hide (Real) Controllers") + checked: shortcutInfo.devices.hideDevices + onCheckedChanged: shortcutInfo.devices.hideDevices = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Hide (Real) Controllers") + helpInfoDialog.text = + qsTr("Hides real game controllers from the system\nThis may prevent doubled inputs") + + "\n" + + qsTr("You can change this setting and which devices are hidden in the GlosSI overlay") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - Row { - CheckBox { - id: realDeviceIds - text: qsTr("Use real device (USB)-IDs") - checked: shortcutInfo.devices.realDeviceIds - onCheckedChanged: shortcutInfo.devices.realDeviceIds = checked + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Use real device (USB)-IDs") - helpInfoDialog.text = - qsTr("Only enable if input's are not recognized by the game") - + "\n" - + qsTr("If enabled, device-hiding won't work.\nUse the \"Max. Controller count\" setting!") - - helpInfoDialog.open() + Row { + CheckBox { + id: realDeviceIds + text: qsTr("Use real device (USB)-IDs") + checked: shortcutInfo.devices.realDeviceIds + onCheckedChanged: shortcutInfo.devices.realDeviceIds = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Use real device (USB)-IDs") + helpInfoDialog.text = + qsTr("Only enable if input's are not recognized by the game") + + "\n" + + qsTr("If enabled, device-hiding won't work.\nUse the \"Max. Controller count\" setting!") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - Row { - CheckBox { - id: emulateDS4 - text: qsTr("Emulate DS4") - checked: shortcutInfo.controller.emulateDS4 || false - onCheckedChanged: shortcutInfo.controller.emulateDS4 = checked + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Emulate DS4") - helpInfoDialog.text = - qsTr("Emulates a DS4 instead of X360 Pad") - + "\n" - qsTr("for usage with, for example, PSNow") - + "\n" - + qsTr("If enabled you have to disable \"Playstation Configuration support\" in Steam") - helpInfoDialog.open() + Row { + CheckBox { + id: emulateDS4 + text: qsTr("Emulate DS4") + checked: shortcutInfo.controller.emulateDS4 || false + onCheckedChanged: shortcutInfo.controller.emulateDS4 = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Emulate DS4") + helpInfoDialog.text = + qsTr("Emulates a DS4 instead of X360 Pad") + + "\n" + qsTr("for usage with, for example, PSNow") + + "\n" + + qsTr("If enabled you have to disable \"Playstation Configuration support\" in Steam") + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - Row { - leftPadding: 16 - Label { - text: qsTr("Max. emulated controllers") - topPadding: 16 - } - SpinBox { - id: maxControllersSpinBox - width: 128 - value: shortcutInfo.controller.maxControllers - from: 0 - to: 4 - onValueChanged: shortcutInfo.controller.maxControllers = value + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Max. emulated controllers") - helpInfoDialog.text = - qsTr("GlosSI will only provide [NUMBER] of controllers") - + "\n" - + qsTr("Required to set to actually connected controller count when using \"real devuce IDs\" ") - helpInfoDialog.open() + Row { + leftPadding: 16 + Label { + text: qsTr("Max. emulated controllers") + topPadding: 16 } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + SpinBox { + id: maxControllersSpinBox + width: 128 + value: shortcutInfo.controller.maxControllers + from: 0 + to: 4 + onValueChanged: shortcutInfo.controller.maxControllers = value + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Max. emulated controllers") + helpInfoDialog.text = + qsTr("GlosSI will only provide [NUMBER] of controllers") + + "\n" + + qsTr("Required to set to actually connected controller count when using \"real devuce IDs\" ") + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } } } - } - RPane { - width: parent.width / 2 - 8 - height: 264 - radius: 4 - Material.elevation: 32 - bgOpacity: 0.97 - Column { - spacing: 2 - width: parent.width - Row { - CheckBox { - id: windowMode - text: qsTr("Steam/GlosSI overlay as separate window") - checked: shortcutInfo.window.windowMode - onCheckedChanged: shortcutInfo.window.windowMode = checked - } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Steam/GlosSI overlay as separate window") - helpInfoDialog.text = - qsTr("Doesn't show overlay on top, but as separate window") - + "\n" - + qsTr("Use if blackscreen-issues are encountered.") - - helpInfoDialog.open() + RPane { + width: parent.width / 2 - 8 + height: 264 + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + Column { + spacing: 2 + width: parent.width + Row { + CheckBox { + id: windowMode + text: qsTr("Steam/GlosSI overlay as separate window") + checked: shortcutInfo.window.windowMode + onCheckedChanged: shortcutInfo.window.windowMode = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Steam/GlosSI overlay as separate window") + helpInfoDialog.text = + qsTr("Doesn't show overlay on top, but as separate window") + + "\n" + + qsTr("Use if blackscreen-issues are encountered.") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - - Row { - CheckBox { - id: disableOverlayCheckbox - text: qsTr("Disable Steam/GlosSI overlay") - checked: shortcutInfo.window.disableOverlay - onCheckedChanged: shortcutInfo.window.disableOverlay = checked + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Disable Steam/GlosSI overlay") - helpInfoDialog.text = - qsTr("Only controller emulation - No extra window") - + "\n" - + qsTr("Might help with Steam remote play.") - helpInfoDialog.open() + Row { + CheckBox { + id: disableOverlayCheckbox + text: qsTr("Disable Steam/GlosSI overlay") + checked: shortcutInfo.window.disableOverlay + onCheckedChanged: shortcutInfo.window.disableOverlay = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Disable Steam/GlosSI overlay") + helpInfoDialog.text = + qsTr("Only controller emulation - No extra window") + + "\n" + + qsTr("Might help with Steam remote play.") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } } } } + } + Item { id: bottomspacing width: 1 diff --git a/GlosSIConfig/svg/expand_more_white_24dp.svg b/GlosSIConfig/svg/expand_more_white_24dp.svg new file mode 100644 index 0000000..9c420ca --- /dev/null +++ b/GlosSIConfig/svg/expand_more_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file From 14796604d191563e6f133c15939064802d27661c Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 15:29:39 +0200 Subject: [PATCH 24/35] GlosSIConfig: declutter UI --- GlosSIConfig/qml/CollapsiblePane.qml | 13 +- GlosSIConfig/qml/ShortcutProps.qml | 502 ++++++++++++++------------- 2 files changed, 270 insertions(+), 245 deletions(-) diff --git a/GlosSIConfig/qml/CollapsiblePane.qml b/GlosSIConfig/qml/CollapsiblePane.qml index c5273e4..6dea9e0 100644 --- a/GlosSIConfig/qml/CollapsiblePane.qml +++ b/GlosSIConfig/qml/CollapsiblePane.qml @@ -25,7 +25,7 @@ RPane { property alias content: ldr.sourceComponent clip: true - height: paneTitle.height + collapseColumn.spacing + height: paneHeader.height + collapseColumn.spacing property bool collapsed: true id: collapsePane @@ -41,8 +41,9 @@ RPane { width: parent.width spacing: 16 Item { + id: paneHeader width: parent.width - height: paneTitle.height + height: paneTitle.height + 32 Label { id: paneTitle anchors.left: parent.left @@ -50,7 +51,7 @@ RPane { font.bold: true font.pixelSize: 24 anchors.top: parent.top - anchors.topMargin: -2 + anchors.topMargin: 14 } RoundButton { width: 48 @@ -58,13 +59,13 @@ RPane { Material.elevation: 0 anchors.rightMargin: 0 anchors.top: parent.top - anchors.topMargin: -12 + anchors.topMargin: 0 onClicked: function(){ collapsed = !collapsed; if (collapsed) { - collapsePane.height = paneTitle.height + collapseColumn.spacing + collapsePane.height = paneHeader.height + collapseColumn.spacing } else { - collapsePane.height = paneTitle.height + collapseColumn.spacing * 3 + ldr.item.height + collapsePane.height = paneHeader.height + collapseColumn.spacing * 3 + ldr.item.height } } Image { diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index d787be0..7b500da 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -140,7 +140,6 @@ Item { } RPane { width: parent.width - height: 248 radius: 4 Material.elevation: 32 bgOpacity: 0.97 @@ -151,7 +150,6 @@ Item { Row { spacing: 32 width: parent.width - height: closeOnExitCol.height CheckBox { id: launchApp text: qsTr("Launch app") @@ -171,54 +169,6 @@ Item { } } } - Column { - id: closeOnExitCol - spacing: 2 - CheckBox { - id: closeOnExit - text: qsTr("Close when launched app quits") - checked: shortcutInfo.launch.closeOnExit - onCheckedChanged: function() { - shortcutInfo.launch.closeOnExit = checked - if (checked) { - waitForChildren.enabled = true; - } else { - waitForChildren.enabled = false; - } - } - } - Label { - text: qsTr("Recommended to disable for launcher-games") - wrapMode: Text.WordWrap - width: parent.width - leftPadding: 32 - topPadding: -8 - } - CheckBox { - id: waitForChildren - text: qsTr("Wait for child processes") - checked: shortcutInfo.launch.waitForChildProcs - onCheckedChanged: function(){ - shortcutInfo.launch.waitForChildProcs = checked - } - } - } - Column { - spacing: 2 - CheckBox { - id: allowDesktopConfig - text: qsTr("Allow desktop-config") - checked: shortcutInfo.controller.allowDesktopConfig - onCheckedChanged: function(){ - shortcutInfo.controller.allowDesktopConfig = checked - } - } - Label { - text: qsTr("Use desktop-config if launched application is not focused") - leftPadding: 32 - topPadding: -8 - } - } } Item { width: 1 @@ -227,7 +177,10 @@ Item { RowLayout { id: launchlayout spacing: 4 - width: parent.width + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 32 + anchors.rightMargin: 32 Image { id: maybeIcon source: shortcutInfo.icon @@ -317,233 +270,304 @@ Item { Material.elevation: 32 bgOpacity: 0.97 title: qsTr("Advanced") - content: Row { + content: + Column { spacing: 16 - width: parent.width RPane { - width: parent.width / 2 - 8 - height: 264 + width: parent.width radius: 4 Material.elevation: 32 bgOpacity: 0.97 - + height: advancedLaunchCol.height + 24 Column { - spacing: 2 - width: parent.width + id: advancedLaunchCol + spacing: 4 + height: advancedLaunchedRow.height Row { - CheckBox { - id: hideDevices - text: qsTr("Hide (Real) Controllers") - checked: shortcutInfo.devices.hideDevices - onCheckedChanged: shortcutInfo.devices.hideDevices = checked + id: advancedLaunchedRow + spacing: 32 + width: parent.width + height: closeOnExitCol.height + Column { + id: closeOnExitCol + spacing: 2 + CheckBox { + id: closeOnExit + text: qsTr("Close when launched app quits") + checked: shortcutInfo.launch.closeOnExit + onCheckedChanged: function() { + shortcutInfo.launch.closeOnExit = checked + if (checked) { + waitForChildren.enabled = true; + } else { + waitForChildren.enabled = false; + } + } + } + Label { + text: qsTr("Recommended to disable for launcher-games") + wrapMode: Text.WordWrap + width: parent.width + leftPadding: 32 + topPadding: -8 + } + CheckBox { + id: waitForChildren + text: qsTr("Wait for child processes") + checked: shortcutInfo.launch.waitForChildProcs + onCheckedChanged: function(){ + shortcutInfo.launch.waitForChildProcs = checked + } + } } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Hide (Real) Controllers") - helpInfoDialog.text = - qsTr("Hides real game controllers from the system\nThis may prevent doubled inputs") - + "\n" - + qsTr("You can change this setting and which devices are hidden in the GlosSI overlay") - - helpInfoDialog.open() + Column { + spacing: 2 + CheckBox { + id: allowDesktopConfig + text: qsTr("Allow desktop-config") + checked: shortcutInfo.controller.allowDesktopConfig + onCheckedChanged: function(){ + shortcutInfo.controller.allowDesktopConfig = checked + } } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + Label { + text: qsTr("Use desktop-config if launched application is not focused") + leftPadding: 32 + topPadding: -8 } } } - Item { - width: 1 - height: 4 - } - Row { - CheckBox { - id: realDeviceIds - text: qsTr("Use real device (USB)-IDs") - checked: shortcutInfo.devices.realDeviceIds - onCheckedChanged: shortcutInfo.devices.realDeviceIds = checked - } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Use real device (USB)-IDs") - helpInfoDialog.text = - qsTr("Only enable if input's are not recognized by the game") - + "\n" - + qsTr("If enabled, device-hiding won't work.\nUse the \"Max. Controller count\" setting!") - - helpInfoDialog.open() + } + } + + Row { + spacing: 16 + width: parent.width + + RPane { + width: parent.width / 2 - 8 + height: 264 + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + + Column { + spacing: 2 + width: parent.width + Row { + CheckBox { + id: hideDevices + text: qsTr("Hide (Real) Controllers") + checked: shortcutInfo.devices.hideDevices + onCheckedChanged: shortcutInfo.devices.hideDevices = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Hide (Real) Controllers") + helpInfoDialog.text = + qsTr("Hides real game controllers from the system\nThis may prevent doubled inputs") + + "\n" + + qsTr("You can change this setting and which devices are hidden in the GlosSI overlay") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - Row { - CheckBox { - id: emulateDS4 - text: qsTr("Emulate DS4") - checked: shortcutInfo.controller.emulateDS4 || false - onCheckedChanged: shortcutInfo.controller.emulateDS4 = checked + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Emulate DS4") - helpInfoDialog.text = - qsTr("Emulates a DS4 instead of X360 Pad") - + "\n" - qsTr("for usage with, for example, PSNow") - + "\n" - + qsTr("If enabled you have to disable \"Playstation Configuration support\" in Steam") - helpInfoDialog.open() + Row { + CheckBox { + id: realDeviceIds + text: qsTr("Use real device (USB)-IDs") + checked: shortcutInfo.devices.realDeviceIds + onCheckedChanged: shortcutInfo.devices.realDeviceIds = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Use real device (USB)-IDs") + helpInfoDialog.text = + qsTr("Only enable if input's are not recognized by the game") + + "\n" + + qsTr("If enabled, device-hiding won't work.\nUse the \"Max. Controller count\" setting!") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - Item { - width: 1 - height: 4 - } - Row { - leftPadding: 16 - Label { - text: qsTr("Max. emulated controllers") - topPadding: 16 - } - SpinBox { - id: maxControllersSpinBox - width: 128 - value: shortcutInfo.controller.maxControllers - from: 0 - to: 4 - onValueChanged: shortcutInfo.controller.maxControllers = value + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Max. emulated controllers") - helpInfoDialog.text = - qsTr("GlosSI will only provide [NUMBER] of controllers") - + "\n" - + qsTr("Required to set to actually connected controller count when using \"real devuce IDs\" ") - helpInfoDialog.open() + Row { + CheckBox { + id: emulateDS4 + text: qsTr("Emulate DS4") + checked: shortcutInfo.controller.emulateDS4 || false + onCheckedChanged: shortcutInfo.controller.emulateDS4 = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Emulate DS4") + helpInfoDialog.text = + qsTr("Emulates a DS4 instead of X360 Pad") + + "\n" + qsTr("for usage with, for example, PSNow") + + "\n" + + qsTr("If enabled you have to disable \"Playstation Configuration support\" in Steam") + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } - } - } - } - RPane { - width: parent.width / 2 - 8 - height: 264 - radius: 4 - Material.elevation: 32 - bgOpacity: 0.97 - Column { - spacing: 2 - width: parent.width - Row { - CheckBox { - id: windowMode - text: qsTr("Steam/GlosSI overlay as separate window") - checked: shortcutInfo.window.windowMode - onCheckedChanged: shortcutInfo.window.windowMode = checked + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Steam/GlosSI overlay as separate window") - helpInfoDialog.text = - qsTr("Doesn't show overlay on top, but as separate window") - + "\n" - + qsTr("Use if blackscreen-issues are encountered.") - - helpInfoDialog.open() + Row { + leftPadding: 16 + Label { + text: qsTr("Max. emulated controllers") + topPadding: 16 } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + SpinBox { + id: maxControllersSpinBox + width: 128 + value: shortcutInfo.controller.maxControllers + from: 0 + to: 4 + onValueChanged: shortcutInfo.controller.maxControllers = value + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Max. emulated controllers") + helpInfoDialog.text = + qsTr("GlosSI will only provide [NUMBER] of controllers") + + "\n" + + qsTr("Required to set to actually connected controller count when using \"real device IDs\" ") + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } } - Item { - width: 1 - height: 4 - } + } + RPane { + width: parent.width / 2 - 8 + height: 264 + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + Column { + spacing: 2 + width: parent.width + Row { + CheckBox { + id: windowMode + text: qsTr("Steam/GlosSI overlay as separate window") + checked: shortcutInfo.window.windowMode + onCheckedChanged: shortcutInfo.window.windowMode = checked + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Steam/GlosSI overlay as separate window") + helpInfoDialog.text = + qsTr("Doesn't show overlay on top, but as separate window") + + "\n" + + qsTr("Use if blackscreen-issues are encountered.") - Row { - CheckBox { - id: disableOverlayCheckbox - text: qsTr("Disable Steam/GlosSI overlay") - checked: shortcutInfo.window.disableOverlay - onCheckedChanged: shortcutInfo.window.disableOverlay = checked + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } + } + Item { + width: 1 + height: 4 } - RoundButton { - onClicked: () => { - helpInfoDialog.titleText = qsTr("Disable Steam/GlosSI overlay") - helpInfoDialog.text = - qsTr("Only controller emulation - No extra window") - + "\n" - + qsTr("Might help with Steam remote play.") - helpInfoDialog.open() + Row { + CheckBox { + id: disableOverlayCheckbox + text: qsTr("Disable Steam/GlosSI overlay") + checked: shortcutInfo.window.disableOverlay + onCheckedChanged: shortcutInfo.window.disableOverlay = checked } - width: 48 - height: 48 - Material.elevation: 0 - anchors.topMargin: 16 - Image { - anchors.centerIn: parent - source: "qrc:/svg/help_outline_white_24dp.svg" - width: 24 - height: 24 + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Disable Steam/GlosSI overlay") + helpInfoDialog.text = + qsTr("Only controller emulation - No extra window") + + "\n" + + qsTr("Might help with Steam remote play.") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } } } } } } } - } Item { From 93667c91cf8b69d3207af1930496349326378200 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 16:09:24 +0200 Subject: [PATCH 25/35] GlosSIConfig add missing config values --- GlosSIConfig/qml/ShortcutProps.qml | 179 +++++++++++++++++++++++++++-- 1 file changed, 170 insertions(+), 9 deletions(-) diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index 7b500da..8d2a7da 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -68,7 +68,9 @@ Item { onShortcutInfoChanged: function() { nameInput.text = shortcutInfo.name || "" - extendedLogging.checked = shortcutInfo.extendedLogging + if (extendedLogging) { + extendedLogging.checked = shortcutInfo.extendedLogging || false + } launchApp.checked = shortcutInfo.launch.launch pathInput.text = shortcutInfo.launch.launchPath || "" argsInput.text = shortcutInfo.launch.launchAppArgs || "" @@ -78,6 +80,8 @@ Item { realDeviceIds.checked = shortcutInfo.devices.realDeviceIds windowMode.checked = shortcutInfo.window.windowMode disableOverlayCheckbox.checked = shortcutInfo.window.disableOverlay + scaleSpinBox.value = shortcutInfo.window.scale + maxFPSSpinBox.value = shortcutInfo.window.maxFps maxControllersSpinBox.value = shortcutInfo.controller.maxControllers allowDesktopConfig.checked = shortcutInfo.controller.allowDesktopConfig emulateDS4.checked = shortcutInfo.controller.emulateDS4 @@ -157,9 +161,11 @@ Item { onCheckedChanged: function() { shortcutInfo.launch.launch = checked if (checked) { - closeOnExit.enabled = true; - if (closeOnExit.checked) { - waitForChildren.enabled = true; + if (closeOnExit) { + closeOnExit.enabled = true; + if (closeOnExit.checked) { + waitForChildren.enabled = true; + } } allowDesktopConfig.enabled = true; } else { @@ -332,7 +338,7 @@ Item { } } Label { - text: qsTr("Use desktop-config if launched application is not focused") + text: qsTr("Allow desktop-config if launched application is not focused") leftPadding: 32 topPadding: -8 } @@ -347,13 +353,13 @@ Item { RPane { width: parent.width / 2 - 8 - height: 264 + height: 248 radius: 4 Material.elevation: 32 bgOpacity: 0.97 Column { - spacing: 2 + spacing: 0 width: parent.width Row { CheckBox { @@ -464,6 +470,7 @@ Item { SpinBox { id: maxControllersSpinBox width: 128 + editable: true value: shortcutInfo.controller.maxControllers from: 0 to: 4 @@ -494,12 +501,12 @@ Item { } RPane { width: parent.width / 2 - 8 - height: 264 + height: 248 radius: 4 Material.elevation: 32 bgOpacity: 0.97 Column { - spacing: 2 + spacing: 0 width: parent.width Row { CheckBox { @@ -564,6 +571,160 @@ Item { } } } + Item { + width: 1 + height: 4 + } + Row { + leftPadding: 16 + Label { + text: qsTr("GlosSI-Overlay scale") + topPadding: 16 + } + SpinBox { + id: scaleSpinBox + width: 172 + from: -100 + value: shortcutInfo.window.scale * 100 || 0 + to: 350 + stepSize: 10 + editable: true + + property int decimals: 2 + property real realValue: value / 100 + + validator: DoubleValidator { + bottom: Math.min(scaleSpinBox.from, scaleSpinBox.to) + top: Math.max(scaleSpinBox.from, scaleSpinBox.to) + } + + textFromValue: function(value, locale) { + return Number(value / 100).toLocaleString(locale, 'f', scaleSpinBox.decimals) + } + + valueFromText: function(text, locale) { + return Number.fromLocaleString(locale, text) * 100 + } + onValueChanged: function() { + if (value <= 0) { + shortcutInfo.window.scale = null + return + } + shortcutInfo.window.scale = value / 100 + } + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("GloSI-Overlay scaling") + helpInfoDialog.text = + qsTr("Scales the elements of the GlosSI-Overlay (not Steam Overlay)") + + "\n" + + qsTr(" <= 0.0 to use auto-detection") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } + } + Item { + width: 1 + height: 4 + } + Row { + leftPadding: 16 + Label { + text: qsTr("Max. Overlay FPS") + topPadding: 16 + } + SpinBox { + id: maxFPSSpinBox + width: 172 + from: -1 + value: shortcutInfo.window.maxFps || 0 + to: 244 + stepSize: 5 + editable: true + + onValueChanged: function() { + if (value <= 0) { + shortcutInfo.window.maxFps = null + return + } + shortcutInfo.window.maxFps = value + } + } + RoundButton { + onClicked: () => { + helpInfoDialog.titleText = qsTr("Max. Overlay FPS") + helpInfoDialog.text = + qsTr("Restricts the FPS of the overlay to the given value") + + "\n" + + qsTr(" <= 0.0 to use screen refresh rate") + + helpInfoDialog.open() + } + width: 48 + height: 48 + Material.elevation: 0 + anchors.topMargin: 16 + Image { + anchors.centerIn: parent + source: "qrc:/svg/help_outline_white_24dp.svg" + width: 24 + height: 24 + } + } + } + } + } + } + + RPane { + width: parent.width + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + Column { + spacing: 4 + Row { + Row { + CheckBox { + id: extendedLogging + text: qsTr("Extended Logging") + checked: shortcutInfo.extendedLogging + onCheckedChanged: shortcutInfo.extendedLogging = checked + } + // RoundButton { + // onClicked: () => { + // helpInfoDialog.titleText = qsTr("Hide (Real) Controllers") + // helpInfoDialog.text = + // qsTr("Hides real game controllers from the system\nThis may prevent doubled inputs") + // + "\n" + // + qsTr("You can change this setting and which devices are hidden in the GlosSI overlay") + + // helpInfoDialog.open() + // } + // width: 48 + // height: 48 + // Material.elevation: 0 + // anchors.topMargin: 16 + // Image { + // anchors.centerIn: parent + // source: "qrc:/svg/help_outline_white_24dp.svg" + // width: 24 + // height: 24 + // } + // } + } } } } From ebab075b9f2055f87c2f0445a7680e8b07e31776 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 16:09:40 +0200 Subject: [PATCH 26/35] GlosSIConfig: Change alert wording --- GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml | 2 +- GlosSIConfig/qml/main.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml index 7c4e9f0..7e2350c 100644 --- a/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml +++ b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml @@ -101,7 +101,7 @@ Dialog { } InfoDialog { id: steamChangedDialog2 - titleText: qsTr("Attention!") + titleText: qsTr("Steam config changed!") text: qsTr("Please restart Steam to reload your changes!") onConfirmed: function (callback) { callback(); diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml index 9b141e0..3be4d08 100644 --- a/GlosSIConfig/qml/main.qml +++ b/GlosSIConfig/qml/main.qml @@ -75,8 +75,8 @@ Window { InfoDialog { id: steamChangedDialog - titleText: qsTr("Attention!") - text: qsTr("Please restart Steam to reload your changes!") + titleText: qsTr("Steam shortcuts changed!") + text: qsTr("Please restart Steam to reload your changes") onConfirmed: function (callback) { callback(); } From 4ede3a32a667df6753b9a0b8ba28464b9ad7a5ac Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 17:01:56 +0200 Subject: [PATCH 27/35] GlosSITarget: Fix device hiding --- GlosSITarget/HidHide.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index bc6a3e4..c86f49e 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -158,7 +158,7 @@ void HidHide::UnPatchValveHooks() // need to load addresses that way.. Otherwise we land before some jumps... if (const auto setupapidll = GetModuleHandle(L"setupapi.dll")) { UnPatchHook("SetupDiEnumDeviceInfo", setupapidll); - //UnPatchHook("SetupDiGetClassDevsW", setupapidll); + UnPatchHook("SetupDiGetClassDevsW", setupapidll); } if (const auto hiddll = GetModuleHandle(L"hid.dll")) { for (const auto& name : ORIGINAL_BYTES | std::views::keys) { @@ -197,6 +197,7 @@ void HidHide::enableOverlayElement() ImGui::SetNextWindowSizeConstraints({400, 270}, {1000, 1000}); if (ImGui::Begin("Hidden Devices")) { if (window_has_focus && (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_)) { + // UnPatchValveHooks(); openCtrlDevice(); bool hidehide_state_store = hidhide_active_; if (Settings::extendedLogging) { From e40eb8b117217679a38007384aa4ef025e0f3c4f Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 17:02:28 +0200 Subject: [PATCH 28/35] GlosSITarget: fix HidHide copy&pasta error --- GlosSITarget/HidHide.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index c86f49e..8f71ae7 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -121,7 +121,7 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) if (!dev.device_instance_path.empty()) { blacklisted_devices_.push_back(dev.device_instance_path); } - if (!dev.device_instance_path.empty()) { + if (!dev.base_container_device_instance_path.empty()) { blacklisted_devices_.push_back(dev.base_container_device_instance_path); } } From ebddcf482a5f5a4d4af9c44e111f0aac3d2857e5 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 17:03:10 +0200 Subject: [PATCH 29/35] GlosSITarget: always use real PID (but still fake VID) --- GlosSITarget/HidHide.cpp | 2 +- GlosSITarget/InputRedirector.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index 8f71ae7..c8a5323 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -117,7 +117,7 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) return blackdev == dev.device_instance_path || blackdev == dev.base_container_device_instance_path; })) { // Valve emulated gamepad PID/VID; mirrord by ViGEm - if (!(dev.vendor_id == 0x28de && dev.product_id == 0x11FF)) { + if (!(dev.vendor_id == 0x28de && (dev.product_id == 0x11FF || dev.product_id == 0x028E))) { if (!dev.device_instance_path.empty()) { blacklisted_devices_.push_back(dev.device_instance_path); } diff --git a/GlosSITarget/InputRedirector.cpp b/GlosSITarget/InputRedirector.cpp index b4bf106..1fdfc02 100644 --- a/GlosSITarget/InputRedirector.cpp +++ b/GlosSITarget/InputRedirector.cpp @@ -163,7 +163,8 @@ void InputRedirector::runLoop() // Multiple controllers can be worked around with by setting max count. if (!use_real_vid_pid_) { vigem_target_set_vid(vt_pad_[i], 0x28de); //VALVE_DIRECTINPUT_GAMEPAD_VID - vigem_target_set_pid(vt_pad_[i], 0x11FF); //VALVE_DIRECTINPUT_GAMEPAD_PID + //vigem_target_set_pid(vt_pad_[i], 0x11FF); //VALVE_DIRECTINPUT_GAMEPAD_PID + vigem_target_set_pid(vt_pad_[i], 0x028E); // XBOX 360 Controller } else { vigem_target_set_vid(vt_pad_[i], 0x045E); // MICROSOFT vigem_target_set_pid(vt_pad_[i], 0x028E); // XBOX 360 Controller From da51d351ed8048a44361047f6a28bee51611ba81 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 17:06:13 +0200 Subject: [PATCH 30/35] GlosSITarget: extendedLogging: also log available gaming devices --- GlosSITarget/HidHide.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index c8a5323..64e10ce 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -110,6 +110,11 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path) setAppWhiteList(whitelist); avail_devices_ = GetHidDeviceList(); + if (Settings::extendedLogging) { + std::ranges::for_each(avail_devices_, [](const auto& dev) { + spdlog::trace(L"AvailDevice device: {}", dev.name); + }); + } blacklisted_devices_ = getBlackListDevices(); for (const auto& dev : avail_devices_) { @@ -207,6 +212,11 @@ void HidHide::enableOverlayElement() setActive(false); } avail_devices_ = GetHidDeviceList(); + if (Settings::extendedLogging) { + std::ranges::for_each(avail_devices_, [](const auto& dev) { + spdlog::trace(L"AvailDevice device: {}", dev.name); + }); + } blacklisted_devices_ = getBlackListDevices(); if (hidehide_state_store) { setActive(true); From 9d6bbdeecb1870cd8d37e1d2ae055b712d82c824 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 20:51:14 +0200 Subject: [PATCH 31/35] SteamTarget: Use Imgui-Docking branch and overhaul overlay - might need to delete `%appdata%\GlosSI\imgui.ini` --- GlosSITarget/HidHide.cpp | 5 +- GlosSITarget/InputRedirector.cpp | 5 +- GlosSITarget/Overlay.cpp | 49 ++++--- GlosSITarget/Overlay.h | 7 +- GlosSITarget/ProcessPriority.h | 5 +- GlosSITarget/Resource.rc | 220 ++++++++++++++++++++++++++++++- GlosSITarget/TargetWindow.cpp | 4 +- GlosSITarget/UWPOverlayEnabler.h | 6 +- deps/imgui | 2 +- 9 files changed, 259 insertions(+), 44 deletions(-) diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp index 64e10ce..1655e32 100644 --- a/GlosSITarget/HidHide.cpp +++ b/GlosSITarget/HidHide.cpp @@ -197,9 +197,8 @@ void HidHide::UnPatchHook(const std::string& name, HMODULE module) void HidHide::enableOverlayElement() { - Overlay::AddOverlayElem([this](bool window_has_focus) { - ImGui::SetNextWindowPos({650, 100}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints({400, 270}, {1000, 1000}); + Overlay::AddOverlayElem([this](bool window_has_focus, ImGuiID dockspace_id) { + ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); if (ImGui::Begin("Hidden Devices")) { if (window_has_focus && (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_)) { // UnPatchValveHooks(); diff --git a/GlosSITarget/InputRedirector.cpp b/GlosSITarget/InputRedirector.cpp index 1fdfc02..498ce05 100644 --- a/GlosSITarget/InputRedirector.cpp +++ b/GlosSITarget/InputRedirector.cpp @@ -53,9 +53,8 @@ void InputRedirector::run() max_controller_count_ = Settings::controller.maxControllers; use_real_vid_pid_ = Settings::devices.realDeviceIds; #ifdef _WIN32 - Overlay::AddOverlayElem([this](bool window_has_focus) { - ImGui::SetNextWindowPos({650, 450}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints({400, 270}, {1000, 1000}); + Overlay::AddOverlayElem([this](bool window_has_focus, ImGuiID dockspace_id) { + ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); ImGui::Begin("Controller Emulation"); int countcopy = max_controller_count_; ImGui::Text("Max. controller count"); diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index b1cadcd..dd7b6b4 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -38,12 +38,14 @@ Overlay::Overlay( ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.Fonts->Clear(); // clear fonts if you loaded some before (even if only default one was loaded) auto fontconf = ImFontConfig{}; fontconf.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromMemoryTTF(Roboto_Regular_ttf.data(), Roboto_Regular_ttf.size(), 24, &fontconf); - ImGui::SFML::UpdateFontTexture(); // important call: updates font texture + ImGui::SFML::UpdateFontTexture(); #ifdef _WIN32 auto config_path = std::filesystem::temp_directory_path() @@ -56,6 +58,7 @@ Overlay::Overlay( if (!std::filesystem::exists(config_path)) std::filesystem::create_directories(config_path); config_path /= "imgui.ini"; + // This assumes that char is utf8 and wchar_t is utf16, which is guaranteed on Windows. config_file_name_ = std::wstring_convert>().to_bytes(config_path.wstring()); io.IniFilename = config_file_name_.data(); @@ -152,14 +155,31 @@ void Overlay::update() { ImGui::SFML::Update(window_, update_clock_.restart()); - showLogs(); + showLogs(0); + if (enabled_ || force_enable_) { + // Create a DockSpace node where any window can be docked + ImGui::SetNextWindowSize({ImGui::GetMainViewport()->Size.x * 0.6f, ImGui::GetMainViewport()->Size.y * 0.7f}, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.25f, 150 }, ImGuiCond_FirstUseEver); + ImGui::Begin("GlosSI Settings"); + if (Settings::settings_path_ != "") { + if (ImGui::Button("Save shortcut settings", {256, 32})) { + Settings::StoreSettings(); + } + } + ImGuiID dockspace_id = ImGui::GetID("GlosSI-DockSpace"); + ImGui::DockSpace(dockspace_id); + window_.clear(sf::Color(0, 0, 0, 128)); // make window slightly dim screen with overlay - std::ranges::for_each(OVERLAY_ELEMS_, [this](const auto& elem) { - elem.second(window_.hasFocus()); + + + std::ranges::for_each(OVERLAY_ELEMS_, [this, &dockspace_id](const auto& elem) { + elem.second(window_.hasFocus(), dockspace_id); }); + ImGui::End(); + // ImGui::ShowDemoWindow(); if (closeButton()) { @@ -167,7 +187,6 @@ void Overlay::update() } closeOverlayButton(); - saveSettingsButton(); } ImGui::SFML::Render(window_); @@ -188,7 +207,7 @@ void Overlay::AddLog(const spdlog::details::log_msg& msg) LOG_MSGS_.push_back({.time = msg.time, .level = msg.level, .payload = msg.payload.data()}); } -int Overlay::AddOverlayElem(const std::function& elem_fn) +int Overlay::AddOverlayElem(const std::function& elem_fn) { OVERLAY_ELEMS_.insert({overlay_element_id_, elem_fn}); // keep this non confusing, but longer... @@ -202,7 +221,7 @@ void Overlay::RemoveOverlayElem(int id) OVERLAY_ELEMS_.erase(id); } -void Overlay::showLogs() +void Overlay::showLogs(ImGuiID dockspace_id) { std::vector logs; if (!enabled_ && !log_expanded_) { @@ -240,6 +259,9 @@ void Overlay::showLogs() ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar); } else { + //ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize({ImGui::GetMainViewport()->Size.x * 0.2f, ImGui::GetMainViewport()->Size.y * 0.7f}, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.05f, 150}, ImGuiCond_FirstUseEver); log_expanded_ = ImGui::Begin("Log"); } if (log_expanded_) { @@ -314,16 +336,3 @@ bool Overlay::closeButton() const ImGui::PopStyleVar(); return false; } - -void Overlay::saveSettingsButton() const -{ - if (Settings::settings_path_ != "") { - ImGui::SetNextWindowPos({(window_.getSize().x - ImGui::GetWindowWidth()) / 2, (window_.getSize().y - ImGui::GetWindowHeight()) / 2}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints({192, 96}, {512, 512}); - ImGui::Begin("Shortcut settings"); - if (ImGui::Button("Save settings", {256, 32})) { - Settings::StoreSettings(); - } - ImGui::End(); - } -} diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h index b971bfa..1f0ebf1 100644 --- a/GlosSITarget/Overlay.h +++ b/GlosSITarget/Overlay.h @@ -38,7 +38,7 @@ class Overlay { static void Shutdown(); static void AddLog(const spdlog::details::log_msg& msg); - static int AddOverlayElem(const std::function& elem_fn); + static int AddOverlayElem(const std::function& elem_fn); static void RemoveOverlayElem(int id); private: @@ -47,10 +47,9 @@ class Overlay { bool enabled_ = true; std::function on_close_; std::function trigger_state_change_; - void showLogs(); + void showLogs(ImGuiID dockspace_id); bool closeOverlayButton() const; [[nodiscard]] bool closeButton() const; - void saveSettingsButton() const; bool force_enable_ = false; bool log_expanded_ = true; sf::Clock time_since_start_clock_; @@ -65,7 +64,7 @@ class Overlay { static constexpr int HIDE_NORMAL_LOGS_AFTER_S = 20; static inline int overlay_element_id_ = 0; - static inline std::map> OVERLAY_ELEMS_; + static inline std::map> OVERLAY_ELEMS_; #ifdef _WIN32 std::string config_file_name_; diff --git a/GlosSITarget/ProcessPriority.h b/GlosSITarget/ProcessPriority.h index 5357a77..f63a429 100644 --- a/GlosSITarget/ProcessPriority.h +++ b/GlosSITarget/ProcessPriority.h @@ -13,9 +13,8 @@ inline void init() { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); - Overlay::AddOverlayElem([](bool window_has_focus) { - ImGui::SetNextWindowPos({913, 418}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints({170, 325}, {1000, 1000}); + Overlay::AddOverlayElem([](bool window_has_focus, ImGuiID dockspace_id) { + ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); ImGui::Begin("Process Priority"); ImGui::Text("Might help with input-lag or bad game performance"); if (ImGui::RadioButton("Realtime", current_priority == REALTIME_PRIORITY_CLASS)) { diff --git a/GlosSITarget/Resource.rc b/GlosSITarget/Resource.rc index 88b5f35..0bece18 100644 --- a/GlosSITarget/Resource.rc +++ b/GlosSITarget/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,8,102000500230 - PRODUCTVERSION 0,0,8,102000500230 + FILEVERSION 0,0,8,1031000051035 + PRODUCTVERSION 0,0,8,1031000051035 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - SteamTarget" - VALUE "FileVersion", "0.0.8.1-2-gc5fc23d" + VALUE "FileVersion", "0.0.8.1-31-gda51d35" VALUE "InternalName", "GlosSITarget" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSITarget.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.8.1-2-gc5fc23d" + VALUE "ProductVersion", "0.0.8.1-31-gda51d35" END END BLOCK "VarFileInfo" @@ -184,6 +184,218 @@ IDI_ICON1 ICON "GloSC_Icon.ico" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSITarget/TargetWindow.cpp b/GlosSITarget/TargetWindow.cpp index b411af6..32790c6 100644 --- a/GlosSITarget/TargetWindow.cpp +++ b/GlosSITarget/TargetWindow.cpp @@ -50,9 +50,9 @@ TargetWindow::TargetWindow( { createWindow(Settings::window.windowMode); - Overlay::AddOverlayElem([this](bool window_has_focus) { + Overlay::AddOverlayElem([this](bool window_has_focus, ImGuiID dockspace_id) { + ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); bool windowed_copy = windowed_; - ImGui::SetNextWindowPos({window_.getSize().x - 370.f, 100}, ImGuiCond_FirstUseEver); ImGui::Begin("Window mode"); if (ImGui::Checkbox("Window mode", &windowed_copy)) { toggle_window_mode_after_frame_ = true; diff --git a/GlosSITarget/UWPOverlayEnabler.h b/GlosSITarget/UWPOverlayEnabler.h index 110b329..02e63fa 100644 --- a/GlosSITarget/UWPOverlayEnabler.h +++ b/GlosSITarget/UWPOverlayEnabler.h @@ -60,10 +60,8 @@ inline void EnableUwpOverlay() inline void AddUwpOverlayOvWidget() { - Overlay::AddOverlayElem([](bool window_has_focus) { - ImGui::SetNextWindowPos({1200, 250}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints({170, 325}, {1000, 1000}); - ImGui::SetNextWindowCollapsed(true, ImGuiCond_FirstUseEver); + Overlay::AddOverlayElem([](bool window_has_focus, ImGuiID dockspace_id) { + ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); ImGui::Begin("UWP-Overlay"); ImGui::Text("To enable the overlay on top of \"fullscreen\" UWP-Apps,"); ImGui::Text("a .dll has to be injected into explorer.exe"); diff --git a/deps/imgui b/deps/imgui index 9aae45e..9cd9c2e 160000 --- a/deps/imgui +++ b/deps/imgui @@ -1 +1 @@ -Subproject commit 9aae45eb4a05a5a1f96be1ef37eb503a12ceb889 +Subproject commit 9cd9c2eff99877a3f10a7f9c2a3a5b9c15ea36c6 From 43546b3d9c8df4ac7127d620089dceff53b656af Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 20:52:44 +0200 Subject: [PATCH 32/35] Overlay tweaks --- GlosSITarget/Overlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index dd7b6b4..a952dcb 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -161,7 +161,7 @@ void Overlay::update() if (enabled_ || force_enable_) { // Create a DockSpace node where any window can be docked ImGui::SetNextWindowSize({ImGui::GetMainViewport()->Size.x * 0.6f, ImGui::GetMainViewport()->Size.y * 0.7f}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.25f, 150 }, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.25f, 100 }, ImGuiCond_FirstUseEver); ImGui::Begin("GlosSI Settings"); if (Settings::settings_path_ != "") { if (ImGui::Button("Save shortcut settings", {256, 32})) { @@ -261,7 +261,7 @@ void Overlay::showLogs(ImGuiID dockspace_id) else { //ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize({ImGui::GetMainViewport()->Size.x * 0.2f, ImGui::GetMainViewport()->Size.y * 0.7f}, ImGuiCond_FirstUseEver); - ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.05f, 150}, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos({ImGui::GetMainViewport()->Size.x * 0.05f, 100}, ImGuiCond_FirstUseEver); log_expanded_ = ImGui::Begin("Log"); } if (log_expanded_) { From 084c282ce2c881553e30c161fb6e286e57c997e3 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 20:56:17 +0200 Subject: [PATCH 33/35] Log processpriority changes --- GlosSITarget/ProcessPriority.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GlosSITarget/ProcessPriority.h b/GlosSITarget/ProcessPriority.h index f63a429..60528e8 100644 --- a/GlosSITarget/ProcessPriority.h +++ b/GlosSITarget/ProcessPriority.h @@ -12,6 +12,7 @@ static int current_priority = HIGH_PRIORITY_CLASS; inline void init() { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); + spdlog::trace("Set process priority to HIGH_PRIORITY_CLASS"); Overlay::AddOverlayElem([](bool window_has_focus, ImGuiID dockspace_id) { ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_FirstUseEver); @@ -20,26 +21,32 @@ inline void init() if (ImGui::RadioButton("Realtime", current_priority == REALTIME_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); current_priority = REALTIME_PRIORITY_CLASS; + spdlog::trace("Set process priority to REALTIME_PRIORITY_CLASS"); } if (ImGui::RadioButton("High", current_priority == HIGH_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); current_priority = HIGH_PRIORITY_CLASS; + spdlog::trace("Set process priority to HIGH_PRIORITY_CLASS"); } if (ImGui::RadioButton("Above Normal", current_priority == ABOVE_NORMAL_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); current_priority = ABOVE_NORMAL_PRIORITY_CLASS; + spdlog::trace("Set process priority to ABOVE_NORMAL_PRIORITY_CLASS"); } if (ImGui::RadioButton("Normal", current_priority == NORMAL_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); current_priority = NORMAL_PRIORITY_CLASS; + spdlog::trace("Set process priority to NORMAL_PRIORITY_CLASS"); } if (ImGui::RadioButton("Below Normal", current_priority == BELOW_NORMAL_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); current_priority = BELOW_NORMAL_PRIORITY_CLASS; + spdlog::trace("Set process priority to BELOW_NORMAL_PRIORITY_CLASS"); } if (ImGui::RadioButton("Low", current_priority == IDLE_PRIORITY_CLASS)) { SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); current_priority = IDLE_PRIORITY_CLASS; + spdlog::trace("Set process priority to IDLE_PRIORITY_CLASS"); } ImGui::End(); }); From 4f1109d77a0f2f4ef78ebcc1208800da1b7bd092 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 20:59:29 +0200 Subject: [PATCH 34/35] Fix errounous log "Child process with PID 0 died" - 0 pid is appended if parent process dies; ignore that --- GlosSITarget/AppLauncher.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GlosSITarget/AppLauncher.cpp b/GlosSITarget/AppLauncher.cpp index 7bc3f25..e660331 100644 --- a/GlosSITarget/AppLauncher.cpp +++ b/GlosSITarget/AppLauncher.cpp @@ -77,6 +77,9 @@ void AppLauncher::update() } if (Settings::launch.waitForChildProcs) { std::erase_if(pids_, [](auto pid) { + if (pid == 0) { + return true; + } const auto running = IsProcessRunning(pid); if (!running) spdlog::trace("Child process with PID \"{}\" died", pid); From abeca3eb816a66c57b3c9aaf17676430117b9cbf Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Fri, 23 Sep 2022 21:29:01 +0200 Subject: [PATCH 35/35] UwpOverlayEnabler: Config to set WindowBand create file %appdata%\GlosSI\UWPOverlayEnabler.cfg and fill with one of those ZBID values ZBID_DEFAULT ZBID_DESKTOP ZBID_UIACCESS ZBID_IMMERSIVE_IHM ZBID_IMMERSIVE_NOTIFICATION ZBID_IMMERSIVE_APPCHROME ZBID_IMMERSIVE_MOGO ZBID_IMMERSIVE_EDGY ZBID_IMMERSIVE_INACTIVEMOBODY ZBID_IMMERSIVE_INACTIVEDOCK ZBID_IMMERSIVE_ACTIVEMOBODY ZBID_IMMERSIVE_ACTIVEDOCK ZBID_IMMERSIVE_BACKGROUND ZBID_IMMERSIVE_SEARCH ZBID_GENUINE_WINDOWS ZBID_IMMERSIVE_RESTRICTED ZBID_SYSTEM_TOOLS ZBID_LOCK ZBID_ABOVELOCK_UX --- UWPOverlayEnablerDLL/dllmain.cpp | 80 ++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/UWPOverlayEnablerDLL/dllmain.cpp b/UWPOverlayEnablerDLL/dllmain.cpp index 1ce6e6a..2e2f1a3 100644 --- a/UWPOverlayEnablerDLL/dllmain.cpp +++ b/UWPOverlayEnablerDLL/dllmain.cpp @@ -54,6 +54,7 @@ There are two (known to me, at time of writing) ways to get a working overlay fo #include #include +#include enum ZBID { @@ -77,6 +78,7 @@ enum ZBID ZBID_LOCK = 17, ZBID_ABOVELOCK_UX = 18, }; + typedef BOOL(WINAPI* fSetWindowBand)(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand); @@ -85,6 +87,8 @@ fSetWindowBand SetWindowBand; std::atomic allow_exit = false; +std::atomic to_set_window_band = ZBID_SYSTEM_TOOLS; + BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand) { subhook::ScopedHookRemove remove(&SetWindowBandHook); @@ -96,11 +100,10 @@ BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand) // However, notification and system_tools does! // use system tools, as that allows the steam overlay to be interacted with // without UWP apps minimizing - SetWindowBand(glossi_hwnd, nullptr, ZBID_SYSTEM_TOOLS); + auto success = SetWindowBand(glossi_hwnd, nullptr, to_set_window_band); allow_exit = true; - spdlog::info("Set GlosSI Window Band to ZBID_SYSTEM_TOOLS"); + spdlog::info("Set GlosSI Window Band to {}; success: {}", static_cast(to_set_window_band), success); } - spdlog::info("Calling original"); return SetWindowBand(hWnd, hwndInsertAfter, dwBand); } @@ -126,17 +129,21 @@ BOOL APIENTRY DllMain( HMODULE hModule, if (ul_reason_for_call == DLL_PROCESS_ATTACH) { - auto path = std::filesystem::temp_directory_path() + auto configDirPath = std::filesystem::temp_directory_path() .parent_path() .parent_path() .parent_path(); - path /= "Roaming"; - path /= "GlosSI"; - if (!std::filesystem::exists(path)) - std::filesystem::create_directories(path); - path /= "UWPOverlayEnabler.log"; - const auto file_sink = std::make_shared(path.string(), true); + configDirPath /= "Roaming"; + configDirPath /= "GlosSI"; + if (!std::filesystem::exists(configDirPath)) + std::filesystem::create_directories(configDirPath); + + + + auto logPath = configDirPath; + logPath /= "UWPOverlayEnabler.log"; + const auto file_sink = std::make_shared(logPath.string(), true); std::vector sinks{ file_sink }; auto logger = std::make_shared("log", sinks.begin(), sinks.end()); logger->set_level(spdlog::level::trace); @@ -145,6 +152,59 @@ BOOL APIENTRY DllMain( HMODULE hModule, spdlog::info("UWPOverlayEnabler loaded"); + auto configPath = configDirPath; + configPath /= "UWPOverlayEnabler.cfg"; + if (std::filesystem::exists(configPath)) + { + std::ifstream config(configPath); + std::string line; + while (std::getline(config, line)) + { + // github copilot, lol + // i take it! + if (line == "ZBID_DEFAULT") + to_set_window_band = ZBID_DEFAULT; + else if (line == "ZBID_DESKTOP") + to_set_window_band = ZBID_DESKTOP; + else if (line == "ZBID_UIACCESS") + to_set_window_band = ZBID_UIACCESS; + else if (line == "ZBID_IMMERSIVE_IHM") + to_set_window_band = ZBID_IMMERSIVE_IHM; + else if (line == "ZBID_IMMERSIVE_NOTIFICATION") + to_set_window_band = ZBID_IMMERSIVE_NOTIFICATION; + else if (line == "ZBID_IMMERSIVE_APPCHROME") + to_set_window_band = ZBID_IMMERSIVE_APPCHROME; + else if (line == "ZBID_IMMERSIVE_MOGO") + to_set_window_band = ZBID_IMMERSIVE_MOGO; + else if (line == "ZBID_IMMERSIVE_EDGY") + to_set_window_band = ZBID_IMMERSIVE_EDGY; + else if (line == "ZBID_IMMERSIVE_INACTIVEMOBODY") + to_set_window_band = ZBID_IMMERSIVE_INACTIVEMOBODY; + else if (line == "ZBID_IMMERSIVE_INACTIVEDOCK") + to_set_window_band = ZBID_IMMERSIVE_INACTIVEDOCK; + else if (line == "ZBID_IMMERSIVE_ACTIVEMOBODY") + to_set_window_band = ZBID_IMMERSIVE_ACTIVEMOBODY; + else if (line == "ZBID_IMMERSIVE_ACTIVEDOCK") + to_set_window_band = ZBID_IMMERSIVE_ACTIVEDOCK; + else if (line == "ZBID_IMMERSIVE_BACKGROUND") + to_set_window_band = ZBID_IMMERSIVE_BACKGROUND; + else if (line == "ZBID_IMMERSIVE_SEARCH") + to_set_window_band = ZBID_IMMERSIVE_SEARCH; + else if (line == "ZBID_GENUINE_WINDOWS") + to_set_window_band = ZBID_GENUINE_WINDOWS; + else if (line == "ZBID_IMMERSIVE_RESTRICTED") + to_set_window_band = ZBID_IMMERSIVE_RESTRICTED; + else if (line == "ZBID_SYSTEM_TOOLS") + to_set_window_band = ZBID_SYSTEM_TOOLS; + else if (line == "ZBID_LOCK") + to_set_window_band = ZBID_LOCK; + else if (line == "ZBID_ABOVELOCK_UX") + to_set_window_band = ZBID_ABOVELOCK_UX; + + } + spdlog::info("Read window band from config: {}", static_cast(to_set_window_band)); + } + const auto hpath = LoadLibrary(L"user32.dll"); if (hpath) {