[fix] release pressed modifier keys when stream window loses focus

This commit is contained in:
dijunkun
2026-03-23 21:33:01 +08:00
parent 83cacf6f51
commit 21b179e01c
3 changed files with 58 additions and 0 deletions

View File

@@ -2455,6 +2455,7 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
case SDL_EVENT_WINDOW_FOCUS_LOST:
if (stream_window_ &&
SDL_GetWindowID(stream_window_) == event.window.windowID) {
ForceReleasePressedModifiers();
focus_on_stream_window_ = false;
} else if (main_window_ &&
SDL_GetWindowID(main_window_) == event.window.windowID) {

View File

@@ -20,6 +20,7 @@
#include <shared_mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "IconsFontAwesome6.h"
@@ -322,6 +323,9 @@ class Render {
private:
int SendKeyCommand(int key_code, bool is_down);
static bool IsModifierVkKey(int key_code);
void UpdatePressedModifierState(int key_code, bool is_down);
void ForceReleasePressedModifiers();
int ProcessMouseEvent(const SDL_Event& event);
static void SdlCaptureAudioIn(void* userdata, Uint8* stream, int len);
@@ -506,6 +510,8 @@ class Render {
std::string controlled_remote_id_ = "";
std::string focused_remote_id_ = "";
std::string remote_client_id_ = "";
std::unordered_set<int> pressed_modifier_keys_;
std::mutex pressed_modifier_keys_mutex_;
SDL_Event last_mouse_event;
SDL_AudioStream* output_stream_;
uint32_t STREAM_REFRESH_EVENT = 0;

View File

@@ -81,6 +81,55 @@ void Render::OnSignalMessageCb(const char* message, size_t size,
}
}
bool Render::IsModifierVkKey(int key_code) {
switch (key_code) {
case 0x10: // VK_SHIFT
case 0x11: // VK_CONTROL
case 0x12: // VK_MENU(ALT)
case 0x5B: // VK_LWIN
case 0x5C: // VK_RWIN
case 0xA0: // VK_LSHIFT
case 0xA1: // VK_RSHIFT
case 0xA2: // VK_LCONTROL
case 0xA3: // VK_RCONTROL
case 0xA4: // VK_LMENU
case 0xA5: // VK_RMENU
return true;
default:
return false;
}
}
void Render::UpdatePressedModifierState(int key_code, bool is_down) {
if (!IsModifierVkKey(key_code)) {
return;
}
std::lock_guard<std::mutex> lock(pressed_modifier_keys_mutex_);
if (is_down) {
pressed_modifier_keys_.insert(key_code);
} else {
pressed_modifier_keys_.erase(key_code);
}
}
void Render::ForceReleasePressedModifiers() {
std::vector<int> pressed_keys;
{
std::lock_guard<std::mutex> lock(pressed_modifier_keys_mutex_);
if (pressed_modifier_keys_.empty()) {
return;
}
pressed_keys.assign(pressed_modifier_keys_.begin(),
pressed_modifier_keys_.end());
pressed_modifier_keys_.clear();
}
for (int key_code : pressed_keys) {
SendKeyCommand(key_code, false);
}
}
int Render::SendKeyCommand(int key_code, bool is_down) {
RemoteAction remote_action;
remote_action.type = ControlType::keyboard;
@@ -109,6 +158,8 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
}
}
UpdatePressedModifierState(key_code, is_down);
return 0;
}