Keep stream capture failures and cursor snapshots tied to their source

This commit is contained in:
evgeny committed 2026-10-17 01:30:06 +02:00
1 parent 9c7d088f8b
commit fd73fae77f
3 files changed
+41 -25

No files matched your search

+14 -14
View File
@@ -6,11 +6,16 @@
#include <qt_windows.h>
#include <cstring>
StreamScreenCursor::StreamScreenCursor(QScreen* screen) : m_screen(screen) {
StreamScreenCursor::StreamScreenCursor(QScreen* screen) {
if (!screen) { DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: Windows screen unavailable"); return; }
m_screenName = screen->name();
auto* native = screen->nativeInterface<QNativeInterface::QWindowsScreen>();
if (!native || !(m_monitor = native->handle())) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: native monitor unavailable screen=%s", qPrintable(m_screenName)); return;
}
m_ready = true;
DEBUG_INFO(DEBUG_CATEGORY_VIDEO, "desktop cursor opened screen=%s scale=%.3f backend=Win32",
qPrintable(screen->name()), screen->devicePixelRatio());
qPrintable(m_screenName), screen->devicePixelRatio());
}
StreamScreenCursor::~StreamScreenCursor() {
@@ -19,30 +24,25 @@ StreamScreenCursor::~StreamScreenCursor() {
/* DrawIconEx работает с фоном кадра: это сохраняет и alpha, и AND/XOR системных курсоров. */
bool StreamScreenCursor::draw(QImage& frame) {
if (!m_ready || !m_screen || frame.isNull()) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor unavailable ready=%d screen=%d frame=%dx%d",
m_ready, !m_screen.isNull(), frame.width(), frame.height()); return false;
if (!m_ready || !m_monitor || frame.isNull()) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor unavailable ready=%d monitor=%p frame=%dx%d",
m_ready, m_monitor, frame.width(), frame.height()); return false;
}
CURSORINFO cursor{}; cursor.cbSize = sizeof(cursor);
if (!GetCursorInfo(&cursor)) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: GetCursorInfo failed error=%lu", GetLastError()); return false;
}
if (!(cursor.flags & CURSOR_SHOWING)) return true;
auto* native = m_screen->nativeInterface<QNativeInterface::QWindowsScreen>();
if (!native) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: native monitor unavailable screen=%s", qPrintable(m_screen->name()));
return false;
}
MONITORINFOEXW monitor{}; monitor.cbSize = sizeof(monitor);
if (!GetMonitorInfoW(native->handle(), reinterpret_cast<MONITORINFO*>(&monitor))) {
if (!GetMonitorInfoW(static_cast<HMONITOR>(m_monitor), reinterpret_cast<MONITORINFO*>(&monitor))) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: GetMonitorInfo failed screen=%s error=%lu",
qPrintable(m_screen->name()), GetLastError()); return false;
qPrintable(m_screenName), GetLastError()); return false;
}
const QSize monitorSize(monitor.rcMonitor.right - monitor.rcMonitor.left,
monitor.rcMonitor.bottom - monitor.rcMonitor.top);
if (frame.size() != monitorSize) {
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop cursor: captured frame does not match monitor screen=%s frame=%dx%d monitor=%dx%d",
qPrintable(m_screen->name()), frame.width(), frame.height(), monitorSize.width(), monitorSize.height());
qPrintable(m_screenName), frame.width(), frame.height(), monitorSize.width(), monitorSize.height());
return false;
}
// RECT использует физические координаты общего виртуального desktop, включая отрицательные origins.
@@ -105,7 +105,7 @@ bool StreamScreenCursor::draw(QImage& frame) {
painter.drawImage(area.topLeft(), composed);
if (!m_reported) {
DEBUG_INFO(DEBUG_CATEGORY_VIDEO, "desktop cursor drawn screen=%s device=%ls origin=%d,%d position=%d,%d hotspot=%lu,%lu sprite=%dx%d frame=%dx%d",
qPrintable(m_screen->name()), monitor.szDevice, origin.x(), origin.y(), position.x(), position.y(), icon.xHotspot,
qPrintable(m_screenName), monitor.szDevice, origin.x(), origin.y(), position.x(), position.y(), icon.xHotspot,
icon.yHotspot, size.width(), size.height(), frame.width(), frame.height());
m_reported = true;
}