ghaerr / microwindows

The Nano-X Window System
Other
648 stars 91 forks source link

Window border glitches after resize #62

Open Flygrounder opened 2 years ago

Flygrounder commented 2 years ago

I've encountered strange behavior while writing tiling window manager using Nano-X. When I resize windows, sometimes old border remains on the screen.

Before resize: image

After: image

Notably this happens only when I increase left window size, but not right.

Here is a simple program to reproduce: https://git.flygrounder.ru/flygrounder/microwindows-border-bug/src/branch/master/src/main.c

ghaerr commented 2 years ago

Hello @Flygrounder,

Thank you for using Nano-X.

Your code looks fine. I'm pretty sure the reason for the problem is that the window border draw output is not being included in the window clip region, and thus the borders are drawing on top of another window. This is only noticeable based on the order the windows are redrawn, and it seems the right window is redrawn last, thus overwriting the left window's client area. If you use GrFillRect to fill the windows with a seperate color, what is going on will become more apparent.

The reason this bug has persisted is likely because the idea of using "automatically-drawn" single-color window borders is pretty much a thing of the past (for Nano-X). That is, a usable window manager will probably have to draw more widgets in its managed windows "non-client" area. To do this requires a bit more work, which is the way the current Nano-X window manager works: it creates a "parent" window for each of the client windows, and the parent window becomes the area which the "borders" are drawn. The borders end up being drawn with title text, title bars, etc using that window's draw code, and the child window is automatically excluded. Thus, the illusion is that the window has a border, but in reality the system is using parent-child windows with full clipping to manage the look and feel. All the windows are created without using the older "internal" border size.

What direction are you thinking of taking your window manager?

Thank you!

Flygrounder commented 2 years ago

I've chosen to stay away from reparenting because in tiling window manager you don't really need those widgets as you are doing everything with keybindings. For example popular X11 tiling window managers like dwm and XMonad are non-reparenting. I might consider framing windows though because this bug is annoying and I don't really know how to fix it.

ghaerr commented 2 years ago

I've chosen to stay away from reparenting because in tiling window manager you don't really need those widgets as you are doing everything with keybindings. For example popular X11 tiling window managers like dwm and XMonad are non-reparenting.

Got it.

I might consider framing windows though because this bug is annoying and I don't really know how to fix it.

IIRC, back early in development, I considered fixing "bordered" windows to be a part of the window's clip region, but this proved to be quite complicated, as Nano-X doesn't really implement the idea of a "client" or "non-client" (i.e. bordered) portions of the window. In retrospect, having window borders was a bad idea - we probably should have implemented a "non-client" draw area, even if its only a single pixel wide.

A path that should not change much in your design but allow you to proceed forward would be to reparent the window and just have the parent draw a single rectangle around itself, using GrRect. This should allow keybindings to move the parent windows around and the events should still go to the child windows.

Another path would be to take the existing Nano-X window manager, and eliminate most of the draw code, with the exception of drawing a single line around the parent frame. That would for sure work, since the window manager already works well. Key bindings might need to be added. I can help you with this approach if you need help.

Flygrounder commented 2 years ago

I've implemented reparenting using the first approach (didn't use GrRect though, just window background color). Now it seems to work fine. Thanks for such comprehensive answer and of course for developing Nano-X