Tor, Thanks for your reply.
I’ve just created the issue: https://qt-project.atlassian.net/browse/QTBUG-148623 I’ve used Claude Code to generate the bug report, forgive me its not perfectly formatted. Thank you! Best, Nuno > On 28 Jul 2026, at 17:04, Tor Arne Vestbø <[email protected]> wrote: > > This sounds like a bug, please file a JIRA issue, thanks! > >> On 28 Jul 2026, at 17:33, Nuno Santos via Interest <[email protected]> >> wrote: >> >> Hi all, >> >> We ship several audio plug-ins (VST2/VST3/AU) that each statically link Qt, >> built with a custom namespace (configure -qtnamespace <ours>). Multiple such >> plug-ins are routinely loaded into the same host process (e.g. Ableton Live) >> >> the classic "several independent static-Qt instances in one process" >> scenario that -qtnamespace exists to support. >> This has worked on Windows for many years. After moving to Qt 6.11, the >> second Qt-based plug-in loaded into a host now comes up with a blank/white >> UI. The logs show its Win32 window classes failing to register: >> >> qt.qpa.windowclass: Failed to register window class >> "Qt6110d<namespace>QWindowIcon" ( "Class already exists." ) >> ... >> QWindowsContext::windowsProc: No Qt Window found for event 0xf >> (WM_PAINT), hwnd=0x... >> i.e. the second instance reuses the first instance's already-registered >> class (and therefore its WNDPROC), its windows' messages are delivered to >> the wrong Qt instance, and it never paints. >> >> WHAT CHANGED >> >> Bisecting src/plugins/platforms/windows: >> >> Up to Qt 6.10, QWindowsContext::registerWindowClass(QString cname, WNDPROC >> proc, ...) appended a UUID to the final, prefixed class name whenever it >> detected the class already existed with a different WNDPROC (i.e. another Qt >> instance in the process): >> >> const bool classExists = >> GetClassInfo(appInstance, (LPCWSTR)cname.utf16(), &wcinfo) != FALSE >> && wcinfo.lpfnWndProc != proc; >> if (classExists) >> cname += QUuid::createUuid().toString(); >> This is what let multiple same-namespace static-Qt plug-ins coexist for >> years. >> >> Qt 6.11 extracted this into a new QWindowsWindowClassRegistry (commits >> 04f13038f5 "Extract window class registration into dedicated class", >> 2025-11-20, and b23b9c8265 "Add shouldDecorateWindowClassName to detect >> window class conflicts", 2025-11-28). In the new code the collision check >> runs against the un-prefixed description.name, while registration uses the >> prefixed classNamePrefix() + description.name: >> >> QString className = description.name; >> if (description.shouldAddPrefix) >> className = classNamePrefix() + className; >> // e.g. "Qt6110d<namespace>QWindowIcon" >> >> if (shouldDecorateWindowClassName(description)) >> // -> uses description.name (unprefixed!) >> className += QUuid::createUuid().toString(); >> ... >> bool QWindowsWindowClassRegistry::shouldDecorateWindowClassName( >> const QWindowsWindowClassDescription &description) const >> { >> return shouldDecorateWindowClassName(description.name, >> description.procedure); >> } >> >> bool QWindowsWindowClassRegistry::shouldDecorateWindowClassName( >> const QString &name, WNDPROC procedure) const >> { >> const auto appInstance = >> static_cast<HINSTANCE>(GetModuleHandle(nullptr)); >> WNDCLASS wc{}; >> return GetClassInfo(appInstance, (LPCWSTR)name.utf16(), &wc) != FALSE >> && wc.lpfnWndProc != procedure; >> } >> Because nothing ever registers the bare QWindowIcon (the registered name is >> always the prefixed form), GetClassInfo on the un-prefixed name always >> returns FALSE, the UUID is never appended, and the second instance collides >> on the plain prefixed name. This still appears to be the case on the current >> dev branch, and there is no related entry in the 6.11.1 release notes. >> >> THE QUESTION >> >> Is this a deliberate change - i.e. is the expectation now that every >> independently-loaded static-Qt plug-in must be built with a unique >> QT_NAMESPACE, so the class-name prefix is already unique and the runtime >> UUID de-duplication is no longer meant to be relied upon? >> >> Or is it an unintended regression, where the check should have been >> performed against the final (prefixed) className rather than the un-prefixed >> description.name? If the latter, the fix looks like a one-liner - decorate >> based on the prefixed name, e.g.: >> >> if (description.shouldAddPrefix) >> className = classNamePrefix() + className; >> >> if (shouldDecorateWindowClassName(className, description.procedure)) >> // prefixed name >> className += QUuid::createUuid().toString(); >> We don't yet have a workaround in place, but we plan to try applying the >> same approach macOS already uses (mangling the Qt namespace to a unique >> value per binary at build time) as a stopgap. In the meantime we'd like to >> know whether we should rely on unique namespaces going forward, or whether a >> fix is expected upstream. Happy to file a bug report with a minimal >> reproducer if that helps. >> >> Thank you! >> >> Best regards, >> >> >> _______________________________________________ >> Interest mailing list >> [email protected] >> https://lists.qt-project.org/listinfo/interest >
_______________________________________________ Interest mailing list [email protected] https://lists.qt-project.org/listinfo/interest
