GlosSITarget: Overlay: Window mode switch

main
Peter Repukat 3 years ago
parent 2a805b488b
commit 7e895d7f4f

@ -18,7 +18,13 @@ limitations under the License.
#include <filesystem> #include <filesystem>
#include <utility> #include <utility>
Overlay::Overlay(sf::RenderWindow& window, std::function<void()> on_close) : window_(window), on_close_(std::move(on_close)) Overlay::Overlay(
sf::RenderWindow& window,
std::function<void()> on_close,
bool force_enable)
: window_(window),
on_close_(std::move(on_close)),
force_enable_(force_enable)
{ {
ImGui::SFML::Init(window_); ImGui::SFML::Init(window_);
@ -134,7 +140,7 @@ void Overlay::update()
showLogs(); showLogs();
if (enabled_) { if (enabled_ || force_enable_) {
window_.clear(sf::Color(0, 0, 0, 64)); // make window slightly dim screen with overlay 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(); }); std::ranges::for_each(OVERLAY_ELEMS_, [](const auto& fn) { fn(); });

@ -28,7 +28,7 @@ limitations under the License.
class Overlay { class Overlay {
public: public:
Overlay(sf::RenderWindow& window, std::function<void()> on_close); Overlay(sf::RenderWindow& window, std::function<void()> on_close, bool force_enable = false);
void setEnabled(bool enabled); void setEnabled(bool enabled);
bool isEnabled() const; bool isEnabled() const;
@ -47,6 +47,7 @@ class Overlay {
std::function<void()> on_close_; std::function<void()> on_close_;
void showLogs() const; void showLogs() const;
[[nodiscard]] bool closeButton() const; [[nodiscard]] bool closeButton() const;
bool force_enable_ = false;
struct Log { struct Log {
std::chrono::system_clock::time_point time; std::chrono::system_clock::time_point time;

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,9303501 FILEVERSION 0,0,0,2080504
PRODUCTVERSION 0,0,0,9303501 PRODUCTVERSION 0,0,0,2080504
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - SteamTarget" VALUE "FileDescription", "GlosSI - SteamTarget"
VALUE "FileVersion", "0.0.0.93c35f1" VALUE "FileVersion", "0.0.0.2a805b4"
VALUE "InternalName", "GlosSITarget" VALUE "InternalName", "GlosSITarget"
VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSITarget.exe" VALUE "OriginalFilename", "GlosSITarget.exe"
VALUE "ProductName", "GlosSI" VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.0.0.93c35f1" VALUE "ProductVersion", "0.0.0.2a805b4"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -164,6 +164,74 @@ END

@ -26,7 +26,13 @@ limitations under the License.
#include <vdf_parser.hpp> #include <vdf_parser.hpp>
SteamTarget::SteamTarget(int argc, char* argv[]) 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()), overlay_(window_.getOverlay()),
detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }), detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }),
launcher_([this] { launcher_([this] {
@ -43,22 +49,25 @@ int SteamTarget::run()
spdlog::warn("Steam-overlay not detected. Showing GlosSI-overlay!\n\ spdlog::warn("Steam-overlay not detected. Showing GlosSI-overlay!\n\
Application will not function!"); Application will not function!");
window_.setClickThrough(false); window_.setClickThrough(false);
overlay_.setEnabled(true); if (!overlay_.expired())
overlay_.lock()->setEnabled(true);
steam_overlay_present_ = false; steam_overlay_present_ = false;
} else { }
else {
spdlog::info("Steam-overlay detected."); 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 spdlog::warn("Open/Close Steam-overlay twice to show GlosSI-overlay"); // Just to color output and really get users attention
window_.setClickThrough(true); window_.setClickThrough(true);
overlay_.setEnabled(false); if (!overlay_.expired())
overlay_.lock()->setEnabled(false);
steam_overlay_present_ = true; steam_overlay_present_ = true;
} }
getXBCRebindingEnabled(); getXBCRebindingEnabled();
run_ = true; run_ = true;
#ifdef _WIN32 #ifdef _WIN32
hidhide_.hideDevices(steam_path_); hidhide_.hideDevices(steam_path_);
input_redirector_.run(); input_redirector_.run();
#endif #endif
if (Settings::launch.launch) { if (Settings::launch.launch) {
@ -68,14 +77,15 @@ Application will not function!");
keepControllerConfig(true); keepControllerConfig(true);
while (run_) { while (run_) {
detector_.update(); detector_.update();
window_.update();
overlayHotkeyWorkaround(); overlayHotkeyWorkaround();
window_.update();
// Wait on shutdown; User might get confused if window closes to fast if anything with launchApp get's borked. // Wait on shutdown; User might get confused if window closes to fast if anything with launchApp get's borked.
if (delayed_shutdown_) { if (delayed_shutdown_) {
if (delay_shutdown_clock_.getElapsedTime().asSeconds() >= 3) { if (delay_shutdown_clock_.getElapsedTime().asSeconds() >= 3) {
run_ = false; run_ = false;
} }
} else { }
else {
launcher_.update(); launcher_.update();
} }
} }
@ -102,19 +112,20 @@ void SteamTarget::onOverlayChanged(bool overlay_open)
} }
else { else {
if (overlay_trigger_clock_.getElapsedTime().asSeconds() <= overlay_trigger_max_seconds_) { 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); window_.setClickThrough(!ov_opened);
if (ov_opened) { if (ov_opened) {
spdlog::info("Opened GlosSI-overlay"); spdlog::info("Opened GlosSI-overlay");
focusWindow(target_window_handle_); focusWindow(target_window_handle_);
} else { }
else {
focusWindow(last_foreground_window_); focusWindow(last_foreground_window_);
spdlog::info("Closed GlosSI-overlay"); spdlog::info("Closed GlosSI-overlay");
} }
} }
overlay_trigger_flag_ = false; overlay_trigger_flag_ = false;
} }
if (!overlay_.isEnabled()) { if (!( overlay_.expired() ? false : overlay_.lock()->isEnabled())) {
window_.setClickThrough(!overlay_open); window_.setClickThrough(!overlay_open);
focusWindow(last_foreground_window_); focusWindow(last_foreground_window_);
} }
@ -124,7 +135,6 @@ void SteamTarget::onOverlayChanged(bool overlay_open)
void SteamTarget::focusWindow(WindowHandle hndl) void SteamTarget::focusWindow(WindowHandle hndl)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (hndl == target_window_handle_) { if (hndl == target_window_handle_) {
spdlog::debug("Bring own window to foreground"); spdlog::debug("Bring own window to foreground");
} }
@ -136,7 +146,7 @@ void SteamTarget::focusWindow(WindowHandle hndl)
const auto current_fgw = GetForegroundWindow(); const auto current_fgw = GetForegroundWindow();
if (current_fgw != target_window_handle_) { if (current_fgw != target_window_handle_) {
last_foreground_window_ = current_fgw; last_foreground_window_ = current_fgw;
} }
const auto fg_thread = GetWindowThreadProcessId(current_fgw, nullptr); const auto fg_thread = GetWindowThreadProcessId(current_fgw, nullptr);
keepControllerConfig(true); // re-hook GetForegroundWindow keepControllerConfig(true); // re-hook GetForegroundWindow
@ -177,7 +187,7 @@ std::filesystem::path SteamTarget::getSteamPath() const
#endif #endif
} }
std::wstring SteamTarget::getSteamUserId() const std::wstring SteamTarget::getSteamUserId() const
{ {
#ifdef _WIN32 #ifdef _WIN32
// TODO: check if keys/value exist // TODO: check if keys/value exist

@ -75,7 +75,7 @@ class SteamTarget {
InputRedirector input_redirector_; InputRedirector input_redirector_;
#endif #endif
TargetWindow window_; TargetWindow window_;
Overlay& overlay_; std::weak_ptr<Overlay> overlay_;
SteamOverlayDetector detector_; SteamOverlayDetector detector_;
AppLauncher launcher_; AppLauncher launcher_;
WindowHandle last_foreground_window_ = nullptr; WindowHandle last_foreground_window_ = nullptr;

@ -36,68 +36,24 @@ limitations under the License.
#endif #endif
TargetWindow::TargetWindow(std::function<void()> on_close, std::vector<std::string> screenshot_hotkey) TargetWindow::TargetWindow(
std::function<void()> on_close,
std::vector<std::string> screenshot_hotkey,
std::function<void()> on_window_changed)
: on_close_(std::move(on_close)), : on_close_(std::move(on_close)),
screenshot_keys_(std::move(screenshot_hotkey)), screenshot_keys_(std::move(screenshot_hotkey)),
overlay_(window_, [this]() { close(); }) on_window_changed_(std::move(on_window_changed))
{ {
auto desktop_mode = sf::VideoMode::getDesktopMode(); createWindow(Settings::window.windowMode);
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();
}
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) void TargetWindow::setFpsLimit(unsigned int fps_limit)
@ -134,11 +90,17 @@ void TargetWindow::update()
return; return;
} }
} }
if (windowed_) {
window_.clear(sf::Color(0,0,0,0)); window_.clear(sf::Color(23, 23, 23, 255));
overlay_.update(); } else {
window_.clear(sf::Color(0, 0, 0, 0));
}
screenShotWorkaround(); screenShotWorkaround();
overlay_->update();
window_.display(); window_.display();
if (toggle_window_mode_after_frame_) {
createWindow(!windowed_);
}
} }
void TargetWindow::close() void TargetWindow::close()
@ -148,7 +110,7 @@ void TargetWindow::close()
on_close_(); on_close_();
} }
Overlay& TargetWindow::getOverlay() std::shared_ptr<Overlay> TargetWindow::getOverlay() const
{ {
return overlay_; return overlay_;
} }
@ -261,5 +223,79 @@ WORD TargetWindow::GetWindowDPI(HWND hWnd)
return static_cast<WORD>(iDpiX); return static_cast<WORD>(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<Overlay>(window_, [this]() { close(); }, windowed_);
ImGuiIO& io = ImGui::GetIO();
io.FontGlobalScale = dpi / 96.f;
ImGui::SFML::UpdateFontTexture();
#else
setFpsLimit(60);
#endif #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_();
}

