diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index 0b6113f..3053be8 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -18,7 +18,13 @@ limitations under the License. #include #include -Overlay::Overlay(sf::RenderWindow& window, std::function on_close) : window_(window), on_close_(std::move(on_close)) +Overlay::Overlay( + sf::RenderWindow& window, + std::function on_close, + bool force_enable) + : window_(window), + on_close_(std::move(on_close)), + force_enable_(force_enable) { ImGui::SFML::Init(window_); @@ -134,7 +140,7 @@ void Overlay::update() showLogs(); - if (enabled_) { + if (enabled_ || force_enable_) { window_.clear(sf::Color(0, 0, 0, 64)); // make window slightly dim screen with overlay std::ranges::for_each(OVERLAY_ELEMS_, [](const auto& fn) { fn(); }); diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h index 63080fe..f0895b8 100644 --- a/GlosSITarget/Overlay.h +++ b/GlosSITarget/Overlay.h @@ -28,7 +28,7 @@ limitations under the License. class Overlay { public: - Overlay(sf::RenderWindow& window, std::function on_close); + Overlay(sf::RenderWindow& window, std::function on_close, bool force_enable = false); void setEnabled(bool enabled); bool isEnabled() const; @@ -47,6 +47,7 @@ class Overlay { std::function on_close_; void showLogs() const; [[nodiscard]] bool closeButton() const; + bool force_enable_ = false; struct Log { std::chrono::system_clock::time_point time; diff --git a/GlosSITarget/Resource.rc b/GlosSITarget/Resource.rc index 5c54f4a..4186eb4 100644 --- a/GlosSITarget/Resource.rc +++ b/GlosSITarget/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,0,9303501 - PRODUCTVERSION 0,0,0,9303501 + FILEVERSION 0,0,0,2080504 + PRODUCTVERSION 0,0,0,2080504 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.0.93c35f1" + VALUE "FileVersion", "0.0.0.2a805b4" VALUE "InternalName", "GlosSITarget" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSITarget.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.0.93c35f1" + VALUE "ProductVersion", "0.0.0.2a805b4" END END BLOCK "VarFileInfo" @@ -164,6 +164,74 @@ END + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp index e1688e1..123c34e 100644 --- a/GlosSITarget/SteamTarget.cpp +++ b/GlosSITarget/SteamTarget.cpp @@ -26,7 +26,13 @@ limitations under the License. #include SteamTarget::SteamTarget(int argc, char* argv[]) - : window_([this] { run_ = false; }, getScreenshotHotkey()), + : window_( + [this] { run_ = false; }, + getScreenshotHotkey(), + [this]() { + target_window_handle_ = window_.getSystemHandle(); + overlay_ = window_.getOverlay(); + }), overlay_(window_.getOverlay()), detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }), launcher_([this] { @@ -43,22 +49,25 @@ int SteamTarget::run() spdlog::warn("Steam-overlay not detected. Showing GlosSI-overlay!\n\ Application will not function!"); window_.setClickThrough(false); - overlay_.setEnabled(true); + if (!overlay_.expired()) + overlay_.lock()->setEnabled(true); steam_overlay_present_ = false; - } else { + } + else { spdlog::info("Steam-overlay detected."); spdlog::warn("Open/Close Steam-overlay twice to show GlosSI-overlay"); // Just to color output and really get users attention window_.setClickThrough(true); - overlay_.setEnabled(false); + if (!overlay_.expired()) + overlay_.lock()->setEnabled(false); steam_overlay_present_ = true; } getXBCRebindingEnabled(); run_ = true; -#ifdef _WIN32 +#ifdef _WIN32 hidhide_.hideDevices(steam_path_); - input_redirector_.run(); + input_redirector_.run(); #endif if (Settings::launch.launch) { @@ -68,14 +77,15 @@ Application will not function!"); keepControllerConfig(true); while (run_) { detector_.update(); - window_.update(); overlayHotkeyWorkaround(); + window_.update(); // Wait on shutdown; User might get confused if window closes to fast if anything with launchApp get's borked. if (delayed_shutdown_) { if (delay_shutdown_clock_.getElapsedTime().asSeconds() >= 3) { run_ = false; } - } else { + } + else { launcher_.update(); } } @@ -102,19 +112,20 @@ void SteamTarget::onOverlayChanged(bool overlay_open) } else { if (overlay_trigger_clock_.getElapsedTime().asSeconds() <= overlay_trigger_max_seconds_) { - const auto ov_opened = overlay_.toggle(); + const auto ov_opened = overlay_.expired() ? false : overlay_.lock()->toggle(); window_.setClickThrough(!ov_opened); if (ov_opened) { spdlog::info("Opened GlosSI-overlay"); focusWindow(target_window_handle_); - } else { + } + else { focusWindow(last_foreground_window_); spdlog::info("Closed GlosSI-overlay"); } } overlay_trigger_flag_ = false; } - if (!overlay_.isEnabled()) { + if (!( overlay_.expired() ? false : overlay_.lock()->isEnabled())) { window_.setClickThrough(!overlay_open); focusWindow(last_foreground_window_); } @@ -124,7 +135,6 @@ void SteamTarget::onOverlayChanged(bool overlay_open) void SteamTarget::focusWindow(WindowHandle hndl) { #ifdef _WIN32 - if (hndl == target_window_handle_) { spdlog::debug("Bring own window to foreground"); } @@ -136,7 +146,7 @@ void SteamTarget::focusWindow(WindowHandle hndl) const auto current_fgw = GetForegroundWindow(); if (current_fgw != target_window_handle_) { last_foreground_window_ = current_fgw; - } + } const auto fg_thread = GetWindowThreadProcessId(current_fgw, nullptr); keepControllerConfig(true); // re-hook GetForegroundWindow @@ -177,7 +187,7 @@ std::filesystem::path SteamTarget::getSteamPath() const #endif } - std::wstring SteamTarget::getSteamUserId() const +std::wstring SteamTarget::getSteamUserId() const { #ifdef _WIN32 // TODO: check if keys/value exist diff --git a/GlosSITarget/SteamTarget.h b/GlosSITarget/SteamTarget.h index 161e7dc..cb2097c 100644 --- a/GlosSITarget/SteamTarget.h +++ b/GlosSITarget/SteamTarget.h @@ -75,7 +75,7 @@ class SteamTarget { InputRedirector input_redirector_; #endif TargetWindow window_; - Overlay& overlay_; + std::weak_ptr overlay_; SteamOverlayDetector detector_; AppLauncher launcher_; WindowHandle last_foreground_window_ = nullptr; diff --git a/GlosSITarget/TargetWindow.cpp b/GlosSITarget/TargetWindow.cpp index 932190e..a78c4f4 100644 --- a/GlosSITarget/TargetWindow.cpp +++ b/GlosSITarget/TargetWindow.cpp @@ -36,68 +36,24 @@ limitations under the License. #endif -TargetWindow::TargetWindow(std::function on_close, std::vector screenshot_hotkey) +TargetWindow::TargetWindow( + std::function on_close, + std::vector screenshot_hotkey, + std::function on_window_changed) : on_close_(std::move(on_close)), screenshot_keys_(std::move(screenshot_hotkey)), - overlay_(window_, [this]() { close(); }) + on_window_changed_(std::move(on_window_changed)) { - auto desktop_mode = sf::VideoMode::getDesktopMode(); - if (Settings::window.windowMode) { - window_.create(sf::VideoMode(desktop_mode.width * 0.75, desktop_mode.height * 0.75, 32), "GlosSITarget"); - } else { -#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. - 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 - } - window_.setActive(true); - -#ifdef _WIN32 - HWND hwnd = window_.getSystemHandle(); - auto dpi = GetWindowDPI(hwnd); - spdlog::debug("Screen DPI: {}", dpi); - - // transparent windows window... - auto style = GetWindowLong(hwnd, GWL_STYLE); - style &= ~WS_OVERLAPPED; - style |= WS_POPUP; - SetWindowLong(hwnd, GWL_STYLE, style); - - MARGINS margins; - margins.cxLeftWidth = -1; - DwmExtendFrameIntoClientArea(hwnd, &margins); - - DEVMODE dev_mode = {}; - dev_mode.dmSize = sizeof(DEVMODE); - dev_mode.dmDriverExtra = 0; - - if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dev_mode) == 0) { - setFpsLimit(60); - } - else { - setFpsLimit(dev_mode.dmDisplayFrequency); - } - - ImGuiIO& io = ImGui::GetIO(); - io.FontGlobalScale = dpi / 96.f; - ImGui::SFML::UpdateFontTexture(); - -#else - setFpsLimit(60); -#endif - - if (Settings::window.maxFps > 0) { - setFpsLimit(Settings::window.maxFps); - } - if (Settings::window.scale > 0.3f) { // Now that's just getting ridicoulus - ImGuiIO& io = ImGui::GetIO(); - io.FontGlobalScale = Settings::window.scale; - ImGui::SFML::UpdateFontTexture(); - } + createWindow(Settings::window.windowMode); + Overlay::AddOverlayElem([this]() { + bool windowed_copy = windowed_; + ImGui::Begin("Window mode"); + if (ImGui::Checkbox("Window mode", &windowed_copy)) { + toggle_window_mode_after_frame_ = true; + } + ImGui::End(); + }); } void TargetWindow::setFpsLimit(unsigned int fps_limit) @@ -134,11 +90,17 @@ void TargetWindow::update() return; } } - - window_.clear(sf::Color(0,0,0,0)); - overlay_.update(); + if (windowed_) { + window_.clear(sf::Color(23, 23, 23, 255)); + } else { + window_.clear(sf::Color(0, 0, 0, 0)); + } screenShotWorkaround(); + overlay_->update(); window_.display(); + if (toggle_window_mode_after_frame_) { + createWindow(!windowed_); + } } void TargetWindow::close() @@ -148,7 +110,7 @@ void TargetWindow::close() on_close_(); } -Overlay& TargetWindow::getOverlay() +std::shared_ptr TargetWindow::getOverlay() const { return overlay_; } @@ -261,5 +223,79 @@ WORD TargetWindow::GetWindowDPI(HWND hWnd) return static_cast(iDpiX); } +#endif +void TargetWindow::createWindow(bool window_mode) +{ + toggle_window_mode_after_frame_ = false; + + auto desktop_mode = sf::VideoMode::getDesktopMode(); + if (window_mode) { + window_.create(sf::VideoMode(desktop_mode.width * 0.75, desktop_mode.height * 0.75, 32), "GlosSITarget"); + windowed_ = true; + } + else { +#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. + 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 + windowed_ = false; + } + window_.setActive(true); + +#ifdef _WIN32 + HWND hwnd = window_.getSystemHandle(); + auto dpi = GetWindowDPI(hwnd); + spdlog::debug("Screen DPI: {}", dpi); + + //if (windowed_) { + // DWM_BLURBEHIND bb{.dwFlags = DWM_BB_ENABLE, .fEnable = true, .hRgnBlur = nullptr}; + // DwmEnableBlurBehindWindow(hwnd, &bb); + //} // semi-transparent in window mode, but deprecated api + // TODO: MAYBE: use undocumented acrylic api as in GlosSI-Config + // On Linux the window will (should) automagically be semi-transparent + + // transparent windows window... + auto style = GetWindowLong(hwnd, GWL_STYLE); + style &= ~WS_OVERLAPPED; + style |= WS_POPUP; + SetWindowLong(hwnd, GWL_STYLE, style); + + MARGINS margins; + margins.cxLeftWidth = -1; + DwmExtendFrameIntoClientArea(hwnd, &margins); + + DEVMODE dev_mode = {}; + dev_mode.dmSize = sizeof(DEVMODE); + dev_mode.dmDriverExtra = 0; + + if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dev_mode) == 0) { + setFpsLimit(60); + } + else { + setFpsLimit(dev_mode.dmDisplayFrequency); + } + + overlay_ = std::make_shared(window_, [this]() { close(); }, windowed_); + + ImGuiIO& io = ImGui::GetIO(); + io.FontGlobalScale = dpi / 96.f; + ImGui::SFML::UpdateFontTexture(); + +#else + setFpsLimit(60); #endif + + if (Settings::window.maxFps > 0) { + setFpsLimit(Settings::window.maxFps); + } + if (Settings::window.scale > 0.3f) { // Now that's just getting ridicoulus + ImGuiIO& io = ImGui::GetIO(); + io.FontGlobalScale = Settings::window.scale; + ImGui::SFML::UpdateFontTexture(); + } + on_window_changed_(); +} diff --git a/GlosSITarget/TargetWindow.h b/GlosSITarget/TargetWindow.h index ee2397f..4686176 100644 --- a/GlosSITarget/TargetWindow.h +++ b/GlosSITarget/TargetWindow.h @@ -31,14 +31,17 @@ using WindowHandle = int; // ??? class TargetWindow { public: explicit TargetWindow( - std::function on_close = []() {}, std::vector screenshot_hotkey = {"KEY_F12"}); + std::function on_close = []() {}, + std::vector screenshot_hotkey = {"KEY_F12"}, + std::function on_window_changed = []() {} + ); void setFpsLimit(unsigned int fps_limit); void setClickThrough(bool click_through); void update(); void close(); - Overlay& getOverlay(); + std::shared_ptr getOverlay() const; /* * Run once per frame @@ -63,6 +66,13 @@ class TargetWindow { const std::function on_close_; sf::RenderWindow window_; std::vector screenshot_keys_; + const std::function on_window_changed_; - Overlay overlay_; + + std::shared_ptr overlay_; + + void createWindow(bool window_mode); + + bool windowed_ = false; + bool toggle_window_mode_after_frame_ = false; }; diff --git a/GlosSITarget/example_conf.json b/GlosSITarget/example_conf.json index 8322118..c591793 100644 --- a/GlosSITarget/example_conf.json +++ b/GlosSITarget/example_conf.json @@ -1,7 +1,7 @@ { "version": 1, "launch": { - "launch": true, + "launch": false, "launchPath": "C:\\Users\\Alia5\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe", "launchAppArgs": "--new-window", "closeOnExit": true diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp index c2a8fe8..906e168 100644 --- a/GlosSITarget/main.cpp +++ b/GlosSITarget/main.cpp @@ -73,10 +73,10 @@ int main(int argc, char* argv[]) logger->flush_on(spdlog::level::info); spdlog::set_default_logger(logger); #ifdef _WIN32 - Settings::Parse(__argv[1]); + Settings::Parse(__argc > 1 ? __argv[1] : ""); SteamTarget target(__argc, __argv); #else - Settings::Parse(argv[1]); + Settings::Parse(argc > 1 ? argv[1] : ""); SteamTarget target(argc, argv); #endif const auto exit = target.run();