From 37426bac82a7f440f03cfa80cbd6f24505444bde Mon Sep 17 00:00:00 2001 From: otavepto Date: Tue, 12 Mar 2024 00:25:47 +0200 Subject: [PATCH] allow notifications of these types to steal input focus: notification_type_message notification_type_invite --- CHANGELOG.md | 9 +++ overlay_experimental/overlay/steam_overlay.h | 2 +- overlay_experimental/steam_overlay.cpp | 61 ++++++++++++++++---- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4db304a4..da48052d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 2024/3/11 +* manage overlay cursor input/clipping and internal frame processing in a better way, + should prevent more games from pausing to display notifications +* allow notifications of these types to steal/obscure input: + - `notification_type_message` + - `notification_type_invite` + +--- + # 2024/3/9 * prevent notifications that do not require interaction from stealing focus diff --git a/overlay_experimental/overlay/steam_overlay.h b/overlay_experimental/overlay/steam_overlay.h index 1c8c2c5e..ba782132 100644 --- a/overlay_experimental/overlay/steam_overlay.h +++ b/overlay_experimental/overlay/steam_overlay.h @@ -148,7 +148,7 @@ class Steam_Overlay // changed each time a notification is posted or overlay is shown/hidden std::atomic_uint32_t renderer_frame_processing_requests = 0; // changed only when overlay is shown/hidden, true means overlay is shown - std::atomic_bool obscure_cursor_requests = false; + std::atomic_uint32_t obscure_cursor_requests = 0; constexpr static const int renderer_detector_polling_ms = 100; std::future future_renderer{}; diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index a0bf394c..9b2430f9 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -442,16 +442,21 @@ void Steam_Overlay::allow_renderer_frame_processing(bool state, bool cleaning_up } void Steam_Overlay::obscure_cursor_input(bool state) { - bool opposite_request = !state; - if (obscure_cursor_requests.compare_exchange_weak(opposite_request, state)) { // if we have the opposite state - if (state) { + if (state) { + auto new_val = ++obscure_cursor_requests; + if (new_val == 1) { // only take an action on first request // clip the cursor _renderer->HideAppInputs(true); - PRINT_DEBUG("Steam_Overlay::obscure_cursor_input obscured app input\n"); - } else { - // restore the old cursor - _renderer->HideAppInputs(false); - PRINT_DEBUG("Steam_Overlay::obscure_cursor_input restored app input\n"); + PRINT_DEBUG("Steam_Overlay::obscure_cursor_input obscured app input (count=%u)\n", new_val); + } + } else { + if (obscure_cursor_requests > 0) { + auto new_val = --obscure_cursor_requests; + if (!new_val) { // only take an action when the requests reach 0 + // restore the old cursor + _renderer->HideAppInputs(false); + PRINT_DEBUG("Steam_Overlay::obscure_cursor_input restored app input (count=%u)\n", new_val); + } } } } @@ -559,7 +564,24 @@ bool Steam_Overlay::submit_notification(notification_type type, const std::strin notif.icon = icon; notifications.emplace_back(notif); - Steam_Overlay::allow_renderer_frame_processing(true); + allow_renderer_frame_processing(true); + switch (type) { + // we want to steal focus for these ones + case notification_type_message: + case notification_type_invite: + obscure_cursor_input(true); + break; + + // not effective + case notification_type_achievement: + case notification_type_auto_accept_invite: + // nothing + break; + + default: + PRINT_DEBUG("Steam_Overlay::submit_notification error unhandled type %i\n", (int)type); + break; + } return true; } @@ -923,10 +945,29 @@ void Steam_Overlay::build_notifications(int width, int height) // erase all notifications whose visible time exceeded the max notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [this, &now](Notification &item) { if ((now - item.start_time) > Notification::show_time) { - PRINT_DEBUG("Steam_Overlay::build_notifications will disable frame processing after removing a notification\n"); + PRINT_DEBUG("Steam_Overlay::build_notifications removing a notification\n"); allow_renderer_frame_processing(false); + switch (item.type) { + // we want to restore focus for these ones + case notification_type_message: + case notification_type_invite: + obscure_cursor_input(false); + break; + + // not effective + case notification_type_achievement: + case notification_type_auto_accept_invite: + // nothing + break; + + default: + PRINT_DEBUG("Steam_Overlay::build_notifications error unhandled remove for type %i\n", (int)item.type); + break; + } + return true; } + return false; }), notifications.end());