What decides where a native event gets sent?
-
I have a top-level frameless window (inherited from QWidget) where I've implemented nativeEvent(). In some instances I display a dialog window created from this same window class, but when the dialog is closed it seems as if one the the top-level window's child widgets is then intercepting the native events.
Are native events passed up the 'ancestral hierarchy' like QEvents are? Or are they sent directly to a specific widget?
-
Cliff notes for anyone who finds this in the future:
-
Native events only get sent to widgets with a native window handle (as the documentation states).
-
Native events don't propagate.
-
Most importantly: when calling winId(), all child widgets of the widget winId() is called on will receive native window handles. Since they now have window handles they will receive native events, blocking the parent from receiving them. It appears that setting Qt::AA_DontCreateNativeWidgetSiblings application-wide will prevent this from happening, and it may be possible to individually remove the Qt::WA_NativeWindow attribute from each of the children.
I fixed this by using effectiveWinId(), which will return 0 if the widget doesn't have a handle and won't assign native window handles to its' children. Then, I wait for QEvent::WinIdChange in the QWidget::event() function; calling the function that required the native window handle when this event occurs.
There's an attribute called Qt::WA_DontCreateNativeAncestors, but it didn't seem to do what it described.
-
-
Hi,
What OS are you using ?
What version of Qt ? -
Windows 10 with Qt 5.11.2.
I'm aware of this bug: https://bugreports.qt.io/browse/QTBUG-70873 but right now I'm not using native event filters.
-
I've created a minimal example (sorry for the length).
The window can be double-click maximized, dragged, resized, etc. like a normal window. Then, if the dialog is shown and then closed the window can no longer be dragged and double-clicked maximized. It can, however, be resized on its' 1 pixel border.
So it appears as if some win32 messages are being intercepted, and not sent to Window::nativeEvent.
-
Cliff notes for anyone who finds this in the future:
-
Native events only get sent to widgets with a native window handle (as the documentation states).
-
Native events don't propagate.
-
Most importantly: when calling winId(), all child widgets of the widget winId() is called on will receive native window handles. Since they now have window handles they will receive native events, blocking the parent from receiving them. It appears that setting Qt::AA_DontCreateNativeWidgetSiblings application-wide will prevent this from happening, and it may be possible to individually remove the Qt::WA_NativeWindow attribute from each of the children.
I fixed this by using effectiveWinId(), which will return 0 if the widget doesn't have a handle and won't assign native window handles to its' children. Then, I wait for QEvent::WinIdChange in the QWidget::event() function; calling the function that required the native window handle when this event occurs.
There's an attribute called Qt::WA_DontCreateNativeAncestors, but it didn't seem to do what it described.
-
-
@Qt_User72653 Dear bro, I know this topic is a little bit old, but could you please elaborate how you fixed it, when and where should I use effectiveWinId() instead of winId(), and do I need to set the Qt::WA_DontCreateNativeAncestors attribute on the widget? I've been lost for quite a few days :(
-