This is for you if:
- You use TigerVNC's
vncvieweron Linux and the remote screen is smaller or larger than the window you want, but you get scrollbars or a remote that changes resolution every time you resize. - The remote is a fixed-resolution session or a low-resolution machine (an old PC, a VM, a game) and you would like to see it bigger and still sharp.
- You tried running the viewer inside gamescope for scaling, and lost your input method or clipboard.
What it adds
Stock TigerVNC has no client-side scaling: the viewer either shows the remote 1:1 with scrollbars, or asks the server to resize itself (RemoteResize). This patch adds two parameters:
| parameter | values | default |
|---|---|---|
Scale | Off, Fit (keep aspect, letterbox), Stretch, Integer | Off |
ScaleFilter | Nearest, Linear, IntegerPlus | Linear |
vncviewer -Scale Fit -ScaleFilter Linear host:1
- Integer scales by the largest whole factor that fits, with nearest sampling and a border around the image.
- IntegerPlus scales by the largest whole factor with nearest, then covers the remaining fraction with bilinear: crisp pixels without the uneven pixel widths of plain nearest at factors like 2.4.
- While scaling,
RemoteResizeis suspended, so the remote resolution stays where it is when you resize the window. Scale=Offis pixel-identical to the stock viewer — the test suite checks it.
Switch it live from the F8 menu
The F8 context menu gets a Display mode submenu — Resize remote session, No resize (scrollbars), Scale to fit, Scale to stretch, Scale by integer — and a Scale filter submenu with Nearest, Linear and Integer+. Changes last for the session.
How it works
The viewer already draws into an offscreen XRender picture. Scaling sets an XRender transform and filter on that picture and composites it to the window, so the X server does the work and the viewer stays an ordinary X11 client and input methods and the clipboard keep working. Pointer coordinates go through the same pixel-centre mapping as the image, so clicks land where you see them, including in the letterbox. The full design, and the traps found while testing (bilinear fading to black at the edges, damage rectangles, the framebuffer-size assertion), are in docs/scaling.md.
Build
On Ubuntu, the script fetches the tigervnc_1.15.0+dfsg-2build1 source package, applies the Debian patches and this patch, and builds only the viewer:
sudo apt install --no-install-recommends \
libfltk1.3-dev libavcodec-dev libavutil-dev libswscale-dev libpam0g-dev
git clone https://github.com/zirize/tigervnc-client-scaling
cd tigervnc-client-scaling
./build.sh # -> build/vncviewer/vncviewer
Elsewhere, apply the patch to a TigerVNC 1.15.0 tree:
git clone --branch v1.15.0 https://github.com/TigerVNC/tigervnc.git
cd tigervnc && git apply ../tigervnc-client-scaling/patches/0001-*.patch
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && ninja -C build vncviewer
Dependencies and how to rework the patch are in docs/build.md.
Tested on
Ubuntu 26.04 LTS with KDE Plasma on Wayland (the viewer under Xwayland), TigerVNC 1.15.0+dfsg-2build1. On the real desktop, in scale mode: clipboard in both directions, Korean input through an IME running in the remote session (fcitx5-hangul) and fullscreen all work. A headless regression test on private Xvnc displays checks stock parity, every mode against reference images, pointer mapping, partial updates, live resizing and F8 switching, with 0 failures. The patch also applies cleanly to the upstream v1.15.0 tag and the viewer built from it passes the same test (stock-parity checks skipped). Other versions have not been tried.
Scale and ScaleFilter are command-line parameters and are not written to .tigervnc files.GPL-2.0-or-later, the same as TigerVNC.