From 52d865c35960f0c1de4811d186dccee27359709c Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Jun 2024 16:01:55 +0200 Subject: [PATCH] Avoid VNC updates for offscreen windows Windows aren't always directly shown, e.g. when the desktop is composited. We should not be sending screen updates for these as the framebuffer didn't actually change. In the case of CopyWindow, we're even sending the wrong screen data, which is how this bug was discovered. --- unix/xserver/hw/vnc/vncHooks.c | 69 ++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/unix/xserver/hw/vnc/vncHooks.c b/unix/xserver/hw/vnc/vncHooks.c index 3838c10d..7fe35ada 100644 --- a/unix/xserver/hw/vnc/vncHooks.c +++ b/unix/xserver/hw/vnc/vncHooks.c @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009-2017 Pierre Ossman for Cendio AB + * Copyright 2009-2024 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -469,39 +469,47 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) { int dx, dy; - BoxRec screen_box; - RegionRec copied, screen_rgn; + RegionRec copied; SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow); - RegionNull(&copied); - RegionCopy(&copied, pOldRegion); + if (is_visible(&pWin->drawable)) { + BoxRec screen_box; + RegionRec screen_rgn; - screen_box.x1 = 0; - screen_box.y1 = 0; - screen_box.x2 = pScreen->width; - screen_box.y2 = pScreen->height; + RegionNull(&copied); + RegionCopy(&copied, pOldRegion); - RegionInitBoxes(&screen_rgn, &screen_box, 1); + screen_box.x1 = 0; + screen_box.y1 = 0; + screen_box.x2 = pScreen->width; + screen_box.y2 = pScreen->height; - dx = pWin->drawable.x - ptOldOrg.x; - dy = pWin->drawable.y - ptOldOrg.y; + RegionInitBoxes(&screen_rgn, &screen_box, 1); - // RFB tracks copies in terms of destination rectangle, not source. - // We also need to copy with changes to the Window's clipping region. - // Finally, make sure we don't get copies to or from regions outside - // the framebuffer. - RegionIntersect(&copied, &copied, &screen_rgn); - RegionTranslate(&copied, dx, dy); - RegionIntersect(&copied, &copied, &screen_rgn); - RegionIntersect(&copied, &copied, &pWin->borderClip); + dx = pWin->drawable.x - ptOldOrg.x; + dy = pWin->drawable.y - ptOldOrg.y; + + // RFB tracks copies in terms of destination rectangle, not source. + // We also need to copy with changes to the Window's clipping region. + // Finally, make sure we don't get copies to or from regions outside + // the framebuffer. + RegionIntersect(&copied, &copied, &screen_rgn); + RegionTranslate(&copied, dx, dy); + RegionIntersect(&copied, &copied, &screen_rgn); + RegionIntersect(&copied, &copied, &pWin->borderClip); + + RegionUninit(&screen_rgn); + } else { + RegionNull(&copied); + dx = dy = 0; + } (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion); add_copied(pScreen, &copied, dx, dy); RegionUninit(&copied); - RegionUninit(&screen_rgn); SCREEN_EPILOGUE(CopyWindow); } @@ -512,18 +520,23 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures) { - BoxRec box; RegionRec reg; SCREEN_PROLOGUE(pWin->drawable.pScreen, ClearToBackground); - box.x1 = x + pWin->drawable.x; - box.y1 = y + pWin->drawable.y; - box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); - box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); + if (is_visible(&pWin->drawable)) { + BoxRec box; - RegionInitBoxes(®, &box, 1); - RegionIntersect(®, ®, &pWin->clipList); + box.x1 = x + pWin->drawable.x; + box.y1 = y + pWin->drawable.y; + box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); + box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); + + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, &pWin->clipList); + } else { + RegionNull(®); + } (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); -- 2.39.5