Suppressing the white flash

tl;dr: can I get Qubes to stop strobing me?

When I resize a vm window – e.g. drag the corner of a window around the screen – there are brief, milliseconds-long flashes of bright white in the newly exposed areas of the window before the window is properly redrawn with content. I think all Qubes users experience a little of this? (If not, please let me know!) And actually, for me often the entire window flashes white before it’s redrawn.

I hate this! For a dark theme-using, low screen brightness user like me each flash is a microtrauma. It’s especially aggravating for full-screen, black background terminals- when I switch to a workspace with a full-screen terminal I have to look away from the monitor in case the entire screen will flash white.

On and off I’ve tried to fix this. I think the underlying cause is some interaction or combination of interactions of:

  • A high refresh rate, high DPI monitor
  • Unimpressive graphics hardware (12th gen Intel on a NUC)
  • Not super well maintained Intel graphics drivers (kernel-side, xorg-side)
  • The quite clever domU-to-dom0 display pipeline (dummy xorg driver, gui agent, vchan, gui daemon)
  • Insufficient buffering by the window manager compositor
  • ???

Things I can remember I’ve tried to get this under control:

  • Patching dummyqbs_drv.so and related scripting on domU to increase the max clock and allow higher refresh rates on domU for high resolution / high DPI displays. This works in that per xrandr the domU refresh rate can now match the dom0 refresh rate, but disappointingly it doesn’t noticeably lower the incidence of white flashing.

  • Varying the dom0 xorg driver; intel or the better maintained modesetting driver, and also experimenting with xorg.conf options. At times I’ve been fooled into believing this has helped but at other times the incidences of white flashes seem equally bad across driver configurations.

  • Experimenting with compositors other than the native XFCE window manager compositor on dom0, and experimenting with no compositor at all. For me this seems to make no noticeable difference in incidence of white flashes. As a hail mary I’ve also tried running compositors on domU’s X session… to strange result.

  • Using an older low DPI, low refresh rate monitor; perhaps the incidence of white flashes is less, but not by much.

  • Using xsetroot or hsetroot to set the domU X11 root window to a solid black background. (I did not expect this to help, and it did not.)

  • Wrapping the domU X session in a Xephyr session. This does greatly lessen the incidence of white flashes by, say, 90%! But at great cost to window redraw performance, even when the domU window is just a large-ish terminal. So it’s a clear win for limited use, but for extended, focused use where latency matters (programming) redraws are frustratingly laggy.

Something I’d like to do, what would be a wholly acceptable workaround, is change the color of these areas of pending redraw / no buffered content from this bright white to an eye-friendly black. I’ve scanned the qubes-gui-agent and qubes-gui-daemon code, as well as the xf86-video-dummy code, but so far this has remained beyond me.

Ultimately I expect I will “solve” this by changing hardware. But if anyone can offer a solution, or just a suggestion for a new path of investigation, I’d love to hear it.

1 Like

I’ve noticed the same issue.

Changing your hardware probably isn’t going to solve the issue, I only get the white flash from domU windows, it doesn’t happen with native dom0 windows, I doubt this is hardware related.

It also only seems to happen when you create a new window, or resize the window to a larger size, I don’t get the flash when I resize the window to a smaller area.

I presume this issue has to do with the initialization of the memory shared between the domU and dom0, and dom0 showing a frame before there is any frame content.

1 Like

I have a solution to mitigate this, although it’s not perfect.

In dom0 menu, search for the window manager settings, switch to advanced tabs, and in “Hidden windows content” check “During resize”.

With this, while resizing a window, the windows content is replaced by a blue square that doesn’t blink.

1 Like

It doesn’t solve it.

You still get the white flash when the resize happens, you just don’t get white area while resizing.

Weird, I can’t reproduce the full screen blinking in white when resizing to a bigger size? I only have the current resized window content being white. :thinking:

I only use key-shortcuts to resize windows.

When I resize a window to a larger size, the resize happens instantly. The new window will for a short amount of time have a white area, equal to the space added. This gives a very noticeable flash, especially when resizing dark windows on a dark background.

1 Like

Thanks for the responses!

That’s what’s meant :+1: it’s just the current resized window that flashes. But if that window is full-screen…

The best way to reproduce this in its worst form is to take two or more workspaces, start a full-screen black background domU terminal in each of them, and then rapidly switch among these workspaces with keyboard shortcuts. If you’re lucky your monitor will only strobe you rarely; if you’re unlucky it will strobe you every time you switch between them.[*] (Um, if a reader has photosensitive epilepsy or a similar condition, maybe do not try this.)

To reproduce this on a smaller scale (but still obnoxious), try rapid window resizing by keyboard as renehoj suggested with, say, wmctrl.

