From f4a2f0431511b18c4c3677113d5ae3e61aaee52a Mon Sep 17 00:00:00 2001 From: Dylan Deverill Date: Sun, 10 May 2026 19:57:47 -0700 Subject: [PATCH] Add Start with Windows, installer script, and release build support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Start with Windows toggle in tray menu — writes/removes the Run registry key so the app launches automatically at login - Inno Setup installer script for packaging the release exe - CMakePresets.json for named debug/release build configurations - README updated with correct Visual Studio 2025 build commands and a note for VS 2022 users Co-Authored-By: Claude Sonnet 4.6 --- CMakePresets.json | 35 +++++++++++++++++++ README.md | 6 ++-- resources/InnoInstallerScript.iss | 56 +++++++++++++++++++++++++++++++ src/app/TrayApp.cpp | 40 +++++++++++++++++++++- src/app/TrayApp.h | 3 ++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 CMakePresets.json create mode 100644 resources/InnoInstallerScript.iss diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..c1bc80c --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,35 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "release", + "displayName": "Release", + "binaryDir": "${sourceDir}/build/release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "debug", + "displayName": "Debug", + "binaryDir": "${sourceDir}/build/debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + } + ], + "buildPresets": [ + { + "name": "release", + "configurePreset": "release", + "configuration": "Release", + "targets": ["SteamlessController"] + }, + { + "name": "debug", + "configurePreset": "debug", + "configuration": "Debug", + "targets": ["SteamlessController"] + } + ] +} diff --git a/README.md b/README.md index 0884265..8148a28 100644 --- a/README.md +++ b/README.md @@ -42,10 +42,12 @@ The executable will be at `build\Debug\SteamlessController.exe`. For a release build: ```bat -cmake -B build -DCMAKE_BUILD_TYPE=Release -cmake --build build --config Release --target SteamlessController +cmake -B build/release -G "Visual Studio 18 2025" +cmake --build build/release --config Release --target SteamlessController ``` +> If you have Visual Studio 2022, replace `"Visual Studio 18 2025"` with `"Visual Studio 17 2022"`. + ## CMake Targets | Target | Description | diff --git a/resources/InnoInstallerScript.iss b/resources/InnoInstallerScript.iss new file mode 100644 index 0000000..6b63cc5 --- /dev/null +++ b/resources/InnoInstallerScript.iss @@ -0,0 +1,56 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! +; Non-commercial use only + +#define MyAppName "SteamlessController" +#define MyAppVersion "1.0" +#define MyAppPublisher "Dylan Deverill" +#define MyAppURL "https://github.com/ddeverill/SteamlessController" +#define MyAppExeName "SteamlessController.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{4E6FF864-969A-44C6-B4AC-848F22D5EF57} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +UninstallDisplayIcon={app}\{#MyAppExeName} +; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run +; on anything but x64 and Windows 11 on Arm. +ArchitecturesAllowed=x64compatible +; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the +; install be done in "64-bit mode" on x64 or Windows 11 on Arm, +; meaning it should use the native 64-bit Program Files directory and +; the 64-bit view of the registry. +ArchitecturesInstallIn64BitMode=x64compatible +DisableProgramGroupPage=yes +; Uncomment the following line to run in non administrative install mode (install for current user only). +;PrivilegesRequired=lowest +OutputBaseFilename=SteamlessController-Setup +SetupIconFile=C:\Users\ddeve\iCloudDrive\Development\SteamlessController\resources\SteamControllerON.ico +SolidCompression=yes +WizardStyle=modern + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "C:\Users\ddeve\iCloudDrive\Development\SteamlessController\build\release\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/src/app/TrayApp.cpp b/src/app/TrayApp.cpp index 9d96de2..ec99600 100644 --- a/src/app/TrayApp.cpp +++ b/src/app/TrayApp.cpp @@ -106,6 +106,9 @@ LRESULT TrayApp::HandleMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { m_controller->SetUseLeftTrackpad(!m_controller->IsUseLeftTrackpad()); SaveSettings(); break; + case IDM_STARTUP: + SetStartupEnabled(!IsStartupEnabled()); + break; case IDM_EXIT: m_controller->DisableGameMode(); PostQuitMessage(0); @@ -177,7 +180,36 @@ void TrayApp::ShowViGEmBalloon() { Shell_NotifyIconW(NIM_MODIFY, &nid); } -static constexpr wchar_t REG_KEY[] = L"Software\\SteamlessController"; +static constexpr wchar_t REG_KEY[] = L"Software\\SteamlessController"; +static constexpr wchar_t REG_RUN_KEY[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; +static constexpr wchar_t APP_NAME[] = L"SteamlessController"; + +bool TrayApp::IsStartupEnabled() const { + HKEY key; + if (RegOpenKeyExW(HKEY_CURRENT_USER, REG_RUN_KEY, 0, KEY_READ, &key) != ERROR_SUCCESS) + return false; + bool exists = RegQueryValueExW(key, APP_NAME, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS; + RegCloseKey(key); + return exists; +} + +void TrayApp::SetStartupEnabled(bool enabled) { + HKEY key; + if (RegOpenKeyExW(HKEY_CURRENT_USER, REG_RUN_KEY, 0, KEY_WRITE, &key) != ERROR_SUCCESS) + return; + + if (enabled) { + wchar_t path[MAX_PATH]; + GetModuleFileNameW(nullptr, path, MAX_PATH); + RegSetValueExW(key, APP_NAME, 0, REG_SZ, + reinterpret_cast(path), + static_cast((wcslen(path) + 1) * sizeof(wchar_t))); + } else { + RegDeleteValueW(key, APP_NAME); + } + + RegCloseKey(key); +} void TrayApp::LoadSettings() { HKEY key; @@ -225,6 +257,7 @@ void TrayApp::ShowContextMenu() { bool trackpadOn = m_controller->IsTrackpadMouseEnabled(); bool backButtonsOn = m_controller->IsBackButtonsEnabled(); bool leftTrackpad = m_controller->IsUseLeftTrackpad(); + bool startupOn = IsStartupEnabled(); HMENU menu = CreatePopupMenu(); @@ -243,6 +276,11 @@ void TrayApp::ShowContextMenu() { UINT leftFlags = MF_STRING | (leftTrackpad ? MF_CHECKED : MF_UNCHECKED); AppendMenuW(menu, leftFlags, IDM_LEFT_TRACKPAD, L"Use Left Trackpad Instead"); + AppendMenuW(menu, MF_SEPARATOR, 0, nullptr); + + UINT startupFlags = MF_STRING | (startupOn ? MF_CHECKED : MF_UNCHECKED); + AppendMenuW(menu, startupFlags, IDM_STARTUP, L"Start with Windows"); + AppendMenuW(menu, MF_SEPARATOR, 0, nullptr); AppendMenuW(menu, MF_STRING, IDM_EXIT, L"Exit"); diff --git a/src/app/TrayApp.h b/src/app/TrayApp.h index e829b10..8914583 100644 --- a/src/app/TrayApp.h +++ b/src/app/TrayApp.h @@ -23,6 +23,8 @@ private: void ShowContextMenu(); void LoadSettings(); void SaveSettings(); + bool IsStartupEnabled() const; + void SetStartupEnabled(bool enabled); HWND m_hwnd = nullptr; HINSTANCE m_hInstance = nullptr; @@ -36,6 +38,7 @@ private: static constexpr UINT IDM_TRACKPAD = 1003; static constexpr UINT IDM_BACKBUTTONS = 1004; static constexpr UINT IDM_LEFT_TRACKPAD = 1005; + static constexpr UINT IDM_STARTUP = 1006; static constexpr UINT WM_TRAY = WM_APP + 1; static constexpr UINT TRAY_UID = 1; };