diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 5cd55288..64c7cda4 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -3055,6 +3055,19 @@ body{background:transparent;overflow:hidden;width:100vw;height:100vh} config.displayId = Number.isFinite(screenId) && screenId > 0 ? screenId : Number(getScreen().getPrimaryDisplay().id) + + // Monitor handle IDs can drift across Electron/Windows capture boundaries, + // so also provide display bounds for a coordinate-based native fallback. + const allDisplays = getScreen().getAllDisplays() + const display = allDisplays.find((candidate) => String(candidate.id) === String(config.displayId)) + ?? getScreen().getPrimaryDisplay() + + if (display) { + config.displayX = Math.round(display.bounds.x) + config.displayY = Math.round(display.bounds.y) + config.displayW = Math.round(display.bounds.width) + config.displayH = Math.round(display.bounds.height) + } } windowsCaptureOutputBuffer = '' diff --git a/electron/native/bin/win32-x64/wgc-capture.exe b/electron/native/bin/win32-x64/wgc-capture.exe index c7b51cd5..2973f783 100644 Binary files a/electron/native/bin/win32-x64/wgc-capture.exe and b/electron/native/bin/win32-x64/wgc-capture.exe differ diff --git a/electron/native/wgc-capture/src/main.cpp b/electron/native/wgc-capture/src/main.cpp index dd80bee2..2f61d046 100644 --- a/electron/native/wgc-capture/src/main.cpp +++ b/electron/native/wgc-capture/src/main.cpp @@ -33,6 +33,11 @@ struct CaptureConfig { int fps = 60; int width = 0; int height = 0; + int displayX = 0; + int displayY = 0; + int displayW = 0; + int displayH = 0; + bool hasDisplayBounds = false; bool captureSystemAudio = false; bool captureMic = false; }; @@ -127,6 +132,18 @@ static bool parseSimpleJson(const std::string& json, CaptureConfig& config) { config.captureSystemAudio = findBool("captureSystemAudio"); config.captureMic = findBool("captureMic"); + int dx = findInt("displayX"); + int dy = findInt("displayY"); + int dw = findInt("displayW"); + int dh = findInt("displayH"); + if (dw > 0 && dh > 0) { + config.displayX = dx; + config.displayY = dy; + config.displayW = dw; + config.displayH = dh; + config.hasDisplayBounds = true; + } + return true; } @@ -198,6 +215,12 @@ int main(int argc, char* argv[]) { } } else { HMONITOR monitor = findMonitorByDisplayId(config.displayId); + if (!monitor && config.hasDisplayBounds) { + std::cerr << "Monitor ID match failed, attempting coordinate-based match: " + << config.displayX << "," << config.displayY << " " << config.displayW << "x" << config.displayH << std::endl; + monitor = findMonitorByBounds(config.displayX, config.displayY, config.displayW, config.displayH); + } + if (!monitor) { std::cerr << "ERROR: Could not find monitor for displayId " << config.displayId << std::endl; return 1; diff --git a/electron/native/wgc-capture/src/monitor_utils.cpp b/electron/native/wgc-capture/src/monitor_utils.cpp index e6b0d03d..a175bd7f 100644 --- a/electron/native/wgc-capture/src/monitor_utils.cpp +++ b/electron/native/wgc-capture/src/monitor_utils.cpp @@ -1,5 +1,6 @@ #include "monitor_utils.h" #include +#include static BOOL CALLBACK enumMonitorCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM lParam) { auto* monitors = reinterpret_cast*>(lParam); @@ -39,6 +40,33 @@ HMONITOR findMonitorByDisplayId(int64_t displayId) { return nullptr; } +HMONITOR findMonitorByBounds(int x, int y, int width, int height) { + auto monitors = enumerateMonitors(); + + for (const auto& m : monitors) { + if (m.x == x && m.y == y && m.width == width && m.height == height) { + std::cerr << "Found monitor by exact bounds: " << x << "," << y << " " << width << "x" << height << std::endl; + return m.handle; + } + } + + for (const auto& m : monitors) { + if (m.x == x && m.y == y) { + std::cerr << "Found monitor by top-left point match: " << x << "," << y << std::endl; + return m.handle; + } + } + + RECT rect = { x, y, x + width, y + height }; + HMONITOR monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); + if (monitor) { + std::cerr << "Found monitor via Windows OS MonitorFromRect fallback" << std::endl; + return monitor; + } + + return nullptr; +} + MonitorInfo getMonitorInfo(HMONITOR monitor) { MonitorInfo info; info.handle = monitor; diff --git a/electron/native/wgc-capture/src/monitor_utils.h b/electron/native/wgc-capture/src/monitor_utils.h index 8889410d..90f3ac39 100644 --- a/electron/native/wgc-capture/src/monitor_utils.h +++ b/electron/native/wgc-capture/src/monitor_utils.h @@ -16,4 +16,5 @@ struct MonitorInfo { std::vector enumerateMonitors(); HMONITOR findMonitorByDisplayId(int64_t displayId); +HMONITOR findMonitorByBounds(int x, int y, int width, int height); MonitorInfo getMonitorInfo(HMONITOR monitor);