When the underlying QWindow and QPlatformWindow of a QWidget are destroyed by QWindow::destroy() and re-created with QWindow::create(), QWidget::winId() still returns the old value and did not update.
This is a Qt 5 specific problem introduced by QWindow and it does not exist in Qt 4.x.
QWidget stores the native winId in QWidgetData::winid, but actually the winid is controlled and can be changed by its underlying QWindow and QPlatformWindow.
Once the native window handle is changed, QWidget becomes out of sync.
The correct implementation should call QWidget::setWinId() whenever the native handle of its associated QWindow and QPlatformWindow is changed and emit QEvent::WinIdChange signal.
Please note that QWindow and QPlatformWindow can be changed behind the back of QWidget under several conditions and QWidget is unaware of the change.
There may be more conditions but I haven't dig into this deeply enough.
The proposed solution to this problem:
1. Let QWindow and QPlatformWindow fire a QEvent::winIdChange event whenever its native handle is changed. QWidget can filter this by installing an event filter on the QWindow.
2. Alternatively, add a winIdChanged() signal to QWindow and QplatformWindow and let QWidget connect to it.
3. Or, look up in the map between native handle and QWidget used by the event dispatcher to check if a QWindow has an associated QWidget.
4. Check every invocation of QWindow::create(), QWindow::destroy(), QPlatformWindow::create(), QPlatformWindow::destroy() and make sure all of them can trigger QWidget::setWinId() if the window belongs to a QWidget.
This bug is not X11-specific and should affect all supported platforms. It can break any code which utilize the native winId() to do platform specific operations.
This may also affect bug #40681.
Thank you very much!