Incorrect window coloring behavior in a Qt frameless window (win32)

I have a QML application (also tested it with QWidgets, same problem) and make it borderless (but still support my own WM functions like aero snap, etc.). I followed this up by implementing the QAbstractNativeEventFilter and responding to the WM_NCCALSIZE signal with zero:

switch(msg->message) { case WM_NCCALCSIZE: *r = 0; return 1; ... } 

I also set some window flags that are not in the Qt namespace with

 SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME); 

This works fine until I moved or resized the window, which is why Qt redraws the width of the unpainted area of ​​the header width and borders:

Before moving / resizing Before

After moving / resizing After

I also found a workaround for this by adding the FramelessWindowHint flag in Qt:

 window->setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Dialog); 

But now these fields are repeated again when the state of the window changes (maximize, minimize, ...). By blocking the WM_SIZE event, for example, when SIZE_MAXIMIZED is a parameter, the margin does not appear, but then I also can not maximize the window from Qt. This means that this is a problem with the Qt side.

I also noticed by looking at the window style with winspector, after I maximized it, a new property atom appears:

winspector screenshot

Can you help me fix this?

+6
source share
2 answers

I think that using SetWindowLong in your window handle using the Qt Window Flags / Qt Widget attributes is causing problems. You can go and see the source of Qt to find out what happens when these window flags are processed.

When I created frameless windows, I usually did this to prevent moving and resizing, because I manage it separately.

One of the problems I'm connected with was that when the on-screen keyboard appeared and docked, it would resize my windows. Therefore, in addition to calling resize() , I had to use setFixedSize to prevent my widgets from being manipulated when the operating system tried to resize the window.

In other words, I would add a QShortcut wide QShortcut by listening to the shortcut keys and QShortcut your window the way you want it to happen if you control a frameless window.

Hope this helps.

0
source

I wonder if this was not a Qt message relay error, because I met a similar problem that occurs on nested windows. If you press the SIZE_MAXIMIZE or SIZE_MINIMIZE button of the parent window, the child window will sometimes be unable to receive the WM_SIZE message. I assume that there are approximately two solutions: 1. Fix Qt, 2. Work around.

Here I have an OGL rendering child window, sometimes even the WM_SIZE message is incorrectly transmitted. That is, if you change the size of the parent window, you will get part of the black area of ​​the client.

I just use a simple workaround to fix this, which check the current size using cached and manually resize themselves.

0
source

All Articles