#4294

sub-logical-pixel slivers of the background are visible at edges of scaled outputs

Opendmanamopened 3mo ago

When running on a scaled monitor without gaps, the background potentially shows through at the bottom and right edge of the screen, even with windows open nominally taking up 100% of the space. The underlying cause is rounding, in two places:

  1. The requested window size is necessarily an integer number of logical pixels, so it's floored from the desired tile size (request_tile_size). Unfortunately, there's nothing we can do about this directly, but see below.
  2. compute_working_area is rounded to an integer number of logical pixels, since it comes from Smithay's non_exclusive_zone.

The main problem is #⁠1, which seems to be a persistent source of issues (e.g. #1402). However, #⁠2 makes it worse, since it means we're rounding twice, potentially leaving a sub-logical-pixel gap before computing the desired tile size and rounding again. This at least can be fixed straightforwardly by adjusting the working area to meet the output edge whenever it's within 1 logical pixel of it.

For #⁠1 there's no perfect fix. My preference would be that, if gaps are off, any such slivers should be occupied by a sub-logical-pixel thickening of the window border. This is what I intuitively expect to happen, since usually with a tiling WM one can cover the background entirely. The downside is that the border width can then vary slightly between edges. This also doesn't do anything about the situation when borders are disabled (though in that case it really seems like there's nothing we can do).

I can write a PR for these changes if they're deemed suitable. I figure the fix for #⁠2 should be uncontroversial, since it's a simple change within one function and just fixes a double-rounding bug. The fix for #⁠1 is more involved, as it requires tiles to keep track of their requested size and requires the layout engine to use that requested tile size for windows which conform to their requested window size. It's also a genuine change to the rendering logic rather than a simple bugfix. (On the plus side, it should also fix #1402).

Config
prefer-no-csd
output "HDMI-1" {
    scale 1.75
}
layout {
    gaps 0
    border {
        width 2
    }
}

System Information

  • niri version: 25.11 (Nixpkgs)
  • Distro: NixOS
  • GPU: Intel iGPU
  • CPU: Intel Core i5-6600K

Activity

3
Sempyos3mo ago

Can you provide a screenshot

dmanam3mo ago

Here's a screenshot; you can see the orange background showing as 1px on the bottom of the screen and 2px on the right.

YaLTeR3mo ago

I'm not sure what would be a good way to fix this. request_tile_size() has to floor to (try to) make sure that you can always fit n of 1/n sized columns in the screen even with unfortunate rounding.

Various border thickening or adding 1 physical px -- I'm not sure if it can be done in a generic way without adding a ton of edge cases everywhere. How do you know when to thicken the border? What if there are two windows in the column? What if they overflow by height? I kinda doubt there's a good solution here.

Regarding fixing compute_working_area() rounding: you could give it a try. My thinking was to re-use the rounded logical size from Smithay exactly to avoid any surprises when some sizes end up mismatching somewhere. But off the bat I can't remember any places where it's important.