[fix] route unelevated Windows input through service

This commit is contained in:
kunkundi
2026-10-09 16:33:51 +08:00
parent 5a7e816fb7
commit 055d8424a6
8 changed files with 76 additions and 12 deletions
@@ -17,6 +17,7 @@
#include "desktop_transition_policy.h"
#include "interactive_state.h"
#include "service_host.h"
#include "unattended_config.h"
#endif
namespace crossdesk {
@@ -205,7 +206,12 @@ void GuiRuntime::HandleWindowsServiceIntegration() {
status.interactive_stage == "user-desktop";
local_service_status_received_ =
status_ok || previous_secure_desktop_interaction;
local_service_available_ = status.available;
const bool service_was_available =
local_service_available_.exchange(status.available);
if (status.available && !service_was_available && !IsAdministratorProcess()) {
LOG_INFO("Unelevated host input routed through Windows service, including "
"elevated applications on the user desktop");
}
if (status.available) {
if (keep_optimistic_secure_desktop) {
local_interactive_stage_ = "secure-desktop";
@@ -19,6 +19,18 @@ inline bool PreferUserDesktopInput(bool user_desktop_active,
return user_desktop_active && !consent_ui_visible;
}
inline bool PreferUserDesktopInput(bool user_desktop_active,
bool consent_ui_visible,
bool service_available,
bool process_elevated) {
// An elevated application still lives on Default. SendInput only reports
// insertion into the input stream, not delivery to that application's UI.
// Use the authorized service proactively for an unelevated host, including
// clicks on an elevated window that has not become the foreground window.
return PreferUserDesktopInput(user_desktop_active, consent_ui_visible) &&
(process_elevated || !service_available);
}
inline bool IsDesktopInputSetupPending(const std::string& error) {
// These failures explicitly precede injection; timeouts remain ambiguous.
return error == "secure_input_helper_not_ready" ||
@@ -1250,6 +1250,7 @@ LONG NormalizeAbsoluteMouseCoordinate(int value, int origin, int size) {
INPUT BuildAbsoluteMouseMoveInput(int x, int y) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwExtraInfo = crossdesk::kInjectedMouseInputMarker;
const int virtual_left = GetSystemMetrics(SM_XVIRTUALSCREEN);
const int virtual_top = GetSystemMetrics(SM_YVIRTUALSCREEN);
@@ -1283,6 +1284,7 @@ InputInjectionResult InjectMouseInput(const SecureMouseRequest& request) {
INPUT action_input = {0};
action_input.type = INPUT_MOUSE;
action_input.mi.dwExtraInfo = crossdesk::kInjectedMouseInputMarker;
switch (request.flag) {
case 0:
break;