mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-04-27 13:46:12 +08:00
[fix] fix Wayland keyboard capture by using SDL key events
This commit is contained in:
@@ -98,6 +98,7 @@ std::map<int, int> vkCodeToCGKeyCode = {
|
|||||||
{0x67, 0x59}, // Numpad 7
|
{0x67, 0x59}, // Numpad 7
|
||||||
{0x68, 0x5B}, // Numpad 8
|
{0x68, 0x5B}, // Numpad 8
|
||||||
{0x69, 0x5C}, // Numpad 9
|
{0x69, 0x5C}, // Numpad 9
|
||||||
|
{0x90, 0x47}, // Num Lock / Keypad Clear
|
||||||
{0x6E, 0x41}, // Numpad .
|
{0x6E, 0x41}, // Numpad .
|
||||||
{0x6F, 0x4B}, // Numpad /
|
{0x6F, 0x4B}, // Numpad /
|
||||||
{0x6A, 0x43}, // Numpad *
|
{0x6A, 0x43}, // Numpad *
|
||||||
@@ -216,6 +217,7 @@ std::map<int, int> CGKeyCodeToVkCode = {
|
|||||||
{0x59, 0x67}, // Numpad 7
|
{0x59, 0x67}, // Numpad 7
|
||||||
{0x5B, 0x68}, // Numpad 8
|
{0x5B, 0x68}, // Numpad 8
|
||||||
{0x5C, 0x69}, // Numpad 9
|
{0x5C, 0x69}, // Numpad 9
|
||||||
|
{0x47, 0x90}, // Num Lock / Keypad Clear
|
||||||
{0x41, 0x6E}, // Numpad .
|
{0x41, 0x6E}, // Numpad .
|
||||||
{0x4B, 0x6F}, // Numpad /
|
{0x4B, 0x6F}, // Numpad /
|
||||||
{0x43, 0x6A}, // Numpad *
|
{0x43, 0x6A}, // Numpad *
|
||||||
@@ -336,6 +338,7 @@ std::map<int, int> vkCodeToX11KeySym = {
|
|||||||
{0x67, 0xFFB7}, // Numpad 7
|
{0x67, 0xFFB7}, // Numpad 7
|
||||||
{0x68, 0xFFB8}, // Numpad 8
|
{0x68, 0xFFB8}, // Numpad 8
|
||||||
{0x69, 0xFFB9}, // Numpad 9
|
{0x69, 0xFFB9}, // Numpad 9
|
||||||
|
{0x90, 0xFF7F}, // Num Lock
|
||||||
{0x6E, 0xFFAE}, // Numpad .
|
{0x6E, 0xFFAE}, // Numpad .
|
||||||
{0x6F, 0xFFAF}, // Numpad /
|
{0x6F, 0xFFAF}, // Numpad /
|
||||||
{0x6A, 0xFFAA}, // Numpad *
|
{0x6A, 0xFFAA}, // Numpad *
|
||||||
@@ -464,6 +467,7 @@ std::map<int, int> x11KeySymToVkCode = {
|
|||||||
{0xFFB7, 0x67}, // Numpad 7
|
{0xFFB7, 0x67}, // Numpad 7
|
||||||
{0xFFB8, 0x68}, // Numpad 8
|
{0xFFB8, 0x68}, // Numpad 8
|
||||||
{0xFFB9, 0x69}, // Numpad 9
|
{0xFFB9, 0x69}, // Numpad 9
|
||||||
|
{0xFF7F, 0x90}, // Num Lock
|
||||||
{0xFFAE, 0x6E}, // Numpad .
|
{0xFFAE, 0x6E}, // Numpad .
|
||||||
{0xFFAF, 0x6F}, // Numpad /
|
{0xFFAF, 0x6F}, // Numpad /
|
||||||
{0xFFAA, 0x6A}, // Numpad *
|
{0xFFAA, 0x6A}, // Numpad *
|
||||||
@@ -582,6 +586,7 @@ std::map<int, int> cgKeyCodeToX11KeySym = {
|
|||||||
{0x59, 0xFFB7}, // Numpad 7
|
{0x59, 0xFFB7}, // Numpad 7
|
||||||
{0x5B, 0xFFB8}, // Numpad 8
|
{0x5B, 0xFFB8}, // Numpad 8
|
||||||
{0x5C, 0xFFB9}, // Numpad 9
|
{0x5C, 0xFFB9}, // Numpad 9
|
||||||
|
{0x47, 0xFF7F}, // Num Lock / Keypad Clear
|
||||||
{0x41, 0xFFAE}, // Numpad .
|
{0x41, 0xFFAE}, // Numpad .
|
||||||
{0x4B, 0xFFAF}, // Numpad /
|
{0x4B, 0xFFAF}, // Numpad /
|
||||||
{0x43, 0xFFAA}, // Numpad *
|
{0x43, 0xFFAA}, // Numpad *
|
||||||
@@ -708,6 +713,7 @@ std::map<int, int> x11KeySymToCgKeyCode = {
|
|||||||
{0xFFB7, 0x59}, // Numpad 7
|
{0xFFB7, 0x59}, // Numpad 7
|
||||||
{0xFFB8, 0x5B}, // Numpad 8
|
{0xFFB8, 0x5B}, // Numpad 8
|
||||||
{0xFFB9, 0x5C}, // Numpad 9
|
{0xFFB9, 0x5C}, // Numpad 9
|
||||||
|
{0xFF7F, 0x47}, // Num Lock / Keypad Clear
|
||||||
{0xFFAE, 0x41}, // Numpad .
|
{0xFFAE, 0x41}, // Numpad .
|
||||||
{0xFFAF, 0x4B}, // Numpad /
|
{0xFFAF, 0x4B}, // Numpad /
|
||||||
{0xFFAA, 0x43}, // Numpad *
|
{0xFFAA, 0x43}, // Numpad *
|
||||||
|
|||||||
+37
-13
@@ -98,8 +98,7 @@ RemoteAction BuildWindowsServiceStatusAction(
|
|||||||
action.ss.available = status.available;
|
action.ss.available = status.available;
|
||||||
std::strncpy(action.ss.interactive_stage, status.interactive_stage.c_str(),
|
std::strncpy(action.ss.interactive_stage, status.interactive_stage.c_str(),
|
||||||
sizeof(action.ss.interactive_stage) - 1);
|
sizeof(action.ss.interactive_stage) - 1);
|
||||||
action.ss.interactive_stage[sizeof(action.ss.interactive_stage) - 1] =
|
action.ss.interactive_stage[sizeof(action.ss.interactive_stage) - 1] = '\0';
|
||||||
'\0';
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,6 +794,13 @@ int Render::StopMouseController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Render::StartKeyboardCapturer() {
|
int Render::StartKeyboardCapturer() {
|
||||||
|
#if defined(__linux__) && !defined(__APPLE__)
|
||||||
|
if (IsWaylandSession()) {
|
||||||
|
LOG_INFO("Start keyboard capturer with SDL Wayland backend");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!keyboard_capturer_) {
|
if (!keyboard_capturer_) {
|
||||||
LOG_INFO("keyboard capturer is nullptr");
|
LOG_INFO("keyboard capturer is nullptr");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -818,6 +824,13 @@ int Render::StartKeyboardCapturer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Render::StopKeyboardCapturer() {
|
int Render::StopKeyboardCapturer() {
|
||||||
|
#if defined(__linux__) && !defined(__APPLE__)
|
||||||
|
if (IsWaylandSession()) {
|
||||||
|
LOG_INFO("Stop keyboard capturer with SDL Wayland backend");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (keyboard_capturer_) {
|
if (keyboard_capturer_) {
|
||||||
keyboard_capturer_->Unhook();
|
keyboard_capturer_->Unhook();
|
||||||
LOG_INFO("Stop keyboard capturer");
|
LOG_INFO("Stop keyboard capturer");
|
||||||
@@ -1883,19 +1896,18 @@ void Render::HandleWindowsServiceIntegration() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool has_connected_remote = std::any_of(
|
const bool has_connected_remote =
|
||||||
connection_status_.begin(), connection_status_.end(),
|
std::any_of(connection_status_.begin(), connection_status_.end(),
|
||||||
[](const auto& entry) {
|
[](const auto& entry) {
|
||||||
return entry.second == ConnectionStatus::Connected;
|
return entry.second == ConnectionStatus::Connected;
|
||||||
});
|
});
|
||||||
if (!has_connected_remote) {
|
if (!has_connected_remote) {
|
||||||
ResetLocalWindowsServiceState(false);
|
ResetLocalWindowsServiceState(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool force_broadcast = false;
|
bool force_broadcast = false;
|
||||||
if (pending_windows_service_sas_.exchange(false,
|
if (pending_windows_service_sas_.exchange(false, std::memory_order_relaxed)) {
|
||||||
std::memory_order_relaxed)) {
|
|
||||||
const std::string response =
|
const std::string response =
|
||||||
QueryCrossDeskService("sas", kWindowsServiceSasTimeoutMs);
|
QueryCrossDeskService("sas", kWindowsServiceSasTimeoutMs);
|
||||||
auto json = nlohmann::json::parse(response, nullptr, false);
|
auto json = nlohmann::json::parse(response, nullptr, false);
|
||||||
@@ -1931,10 +1943,12 @@ void Render::HandleWindowsServiceIntegration() {
|
|||||||
status.error_code != last_logged_service_error_code);
|
status.error_code != last_logged_service_error_code);
|
||||||
if (availability_changed || error_changed) {
|
if (availability_changed || error_changed) {
|
||||||
if (status.available) {
|
if (status.available) {
|
||||||
LOG_INFO("Local Windows service available for secure desktop integration");
|
LOG_INFO(
|
||||||
|
"Local Windows service available for secure desktop integration");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"Local Windows service unavailable, secure desktop integration disabled: error={}, code={}",
|
"Local Windows service unavailable, secure desktop integration "
|
||||||
|
"disabled: error={}, code={}",
|
||||||
status.error, status.error_code);
|
status.error, status.error_code);
|
||||||
}
|
}
|
||||||
last_logged_service_available = status.available;
|
last_logged_service_available = status.available;
|
||||||
@@ -1944,7 +1958,8 @@ void Render::HandleWindowsServiceIntegration() {
|
|||||||
} else if (last_logged_service_available ||
|
} else if (last_logged_service_available ||
|
||||||
last_logged_service_error != "invalid_service_status_json") {
|
last_logged_service_error != "invalid_service_status_json") {
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"Local Windows service status query failed, secure desktop integration disabled");
|
"Local Windows service status query failed, secure desktop integration "
|
||||||
|
"disabled");
|
||||||
last_logged_service_available = false;
|
last_logged_service_available = false;
|
||||||
last_logged_service_error = "invalid_service_status_json";
|
last_logged_service_error = "invalid_service_status_json";
|
||||||
last_logged_service_error_code = 0;
|
last_logged_service_error_code = 0;
|
||||||
@@ -2670,7 +2685,7 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
|
|||||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||||
if (stream_window_ &&
|
if (stream_window_ &&
|
||||||
SDL_GetWindowID(stream_window_) == event.window.windowID) {
|
SDL_GetWindowID(stream_window_) == event.window.windowID) {
|
||||||
ForceReleasePressedModifiers();
|
ForceReleasePressedKeys();
|
||||||
focus_on_stream_window_ = false;
|
focus_on_stream_window_ = false;
|
||||||
} else if (main_window_ &&
|
} else if (main_window_ &&
|
||||||
SDL_GetWindowID(main_window_) == event.window.windowID) {
|
SDL_GetWindowID(main_window_) == event.window.windowID) {
|
||||||
@@ -2702,6 +2717,15 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_EVENT_KEY_DOWN:
|
||||||
|
case SDL_EVENT_KEY_UP:
|
||||||
|
if (keyboard_capturer_is_started_ && focus_on_stream_window_ &&
|
||||||
|
stream_window_ &&
|
||||||
|
SDL_GetWindowID(stream_window_) == event.key.windowID) {
|
||||||
|
ProcessKeyboardEvent(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (event.type == STREAM_REFRESH_EVENT) {
|
if (event.type == STREAM_REFRESH_EVENT) {
|
||||||
auto* props = static_cast<SubStreamWindowProperties*>(event.user.data1);
|
auto* props = static_cast<SubStreamWindowProperties*>(event.user.data1);
|
||||||
|
|||||||
+6
-5
@@ -287,7 +287,7 @@ class Render {
|
|||||||
void ResetRemoteServiceStatus(SubStreamWindowProperties& props);
|
void ResetRemoteServiceStatus(SubStreamWindowProperties& props);
|
||||||
void ApplyRemoteServiceStatus(SubStreamWindowProperties& props,
|
void ApplyRemoteServiceStatus(SubStreamWindowProperties& props,
|
||||||
const ServiceStatus& status);
|
const ServiceStatus& status);
|
||||||
RemoteUnlockState GetRemoteUnlockState(
|
RemoteUnlockState GetRemoteUnlockState(
|
||||||
const SubStreamWindowProperties& props) const;
|
const SubStreamWindowProperties& props) const;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
int RequestPermissionWindow();
|
int RequestPermissionWindow();
|
||||||
@@ -342,8 +342,9 @@ class Render {
|
|||||||
private:
|
private:
|
||||||
int SendKeyCommand(int key_code, bool is_down);
|
int SendKeyCommand(int key_code, bool is_down);
|
||||||
static bool IsModifierVkKey(int key_code);
|
static bool IsModifierVkKey(int key_code);
|
||||||
void UpdatePressedModifierState(int key_code, bool is_down);
|
void TrackPressedKeyState(int key_code, bool is_down);
|
||||||
void ForceReleasePressedModifiers();
|
void ForceReleasePressedKeys();
|
||||||
|
int ProcessKeyboardEvent(const SDL_Event& event);
|
||||||
int ProcessMouseEvent(const SDL_Event& event);
|
int ProcessMouseEvent(const SDL_Event& event);
|
||||||
|
|
||||||
static void SdlCaptureAudioIn(void* userdata, Uint8* stream, int len);
|
static void SdlCaptureAudioIn(void* userdata, Uint8* stream, int len);
|
||||||
@@ -532,8 +533,8 @@ class Render {
|
|||||||
std::string controlled_remote_id_ = "";
|
std::string controlled_remote_id_ = "";
|
||||||
std::string focused_remote_id_ = "";
|
std::string focused_remote_id_ = "";
|
||||||
std::string remote_client_id_ = "";
|
std::string remote_client_id_ = "";
|
||||||
std::unordered_set<int> pressed_modifier_keys_;
|
std::unordered_set<int> pressed_keyboard_keys_;
|
||||||
std::mutex pressed_modifier_keys_mutex_;
|
std::mutex pressed_keyboard_keys_mutex_;
|
||||||
SDL_Event last_mouse_event;
|
SDL_Event last_mouse_event;
|
||||||
SDL_AudioStream* output_stream_;
|
SDL_AudioStream* output_stream_;
|
||||||
uint32_t STREAM_REFRESH_EVENT = 0;
|
uint32_t STREAM_REFRESH_EVENT = 0;
|
||||||
|
|||||||
+212
-21
@@ -28,6 +28,178 @@ namespace crossdesk {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
int TranslateSdlKeypadScancodeToVk(SDL_Scancode scancode) {
|
||||||
|
switch (scancode) {
|
||||||
|
case SDL_SCANCODE_NUMLOCKCLEAR:
|
||||||
|
return 0x90;
|
||||||
|
case SDL_SCANCODE_KP_ENTER:
|
||||||
|
return 0x0D;
|
||||||
|
case SDL_SCANCODE_KP_0:
|
||||||
|
return 0x60;
|
||||||
|
case SDL_SCANCODE_KP_1:
|
||||||
|
return 0x61;
|
||||||
|
case SDL_SCANCODE_KP_2:
|
||||||
|
return 0x62;
|
||||||
|
case SDL_SCANCODE_KP_3:
|
||||||
|
return 0x63;
|
||||||
|
case SDL_SCANCODE_KP_4:
|
||||||
|
return 0x64;
|
||||||
|
case SDL_SCANCODE_KP_5:
|
||||||
|
return 0x65;
|
||||||
|
case SDL_SCANCODE_KP_6:
|
||||||
|
return 0x66;
|
||||||
|
case SDL_SCANCODE_KP_7:
|
||||||
|
return 0x67;
|
||||||
|
case SDL_SCANCODE_KP_8:
|
||||||
|
return 0x68;
|
||||||
|
case SDL_SCANCODE_KP_9:
|
||||||
|
return 0x69;
|
||||||
|
case SDL_SCANCODE_KP_PERIOD:
|
||||||
|
case SDL_SCANCODE_KP_COMMA:
|
||||||
|
return 0x6E;
|
||||||
|
case SDL_SCANCODE_KP_DIVIDE:
|
||||||
|
return 0x6F;
|
||||||
|
case SDL_SCANCODE_KP_MULTIPLY:
|
||||||
|
return 0x6A;
|
||||||
|
case SDL_SCANCODE_KP_MINUS:
|
||||||
|
return 0x6D;
|
||||||
|
case SDL_SCANCODE_KP_PLUS:
|
||||||
|
return 0x6B;
|
||||||
|
case SDL_SCANCODE_KP_EQUALS:
|
||||||
|
return 0xBB;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TranslateSdlKeyboardEventToVk(const SDL_KeyboardEvent& event) {
|
||||||
|
const int keypad_key_code = TranslateSdlKeypadScancodeToVk(event.scancode);
|
||||||
|
if (keypad_key_code >= 0) {
|
||||||
|
return keypad_key_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int key = static_cast<int>(event.key);
|
||||||
|
if (key >= 'a' && key <= 'z') {
|
||||||
|
return key - 'a' + 0x41;
|
||||||
|
}
|
||||||
|
if (key >= 'A' && key <= 'Z') {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
if (key >= '0' && key <= '9') {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case ';':
|
||||||
|
return 0xBA;
|
||||||
|
case '\'':
|
||||||
|
return 0xDE;
|
||||||
|
case '`':
|
||||||
|
return 0xC0;
|
||||||
|
case ',':
|
||||||
|
return 0xBC;
|
||||||
|
case '.':
|
||||||
|
return 0xBE;
|
||||||
|
case '/':
|
||||||
|
return 0xBF;
|
||||||
|
case '\\':
|
||||||
|
return 0xDC;
|
||||||
|
case '[':
|
||||||
|
return 0xDB;
|
||||||
|
case ']':
|
||||||
|
return 0xDD;
|
||||||
|
case '-':
|
||||||
|
return 0xBD;
|
||||||
|
case '=':
|
||||||
|
return 0xBB;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.scancode) {
|
||||||
|
case SDL_SCANCODE_ESCAPE:
|
||||||
|
return 0x1B;
|
||||||
|
case SDL_SCANCODE_RETURN:
|
||||||
|
return 0x0D;
|
||||||
|
case SDL_SCANCODE_SPACE:
|
||||||
|
return 0x20;
|
||||||
|
case SDL_SCANCODE_BACKSPACE:
|
||||||
|
return 0x08;
|
||||||
|
case SDL_SCANCODE_TAB:
|
||||||
|
return 0x09;
|
||||||
|
case SDL_SCANCODE_PRINTSCREEN:
|
||||||
|
return 0x2C;
|
||||||
|
case SDL_SCANCODE_SCROLLLOCK:
|
||||||
|
return 0x91;
|
||||||
|
case SDL_SCANCODE_PAUSE:
|
||||||
|
return 0x13;
|
||||||
|
case SDL_SCANCODE_INSERT:
|
||||||
|
return 0x2D;
|
||||||
|
case SDL_SCANCODE_DELETE:
|
||||||
|
return 0x2E;
|
||||||
|
case SDL_SCANCODE_HOME:
|
||||||
|
return 0x24;
|
||||||
|
case SDL_SCANCODE_END:
|
||||||
|
return 0x23;
|
||||||
|
case SDL_SCANCODE_PAGEUP:
|
||||||
|
return 0x21;
|
||||||
|
case SDL_SCANCODE_PAGEDOWN:
|
||||||
|
return 0x22;
|
||||||
|
case SDL_SCANCODE_LEFT:
|
||||||
|
return 0x25;
|
||||||
|
case SDL_SCANCODE_RIGHT:
|
||||||
|
return 0x27;
|
||||||
|
case SDL_SCANCODE_UP:
|
||||||
|
return 0x26;
|
||||||
|
case SDL_SCANCODE_DOWN:
|
||||||
|
return 0x28;
|
||||||
|
case SDL_SCANCODE_F1:
|
||||||
|
return 0x70;
|
||||||
|
case SDL_SCANCODE_F2:
|
||||||
|
return 0x71;
|
||||||
|
case SDL_SCANCODE_F3:
|
||||||
|
return 0x72;
|
||||||
|
case SDL_SCANCODE_F4:
|
||||||
|
return 0x73;
|
||||||
|
case SDL_SCANCODE_F5:
|
||||||
|
return 0x74;
|
||||||
|
case SDL_SCANCODE_F6:
|
||||||
|
return 0x75;
|
||||||
|
case SDL_SCANCODE_F7:
|
||||||
|
return 0x76;
|
||||||
|
case SDL_SCANCODE_F8:
|
||||||
|
return 0x77;
|
||||||
|
case SDL_SCANCODE_F9:
|
||||||
|
return 0x78;
|
||||||
|
case SDL_SCANCODE_F10:
|
||||||
|
return 0x79;
|
||||||
|
case SDL_SCANCODE_F11:
|
||||||
|
return 0x7A;
|
||||||
|
case SDL_SCANCODE_F12:
|
||||||
|
return 0x7B;
|
||||||
|
case SDL_SCANCODE_CAPSLOCK:
|
||||||
|
return 0x14;
|
||||||
|
case SDL_SCANCODE_LSHIFT:
|
||||||
|
return 0xA0;
|
||||||
|
case SDL_SCANCODE_RSHIFT:
|
||||||
|
return 0xA1;
|
||||||
|
case SDL_SCANCODE_LCTRL:
|
||||||
|
return 0xA2;
|
||||||
|
case SDL_SCANCODE_RCTRL:
|
||||||
|
return 0xA3;
|
||||||
|
case SDL_SCANCODE_LALT:
|
||||||
|
return 0xA4;
|
||||||
|
case SDL_SCANCODE_RALT:
|
||||||
|
return 0xA5;
|
||||||
|
case SDL_SCANCODE_LGUI:
|
||||||
|
return 0x5B;
|
||||||
|
case SDL_SCANCODE_RGUI:
|
||||||
|
return 0x5C;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
constexpr uint32_t kSecureDesktopInputLogIntervalMs = 2000;
|
constexpr uint32_t kSecureDesktopInputLogIntervalMs = 2000;
|
||||||
|
|
||||||
@@ -36,8 +208,7 @@ bool BuildAbsoluteMousePosition(const std::vector<DisplayInfo>& displays,
|
|||||||
float normalized_y, int* absolute_x_out,
|
float normalized_y, int* absolute_x_out,
|
||||||
int* absolute_y_out) {
|
int* absolute_y_out) {
|
||||||
if (absolute_x_out == nullptr || absolute_y_out == nullptr ||
|
if (absolute_x_out == nullptr || absolute_y_out == nullptr ||
|
||||||
display_index < 0 ||
|
display_index < 0 || display_index >= static_cast<int>(displays.size())) {
|
||||||
display_index >= static_cast<int>(displays.size())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,29 +323,29 @@ bool Render::IsModifierVkKey(int key_code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render::UpdatePressedModifierState(int key_code, bool is_down) {
|
void Render::TrackPressedKeyState(int key_code, bool is_down) {
|
||||||
if (!IsModifierVkKey(key_code)) {
|
if (!IsWaylandSession() && !IsModifierVkKey(key_code)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(pressed_modifier_keys_mutex_);
|
std::lock_guard<std::mutex> lock(pressed_keyboard_keys_mutex_);
|
||||||
if (is_down) {
|
if (is_down) {
|
||||||
pressed_modifier_keys_.insert(key_code);
|
pressed_keyboard_keys_.insert(key_code);
|
||||||
} else {
|
} else {
|
||||||
pressed_modifier_keys_.erase(key_code);
|
pressed_keyboard_keys_.erase(key_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render::ForceReleasePressedModifiers() {
|
void Render::ForceReleasePressedKeys() {
|
||||||
std::vector<int> pressed_keys;
|
std::vector<int> pressed_keys;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(pressed_modifier_keys_mutex_);
|
std::lock_guard<std::mutex> lock(pressed_keyboard_keys_mutex_);
|
||||||
if (pressed_modifier_keys_.empty()) {
|
if (pressed_keyboard_keys_.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pressed_keys.assign(pressed_modifier_keys_.begin(),
|
pressed_keys.assign(pressed_keyboard_keys_.begin(),
|
||||||
pressed_modifier_keys_.end());
|
pressed_keyboard_keys_.end());
|
||||||
pressed_modifier_keys_.clear();
|
pressed_keyboard_keys_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int key_code : pressed_keys) {
|
for (int key_code : pressed_keys) {
|
||||||
@@ -210,11 +381,28 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePressedModifierState(key_code, is_down);
|
TrackPressedKeyState(key_code, is_down);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Render::ProcessKeyboardEvent(const SDL_Event& event) {
|
||||||
|
if (event.type != SDL_EVENT_KEY_DOWN && event.type != SDL_EVENT_KEY_UP) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int key_code = TranslateSdlKeyboardEventToVk(event.key);
|
||||||
|
if (key_code < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SendKeyCommand(key_code, event.type == SDL_EVENT_KEY_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
int Render::ProcessMouseEvent(const SDL_Event& event) {
|
int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||||
controlled_remote_id_ = "";
|
controlled_remote_id_ = "";
|
||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
@@ -292,7 +480,8 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_pointer_position_event && cursor_x >= render_rect.x &&
|
if (is_pointer_position_event && cursor_x >= render_rect.x &&
|
||||||
cursor_x <= render_rect.x + render_rect.w && cursor_y >= render_rect.y &&
|
cursor_x <= render_rect.x + render_rect.w &&
|
||||||
|
cursor_y >= render_rect.y &&
|
||||||
cursor_y <= render_rect.y + render_rect.h) {
|
cursor_y <= render_rect.y + render_rect.h) {
|
||||||
controlled_remote_id_ = it.first;
|
controlled_remote_id_ = it.first;
|
||||||
last_mouse_event.motion.x = cursor_x;
|
last_mouse_event.motion.x = cursor_x;
|
||||||
@@ -827,9 +1016,9 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
remote_action.m.x, remote_action.m.y,
|
remote_action.m.x, remote_action.m.y,
|
||||||
&absolute_x, &absolute_y)) {
|
&absolute_x, &absolute_y)) {
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"Secure desktop mouse injection skipped, invalid display mapping: display_index={}, x={}, y={}",
|
"Secure desktop mouse injection skipped, invalid display "
|
||||||
render->selected_display_, remote_action.m.x,
|
"mapping: display_index={}, x={}, y={}",
|
||||||
remote_action.m.y);
|
render->selected_display_, remote_action.m.x, remote_action.m.y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,7 +1031,8 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
&render->last_local_secure_input_block_log_tick_, "local",
|
&render->last_local_secure_input_block_log_tick_, "local",
|
||||||
render->local_interactive_stage_.c_str());
|
render->local_interactive_stage_.c_str());
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"Secure desktop mouse injection failed, x={}, y={}, wheel={}, flag={}, response={}",
|
"Secure desktop mouse injection failed, x={}, y={}, wheel={}, "
|
||||||
|
"flag={}, response={}",
|
||||||
absolute_x, absolute_y, remote_action.m.s,
|
absolute_x, absolute_y, remote_action.m.s,
|
||||||
static_cast<int>(remote_action.m.flag), response);
|
static_cast<int>(remote_action.m.flag), response);
|
||||||
}
|
}
|
||||||
@@ -1153,8 +1343,9 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
// Keep Wayland capture session warm to avoid black screen on
|
// Keep Wayland capture session warm to avoid black screen on
|
||||||
// subsequent reconnects.
|
// subsequent reconnects.
|
||||||
render->start_screen_capturer_ = true;
|
render->start_screen_capturer_ = true;
|
||||||
LOG_INFO("Keeping Wayland screen capturer running after "
|
LOG_INFO(
|
||||||
"disconnect to preserve reconnect stability");
|
"Keeping Wayland screen capturer running after "
|
||||||
|
"disconnect to preserve reconnect stability");
|
||||||
} else {
|
} else {
|
||||||
render->start_screen_capturer_ = false;
|
render->start_screen_capturer_ = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user