- 
    Bug 
- 
    Resolution: Fixed
- 
    P1: Critical 
- 
    6.8.1
- 
    None
- 
    windows10 and windows 11
Qt does NOT support frameless windows / custom title bar. Which is very incredible in 2025 IMO. There's virtually no professional applications that don't have custom title bar. It's ridiculous that Qt does not support this out of the box.
But on top of that Qt6 actually breaks the possibility to implement it yourself!
The following code was working perfectly on Qt 5.15 to achieve a custom title bar with native Windows support :
- Aero snaps working
- Resizing by the edges working
- Click and drag the title bar to move the window OK
- Double click title bar to maximize OK
- Shadows/(round corners for win11) drawn correctly
FramelessWindow::FramelessWindow(QWidget * parent, Qt::WindowFlags f)
  : QMainWindow( parent, f )
{
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Window);
    HWND hwnd = (HWND)this->winId();
    DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
    ::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
    const MARGINS shadow = { 1, 1, 1, 1 };
    DwmExtendFrameIntoClientArea(HWND(winId()), &shadow);
    auto* titleBar = new CustomTitleBar(this);
    setMenuWidget(titleBar);
}
bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    MSG* msg = reinterpret_cast<MSG*>(message);
    switch (msg->message)
    {
    case WM_NCCALCSIZE:
    {
        if (msg->wParam == TRUE)
{             NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam);             *result = WVR_REDRAW;             return true;         }
    }
    case WM_NCHITTEST:
    {
        auto titleBar = menuWidget();
        if (!titleBar)
{             return QMainWindow::nativeEvent(eventType, message, result);         }
        *result = 0;
        const LONG border_width = 5;
        RECT winrect;
        GetWindowRect(HWND(winId()), &winrect);
        long x = GET_X_LPARAM(msg->lParam);
        long y = GET_Y_LPARAM(msg->lParam);
        bool resizeWidth = minimumWidth() != maximumWidth();
        bool resizeHeight = minimumHeight() != maximumHeight();
        if (resizeWidth) {
            //left border
            if (x >= winrect.left && x < winrect.left + border_width)
           
{                 *result = HTLEFT;             }
            //right border
            if (x < winrect.right && x >= winrect.right - border_width)
           
{                 *result = HTRIGHT;             }
        }
        if (resizeHeight) {
            //bottom border
            if (y < winrect.bottom && y >= winrect.bottom - border_width)
{                 *result = HTBOTTOM;             }
            //top border
            if (y >= winrect.top && y < winrect.top + border_width)
{                 *result = HTTOP;             }
        }
        if (resizeWidth && resizeHeight) {
            //bottom left corner
            if (x >= winrect.left && x < winrect.left + border_width &&
                y < winrect.bottom && y >= winrect.bottom - border_width)
{                 *result = HTBOTTOMLEFT;             }
            //bottom right corner
            if (x < winrect.right && x >= winrect.right - border_width &&
                y < winrect.bottom && y >= winrect.bottom - border_width)
{                 *result = HTBOTTOMRIGHT;             }
            //top left corner
            if (x >= winrect.left && x < winrect.left + border_width &&
                y >= winrect.top && y < winrect.top + border_width)
{                 *result = HTTOPLEFT;             }
            //top right corner
            if (x < winrect.right && x >= winrect.right - border_width &&
                y >= winrect.top && y < winrect.top + border_width)
{                 *result = HTTOPRIGHT;             }
        }
        if (0 != *result) return true;
        //*result still equals 0, that means the cursor locate OUTSIDE the frame area
        //but it may locate in titlebar area
        //support highdpi
        double dpr = this->devicePixelRatioF();
        QPoint pos = titleBar->mapFromGlobal(QPoint(x / dpr, y / dpr));
        if (!titleBar->rect().contains(pos)) return false;
        QWidget* child = titleBar->childAt(pos);
        if (!child)
{             *result = HTCAPTION;             return true;         }
        return false;
    } //end case WM_NCHITTEST
    default:
        return QMainWindow::nativeEvent(eventType, message, result);
    }
    return QMainWindow::nativeEvent(eventType, message, result);
}
  
Now I upgraded to Qt 6.8.1 and nothing works anymore.
Please advise why SetWindowLong and/or DwmExtendFrameIntoClientArea don't work anymore on Qt6. And how to make it work again.
And please just implement support for frameless window on Qt! At least for Windows, MacOS and Linux It should have been done 15 years ago already.