Yeah, important note- the white flashes never happen for dom0 windows; only domU windows, and presumably because they display through the dummy driver → gui agent → vchan → gui daemon path.

[*] This inconsistency is why I’ve been wondering if the issue is not at least partly a hardware/resource one. During some periods of using my workstation this rapid switching will induce flashing only ~5% of the time. More usually though the rate is ~50% of the time. So far I’ve discovered no specific workload correlations that might explain the difference.

This is my instinct too. My remaining hope is to hack some piece of the display pipeline to, like, change all the rectangles of 0xFF to 0x00 (speaking figuratively but possibly also literally).

1 Like

I think the inconsistency has to do with timing, and the orientation you resize the window. When you resize from the bottom towards the top, or right to left, the current content is moved to the new area. You still get the flash, but the duration is much shorter, then when you resize in the other direction.

Resizing a terminal window left to right, 50% screen size to 100%, always gives me a clearly visible flash.

It would be great with an option to set the color to black or white, as part of Qubes OS that doesn’t require patching and recompiling.

I looked at the code that sends systray icons to dom0, it wasn’t something you could just compile with make.

1 Like

Agreed, it’d be best to have the color of “contentlessness” be user-configurable. Assuming this is not a simple bug but rather is inherent to the Qubes domU display model, which my gut tells me it probably is. (And just to be clear, my complaints aren’t a criticism of the design or implementation of the model, it’s very impressive how well it works aside from this singular issue.)

My observations don’t quite match yours. I see the flashing about as frequently when shrinking vs extending a domU window. I use a set of keybindings to grow or shrink the current window by a constant pixel count, and:

  • If I mash the “grow vertically by N pixels” binding the window flashes a lot as it iteratively grows by N pixels, then N again, then N again, …
  • If I mash the “shrink vertically by N pixels” binding, same story
  • If I mash the “grow horizontally by N pixels” binding, same story
  • If I mash the “shrink horizontally by N pixels” binding, same story

For me what does make a difference are the dimensions of the window being shrunk/grown. If it is a small window the flashes are infrequent or maybe just brief. If it is a large window, nearly the size of the screen, then the flashes are frequent or maybe just longer-than-brief.

I guess it has to do with “background pixel”: qubes-gui-daemon/gui-daemon/xside.c at main · QubesOS/qubes-gui-daemon · GitHub
If somebody wants to play with it, it should be quite easy to change it and see if it helps. For example there is similar BlackPixel function. Making it configurable should also be possible, but it’s going to be a bit more work (add config option to gui-daemon, fetch it from the config file there, and then add support for setting this option via features in core-admin-client).

4 Likes

Whoah, there it is in black and white, so to speak! Thank you so much for this pointer, I’ll play with it and see what comes.

Can confirm that it works. All backgrounds are black with BlackPixel.

Here is the background of my Windows HVM, which used to be white in full screen:
image

3 Likes

Confirmed here too. Wonderful! I can see about shepherding upstream a patch to make the background pixel configurable, though it may take some time.

1 Like

Tracking issue:

1 Like

It would help if the SysTray could default to the same color, and you could select any color.

The patch is now merged upstream (yay), though it’ll be some time before RPMs with this change are released to stable. The color is configurable through a new gui-default-window-background-color feature [0]:

# Substitute your actual guivm if not dom0
[user@dom0 ~]$ qvm-features dom0 gui-default-window-background-color 'dark blue'

Then start or restart relevant app qubes to have the new color applied. [1] Color options are English color names from /etc/X11/rgb.txt or hex format RGB: '0xRRGGBB'.

I’m pretty pleased with this. There is still an occasional white flash when first starting up programs with complex rendering like Firefox or KeePassXC, and some minor rectangular white tearing when rapidly resizing windows for programs like these, but I believe it’s an application-level rendering issue, not a Qubes issue. And it’s rare and predictable.


[0] Also the feature gui-window-background-color to change the color on a per-VM basis, but I don’t see an obvious use case for this.
[1] What’s actually needed is to restart the qubes-guid process for the VM. Restarting the whole VM is the simplest and safest way.

2 Likes

I would like to see the tray icons fixed too and I did look into this a bit but was daunted by the discussion and prior stalled fixes in the github issue.

It seems like there’s an easy fix (accept a user-specified color as a pseudo-background color that is actually a foreground color) and a proper fix (take advantage of some spare pixel bits in the GUI implementation to support an alpha channel for tray icons). Either of which would need to live alongside the rest of the tray configuration (see: man qubes-guid, search for trayicon). I don’t have an instinct for which approach has the most support. Also, there is the possibility that a future transition to Wayland will obviate the need for a fix, but I don’t know that this is so.

It’s been a couple years, maybe we could poke the discussion again and see what comes.

1 Like