From 334b361c8d1bf17652663768fd9237b46287781f Mon Sep 17 00:00:00 2001 From: Tony Miller <2032667+tnymlr@users.noreply.github.com> Date: Sun, 3 May 2026 06:06:00 +1000 Subject: screenshare: round captureBox after scaling to fix region capture at fractional scales (#14257) After scaling m_captureBox from logical to pixel coordinates, the box may have non-integer dimensions (e.g. logical 401x301 at scale 1.25 -> pixel 501.25x376.25). m_bufferSize is then computed as captureBox.size() and sent to the client as int32 width/height (truncating the fraction), but m_bufferSize itself stays as a fractional Vector2D. When the client allocates the integer-sized buffer and submits it, CScreenshareFrame::share() rejects it with ERROR_BUFFER_SIZE because Vector2D::operator== is exact double comparison: (501, 376) != (501.25, 376.25). The frame is sent failed, and the client retries forever. The SHARE_WINDOW path already rounds its bufferSize; the SHARE_REGION path didn't. Round the captureBox immediately after scaling so all downstream consumers (m_bufferSize, render translates) see clean integer pixel coordinates. Reproducer at scale 1.25 on a 1920x1080 monitor: wf-recorder -g '500,200 401x301' -f /tmp/x.mp4 # "Failed to copy frame, retrying..." until exit wf-recorder -g '500,200 400x300' -f /tmp/x.mp4 # works (400*1.25=500, 300*1.25=375, both integer) --- src/managers/screenshare/ScreenshareSession.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/managers/screenshare/ScreenshareSession.cpp') diff --git a/src/managers/screenshare/ScreenshareSession.cpp b/src/managers/screenshare/ScreenshareSession.cpp index 1f7aeb88..7e6aea6f 100644 --- a/src/managers/screenshare/ScreenshareSession.cpp +++ b/src/managers/screenshare/ScreenshareSession.cpp @@ -80,8 +80,9 @@ void CScreenshareSession::init() { if (g_pEventLoopManager) g_pEventLoopManager->addTimer(m_shareStopTimer); - // scale capture box since it's in logical coords - m_captureBox.scale(monitor()->m_scale); + // scale capture box since it's in logical coords; round to integer pixel + // dims so m_bufferSize matches the int32 size we send to the client + m_captureBox.scale(monitor()->m_scale).round(); m_listeners.monitorDestroyed = monitor()->m_events.disconnect.listen([this]() { stop(); }); m_listeners.monitorModeChanged = monitor()->m_events.modeChanged.listen([this]() { -- cgit v1.2.3