From 32345f93bf6ca69d9e1fb32a0d730a6d7dd76f5f Mon Sep 17 00:00:00 2001 From: dijunkun Date: Thu, 28 May 2026 04:22:14 +0800 Subject: [PATCH] [fix] validate macOS input display state before injecting events --- .../keyboard/mac/keyboard_capturer.cpp | 4 + .../mouse/mac/mouse_controller.cpp | 161 ++++++++++-------- src/gui/render_callback.cpp | 9 +- 3 files changed, 100 insertions(+), 74 deletions(-) diff --git a/src/device_controller/keyboard/mac/keyboard_capturer.cpp b/src/device_controller/keyboard/mac/keyboard_capturer.cpp index 7de0496..dc6ac0d 100644 --- a/src/device_controller/keyboard/mac/keyboard_capturer.cpp +++ b/src/device_controller/keyboard/mac/keyboard_capturer.cpp @@ -310,6 +310,10 @@ int KeyboardCapturer::SendKeyboardCommand(int key_code, bool is_down, if (IsFunctionKey(cg_key_code) && !is_down) { CGEventRef fn_release_event = CGEventCreateKeyboardEvent(NULL, fn_key_code_, false); + if (!fn_release_event) { + LOG_ERROR("CGEventCreateKeyboardEvent failed for fn release"); + return -1; + } CGEventPost(kCGHIDEventTap, fn_release_event); CFRelease(fn_release_event); } diff --git a/src/device_controller/mouse/mac/mouse_controller.cpp b/src/device_controller/mouse/mac/mouse_controller.cpp index 11b270a..ddbf635 100644 --- a/src/device_controller/mouse/mac/mouse_controller.cpp +++ b/src/device_controller/mouse/mac/mouse_controller.cpp @@ -1,6 +1,7 @@ #include "mouse_controller.h" #include +#include #include "rd_log.h" @@ -20,85 +21,101 @@ int MouseController::Destroy() { return 0; } int MouseController::SendMouseCommand(RemoteAction remote_action, int display_index) { + if (remote_action.type != ControlType::mouse) { + return 0; + } + + if (display_index < 0 || + display_index >= static_cast(display_info_list_.size())) { + LOG_WARN("Mouse command skipped, invalid display_index={}, displays={}", + display_index, display_info_list_.size()); + return -1; + } + + const DisplayInfo& display_info = display_info_list_[display_index]; + if (display_info.width <= 0 || display_info.height <= 0) { + LOG_WARN("Mouse command skipped, invalid display geometry: {}x{}", + display_info.width, display_info.height); + return -1; + } + + const float normalized_x = std::clamp(remote_action.m.x, 0.0f, 1.0f); + const float normalized_y = std::clamp(remote_action.m.y, 0.0f, 1.0f); int mouse_pos_x = - remote_action.m.x * display_info_list_[display_index].width + - display_info_list_[display_index].left; + normalized_x * display_info.width + display_info.left; int mouse_pos_y = - remote_action.m.y * display_info_list_[display_index].height + - display_info_list_[display_index].top; + normalized_y * display_info.height + display_info.top; - if (remote_action.type == ControlType::mouse) { - CGEventRef mouse_event = nullptr; - CGEventType mouse_type; - CGMouseButton mouse_button; - CGPoint mouse_point = CGPointMake(mouse_pos_x, mouse_pos_y); + CGEventRef mouse_event = nullptr; + CGEventType mouse_type; + CGMouseButton mouse_button; + CGPoint mouse_point = CGPointMake(mouse_pos_x, mouse_pos_y); - switch (remote_action.m.flag) { - case MouseFlag::left_down: - mouse_type = kCGEventLeftMouseDown; - left_dragging_ = true; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonLeft); - break; - case MouseFlag::left_up: - mouse_type = kCGEventLeftMouseUp; - left_dragging_ = false; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonLeft); - break; - case MouseFlag::right_down: - mouse_type = kCGEventRightMouseDown; - right_dragging_ = true; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonRight); - break; - case MouseFlag::right_up: - mouse_type = kCGEventRightMouseUp; - right_dragging_ = false; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonRight); - break; - case MouseFlag::middle_down: - mouse_type = kCGEventOtherMouseDown; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonCenter); - break; - case MouseFlag::middle_up: - mouse_type = kCGEventOtherMouseUp; - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - kCGMouseButtonCenter); - break; - case MouseFlag::wheel_vertical: - mouse_event = CGEventCreateScrollWheelEvent( - NULL, kCGScrollEventUnitLine, 2, remote_action.m.s, 0); - break; - case MouseFlag::wheel_horizontal: - mouse_event = CGEventCreateScrollWheelEvent( - NULL, kCGScrollEventUnitLine, 2, 0, remote_action.m.s); - break; - default: - if (left_dragging_) { - mouse_type = kCGEventLeftMouseDragged; - mouse_button = kCGMouseButtonLeft; - } else if (right_dragging_) { - mouse_type = kCGEventRightMouseDragged; - mouse_button = kCGMouseButtonRight; - } else { - mouse_type = kCGEventMouseMoved; - mouse_button = kCGMouseButtonLeft; - } + switch (remote_action.m.flag) { + case MouseFlag::left_down: + mouse_type = kCGEventLeftMouseDown; + left_dragging_ = true; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonLeft); + break; + case MouseFlag::left_up: + mouse_type = kCGEventLeftMouseUp; + left_dragging_ = false; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonLeft); + break; + case MouseFlag::right_down: + mouse_type = kCGEventRightMouseDown; + right_dragging_ = true; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonRight); + break; + case MouseFlag::right_up: + mouse_type = kCGEventRightMouseUp; + right_dragging_ = false; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonRight); + break; + case MouseFlag::middle_down: + mouse_type = kCGEventOtherMouseDown; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonCenter); + break; + case MouseFlag::middle_up: + mouse_type = kCGEventOtherMouseUp; + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + kCGMouseButtonCenter); + break; + case MouseFlag::wheel_vertical: + mouse_event = CGEventCreateScrollWheelEvent( + NULL, kCGScrollEventUnitLine, 2, remote_action.m.s, 0); + break; + case MouseFlag::wheel_horizontal: + mouse_event = CGEventCreateScrollWheelEvent( + NULL, kCGScrollEventUnitLine, 2, 0, remote_action.m.s); + break; + default: + if (left_dragging_) { + mouse_type = kCGEventLeftMouseDragged; + mouse_button = kCGMouseButtonLeft; + } else if (right_dragging_) { + mouse_type = kCGEventRightMouseDragged; + mouse_button = kCGMouseButtonRight; + } else { + mouse_type = kCGEventMouseMoved; + mouse_button = kCGMouseButtonLeft; + } - mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, - mouse_button); - break; - } + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, + mouse_button); + break; + } - if (mouse_event) { - CGEventPost(kCGHIDEventTap, mouse_event); - CFRelease(mouse_event); - } + if (mouse_event) { + CGEventPost(kCGHIDEventTap, mouse_event); + CFRelease(mouse_event); } return 0; } -} // namespace crossdesk \ No newline at end of file +} // namespace crossdesk diff --git a/src/gui/render_callback.cpp b/src/gui/render_callback.cpp index 8d6bcb5..202e533 100644 --- a/src/gui/render_callback.cpp +++ b/src/gui/render_callback.cpp @@ -1196,8 +1196,13 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size, remote_action.k.extended); } else if (remote_action.type == ControlType::display_id && render->screen_capturer_) { - render->selected_display_ = remote_action.d; - render->screen_capturer_->SwitchTo(remote_action.d); + const int ret = render->screen_capturer_->SwitchTo(remote_action.d); + if (ret == 0) { + render->selected_display_ = remote_action.d; + } else { + LOG_WARN("Display switch skipped, invalid display_id={}", + remote_action.d); + } } } }