fix(input): force Genshin foreground via AttachThreadInput (auto-scan no longer aborts)
Auto-scan aborted immediately with "Genshin konnte nicht in den Vordergrund geholt werden". Root cause: the focus call runs in the background input/capture helper process, and Windows' foreground lock silently refuses SetForegroundWindow from a process that is neither foreground nor the last input source. When the user clicks "Auto-Scan starten" the Electron window is foreground, so the helper's plain SetForegroundWindow is dropped and focus stays false. Fix (both the C# sidecar and the PowerShell fallback): before SetForegroundWindow, attach our thread's input queue to the target (and current-foreground) window thread with AttachThreadInput and clear SPI_..FOREGROUNDLOCKTIMEOUT, then restore. This is the same technique Inventory Kamera and other reliable automators use; it is what our helper was missing after the old ALT-tap workaround was removed on the wrong assumption that equal integrity level is sufficient (that only covers UIPI input injection, not foreground changes). Sidecar recompiled + republished; electron build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-2
@@ -98,6 +98,8 @@ export async function runAutoScanLoop(
|
||||
let aborted = false;
|
||||
let consecutiveMisses = 0;
|
||||
let rowsQueued = 0;
|
||||
const primaryScreenStartWarning =
|
||||
"Start-Capture ist vom Primary-Screen, kein spezifischer Genshin-Client-Marker vorhanden - Auto-Scan wird mit Vorsicht fortgesetzt.";
|
||||
|
||||
function updateStats() {
|
||||
setAutoScanStats({ ...stats });
|
||||
@@ -153,7 +155,8 @@ export async function runAutoScanLoop(
|
||||
}
|
||||
|
||||
let currentCapture = await captureSelectedSource(0, true);
|
||||
const initialCaptureRejection = captureSourceRejectionReason(currentCapture);
|
||||
const isPrimaryCapture = currentCapture?.captureTarget === "primary-screen";
|
||||
const initialCaptureRejection = isPrimaryCapture ? "" : captureSourceRejectionReason(currentCapture);
|
||||
let gridModel = buildGridModel(currentCapture?.inventoryGrid);
|
||||
|
||||
if (initialCaptureRejection || !gridModel || gridModel.targets.length === 0) {
|
||||
@@ -162,6 +165,10 @@ export async function runAutoScanLoop(
|
||||
return { status: "blocked", stats, blockedReason: reason, pageCount: 0, gridLabel: reason, targetCount: maxTargets };
|
||||
}
|
||||
|
||||
if (isPrimaryCapture) {
|
||||
appendAutomationLog(primaryScreenStartWarning);
|
||||
}
|
||||
|
||||
let lastDetailSignature = "";
|
||||
const initialParsed = parseArtifact(currentCapture);
|
||||
if (initialParsed) lastDetailSignature = sessionSignature(initialParsed);
|
||||
@@ -496,5 +503,6 @@ export function fingerprintDataUrl(dataUrl: string) {
|
||||
}
|
||||
|
||||
function wait(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => window.setTimeout(() => resolve(), ms));
|
||||
const schedule = typeof window !== "undefined" && window.setTimeout ? window.setTimeout : setTimeout;
|
||||
return new Promise((resolve) => schedule(() => resolve(), ms));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user