fix(windows): restore WGC monitor fallback

This commit is contained in:
webadderall
2026-03-28 15:18:56 +11:00
parent 8de1d9a498
commit ca29abd89c
5 changed files with 65 additions and 0 deletions
+13
View File
@@ -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 = ''
Binary file not shown.
+23
View File
@@ -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;
@@ -1,5 +1,6 @@
#include "monitor_utils.h"
#include <ShellScalingApi.h>
#include <iostream>
static BOOL CALLBACK enumMonitorCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM lParam) {
auto* monitors = reinterpret_cast<std::vector<MonitorInfo>*>(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;
@@ -16,4 +16,5 @@ struct MonitorInfo {
std::vector<MonitorInfo> enumerateMonitors();
HMONITOR findMonitorByDisplayId(int64_t displayId);
HMONITOR findMonitorByBounds(int x, int y, int width, int height);
MonitorInfo getMonitorInfo(HMONITOR monitor);