@ -31,14 +31,17 @@ using WindowHandle = int; // ???
class TargetWindow { class TargetWindow {
public: public:
explicit TargetWindow( explicit TargetWindow(
std::function<void()> on_close = []() {}, std::vector<std::string> screenshot_hotkey = {"KEY_F12"}); std::function<void()> on_close = []() {},
std::vector<std::string> screenshot_hotkey = {"KEY_F12"},
std::function<void()> on_window_changed = []() {}
);
void setFpsLimit(unsigned int fps_limit); void setFpsLimit(unsigned int fps_limit);
void setClickThrough(bool click_through); void setClickThrough(bool click_through);
void update(); void update();
void close(); void close();
Overlay& getOverlay(); std::shared_ptr<Overlay> getOverlay() const;
/* /*
* Run once per frame * Run once per frame
@ -63,6 +66,13 @@ class TargetWindow {
const std::function<void()> on_close_; const std::function<void()> on_close_;
sf::RenderWindow window_; sf::RenderWindow window_;
std::vector<std::string> screenshot_keys_; std::vector<std::string> screenshot_keys_;
const std::function<void()> on_window_changed_;
Overlay overlay_;
std::shared_ptr<Overlay> overlay_;
void createWindow(bool window_mode);
bool windowed_ = false;
bool toggle_window_mode_after_frame_ = false;
}; };

@ -1,7 +1,7 @@
{ {
"version": 1, "version": 1,
"launch": { "launch": {
"launch": true, "launch": false,
"launchPath": "C:\\Users\\Alia5\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe", "launchPath": "C:\\Users\\Alia5\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe",
"launchAppArgs": "--new-window", "launchAppArgs": "--new-window",
"closeOnExit": true "closeOnExit": true

@ -73,10 +73,10 @@ int main(int argc, char* argv[])
logger->flush_on(spdlog::level::info); logger->flush_on(spdlog::level::info);
spdlog::set_default_logger(logger); spdlog::set_default_logger(logger);
#ifdef _WIN32 #ifdef _WIN32
Settings::Parse(__argv[1]); Settings::Parse(__argc > 1 ? __argv[1] : "");
SteamTarget target(__argc, __argv); SteamTarget target(__argc, __argv);
#else #else
Settings::Parse(argv[1]); Settings::Parse(argc > 1 ? argv[1] : "");
SteamTarget target(argc, argv); SteamTarget target(argc, argv);
#endif #endif
const auto exit = target.run(); const auto exit = target.run();

Loading…
Cancel
Save