PolyMeilex / sctk-adwaita

Adwaita-like SCTK Frame
MIT License
26 stars 19 forks source link

Shadow is drawn off-by-one with non-integer scale factors #51

Open Friz64 opened 9 months ago

Friz64 commented 9 months ago

150%: image

225%: image

This mostly manifests on the left edge, but sometimes also on the right edge.

While developing the shadow PR, I only tested with integer scale factors 😅

kchibisov commented 9 months ago

subsurface positioning is undefined with fractional scaling.

kchibisov commented 9 months ago

even when used with the protocol, it's undefined even in it.

kchibisov commented 9 months ago

Just thinking on it, what you can do is to try blace below and cover the border in px, so it won't be visible and will either not cover it or cover it. You obviously can't draw for more than border width, otherwise it'll be ugly for transparent clients.

Friz64 commented 8 months ago

subsurface positioning is undefined with fractional scaling.

Ugh, this is incredibly frustrating. Wouldn't it be better if the whole window frame was drawn onto one big subsurface, instead of multiple little ones? This would completely sidestep this issue as well as simplify the codebase somewhat. Are there any disadvantages to this I'm not seeing here?

Just thinking on it, what you can do is to try blace below and cover the border in px, so it won't be visible and will either not cover it or cover it. You obviously can't draw for more than border width, otherwise it'll be ugly for transparent clients.

I am sorry, but I am not understanding this comment.

kchibisov commented 8 months ago

Make shadow under border subsurface, you can manipulate z-pos, so you just draw more than you should, and then add border on top. When you have missmatch, the border will compensate.

Friz64 commented 8 months ago

So you're saying we should make another set of four subsurfaces specifically for the shadow? But how does this avoid the "vertical stripes" that can be seen in the screenshots above if you look closely? They are outside of the border.

Friz64 commented 8 months ago

Wouldn't it be better if the whole window frame was drawn onto one big subsurface, instead of multiple little ones?

Seems like libdecor does something similar. https://gitlab.freedesktop.org/libdecor/libdecor/-/blob/060fe7611aedb5779929e6b1468419c2d4e7168f/src/plugins/gtk/libdecor-gtk.c

Friz64 commented 8 months ago

Wouldn't it be better if the whole window frame was drawn onto one big subsurface, instead of multiple little ones?

Did a really quick and dirty test implementation of this, and this would definitely solve this issue. Unfortunately, the codebase is centered around the idea of multiple little subsurfaces, and doing this properly would require a significant refactor.

Also: I think this refactor should be done along with adding the ability to hide the titlebar, as those changes would go hand in hand. This is so that applications can draw their own window controls, while relying on us to handle window shadows and resize handles.

kchibisov commented 8 months ago

Using one big subsurface is a in-efficient since you allocate more memory, and involve complex blending in compositor for transparent clients, since compositor must blend what you draw under it, which is not the case with the current approach.

Friz64 commented 8 months ago

Huh, I would assumed that compositing all those subsurfaces together is actually more expensive. Are there any learning resources that I can study to build an intuition for this? Is it really that bad to the point where it should be avoided? libdecor seems to get away with it.

kchibisov commented 8 months ago

They don't overlap with the main surface, so it's not. Also, you must not show them when you have tiled, maximized, fullscreen states. It's just way simpler to do it that way, then having intense logic on how to resize and reposition the main subsurface.