NvFBC is unable to capture certain applications that bypasses the DWM
compositor, for example, Firefox playing video in full screen. This
has been a known issue for a long time with Nvidia's ShadowPlay, see:
* https://www.nvidia.com/en-us/geforce/forums/geforce-experience/14/233709/
* https://crbug.com/609857
Nvidia won't fix this, but there are workarounds. For example, we
create a transparent 1x1 layered window, which forces desktop composition
to be enabled.
Note that SetLayeredWindowAttributes also supports alpha-based transparency,
but setting transparency to 0 will cause DWM to skip composition. We could
use a transparency of 1, but this ruins the image by the slightest bit,
which is unacceptable. Therefore, we must use chroma key-based
transparency, which tricks DWM into compositing despite being fully
transparent.
It does not make sense to accumulate fractional error in non-capture mode
as you know exactly where the cursor is supposed to be, at least on Wayland.
On Wayland, we base movements on the current guest position and desired
target position, and the accumulated errors only skew our movements.
Build failed with _FORTIFY_SOURCE enabled because the compiler couldn't
ensure the switch statements didn't hit the default arm and thus wouldn't
define the variables. Adding a statically failing assert makes sure that
all code paths either define the variables or fail early.
$ cd client
$ env CFLAGS='-O1 -D_FORTIFY_SOURCE=1' cmake -B build/
$ make -C build
[...]
client/renderers/EGL/egl.c: In function ‘egl_calc_mouse_size’:
client/renderers/EGL/egl.c:299:36: error: ‘h’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
299 | (this->mouseHeight * (1.0f / h)) * this->scaleY
| ~~~~~~^~~~
When using the meta resize feautre the cursor is over the client window,
and as such the application continues to receive motion events. This
causes the window size to spaz out.
As the screen output rotation can be changed on the fly, if it has been
rotated to 90 or 270 the nearest flag will be incorrect, so we perform
this check here and override the provided value.