XCB event XCB_VISIBILITY_NOTIFY not received
-
My Qt App runs on Linux X Windows and i use installNativeEventFilter() to get XCB event, however the XCB event XCB_VISIBILITY_NOTIFY that i'm interested is never been received (i can receive other XCB events like XCB_EXPOSE, XCB_FOCUS_IN...).
is there XCB configuration to enable/disable this event?
-
My Qt App runs on Linux X Windows and i use installNativeEventFilter() to get XCB event, however the XCB event XCB_VISIBILITY_NOTIFY that i'm interested is never been received (i can receive other XCB events like XCB_EXPOSE, XCB_FOCUS_IN...).
is there XCB configuration to enable/disable this event?
@Eric-Yin
The XCB API doesn't say muchXCB_VISIBILITY_NOTIFY
. Qt doesn't process this event either.
In a small test App, I could not see such an event being sent.
But if it is ever sent, the native event filter will see it.
So the answer to your question is probably: It is a rare event, which is probably why you don't get it.Here is my test code:
#include "mainwindow.h" #include <QApplication> #include <QAbstractNativeEventFilter> #include <xcb/xcb.h> static constexpr QLatin1String toString(int response) { switch (response) { case 0: return QLatin1String("XCB_NOTIFY_MODE_NORMAL"); case 1: return QLatin1String("XCB_NOTIFY_MODE_GRAB"); case 2: return QLatin1String("XCB_NOTIFY_MODE_UNGRAB"); case 3: return QLatin1String("XCB_NOTIFY_MODE_WHILE_GRABBED"); case 7: return QLatin1String("XCB_ENTER_NOTIFY"); case 8: return QLatin1String("XCB_LEAVE_NOTIFY"); case 11: return QLatin1String("XCB_KEYMAP_NOTIFY"); case 15: return QLatin1String("XCB_VISIBILITY_NOTIFY"); case 16: return QLatin1String("XCB_CREATE_NOTIFY"); case 17: return QLatin1String("XCB_DESTROY_NOTIFY"); case 18: return QLatin1String("XCB_UNMAP_NOTIFY"); case 19: return QLatin1String("XCB_MAP_NOTIFY"); case 21: return QLatin1String("XCB_REPARENT_NOTIFY"); case 22: return QLatin1String("XCB_CONFIGURE_NOTIFY"); case 24: return QLatin1String("XCB_GRAVITY_NOTIFY"); case 26: return QLatin1String("XCB_CIRCULATE_NOTIFY"); case 28: return QLatin1String("XCB_PROPERTY_NOTIFY"); case 31: return QLatin1String("XCB_SELECTION_NOTIFY"); case 32: return QLatin1String("XCB_COLORMAP_NOTIFY"); default: return QLatin1String("unknown"); } } class XcbFilter : public QAbstractNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *) override { Q_ASSERT(eventType == "xcb_generic_event_t"); xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message); qDebug() << toString(ev->response_type); return false; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; XcbFilter filter; w.show(); a.installNativeEventFilter(&filter); return a.exec(); } ``
-
@Eric-Yin
The XCB API doesn't say muchXCB_VISIBILITY_NOTIFY
. Qt doesn't process this event either.
In a small test App, I could not see such an event being sent.
But if it is ever sent, the native event filter will see it.
So the answer to your question is probably: It is a rare event, which is probably why you don't get it.Here is my test code:
#include "mainwindow.h" #include <QApplication> #include <QAbstractNativeEventFilter> #include <xcb/xcb.h> static constexpr QLatin1String toString(int response) { switch (response) { case 0: return QLatin1String("XCB_NOTIFY_MODE_NORMAL"); case 1: return QLatin1String("XCB_NOTIFY_MODE_GRAB"); case 2: return QLatin1String("XCB_NOTIFY_MODE_UNGRAB"); case 3: return QLatin1String("XCB_NOTIFY_MODE_WHILE_GRABBED"); case 7: return QLatin1String("XCB_ENTER_NOTIFY"); case 8: return QLatin1String("XCB_LEAVE_NOTIFY"); case 11: return QLatin1String("XCB_KEYMAP_NOTIFY"); case 15: return QLatin1String("XCB_VISIBILITY_NOTIFY"); case 16: return QLatin1String("XCB_CREATE_NOTIFY"); case 17: return QLatin1String("XCB_DESTROY_NOTIFY"); case 18: return QLatin1String("XCB_UNMAP_NOTIFY"); case 19: return QLatin1String("XCB_MAP_NOTIFY"); case 21: return QLatin1String("XCB_REPARENT_NOTIFY"); case 22: return QLatin1String("XCB_CONFIGURE_NOTIFY"); case 24: return QLatin1String("XCB_GRAVITY_NOTIFY"); case 26: return QLatin1String("XCB_CIRCULATE_NOTIFY"); case 28: return QLatin1String("XCB_PROPERTY_NOTIFY"); case 31: return QLatin1String("XCB_SELECTION_NOTIFY"); case 32: return QLatin1String("XCB_COLORMAP_NOTIFY"); default: return QLatin1String("unknown"); } } class XcbFilter : public QAbstractNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *) override { Q_ASSERT(eventType == "xcb_generic_event_t"); xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message); qDebug() << toString(ev->response_type); return false; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; XcbFilter filter; w.show(); a.installNativeEventFilter(&filter); return a.exec(); } ``
@Axel-Spoerl thanks for the reply. This event should not be a rare event. By searching online, i feel like that maybe this event is not enabled by default and i'm trying to use function xcb_configure_window() to enable it:
xcb_configure_window (xcb_connection_t *, winId(), XCB_CW_EVENT_MASK, XCB_EVENT_MASK_VISIBILITY_CHANGE );
Right now i'm struggling to get the xcb_connection_t for my widget App.
-
@Axel-Spoerl thanks for the reply. This event should not be a rare event. By searching online, i feel like that maybe this event is not enabled by default and i'm trying to use function xcb_configure_window() to enable it:
xcb_configure_window (xcb_connection_t *, winId(), XCB_CW_EVENT_MASK, XCB_EVENT_MASK_VISIBILITY_CHANGE );
Right now i'm struggling to get the xcb_connection_t for my widget App.
@Eric-Yin
Out of interest: what is your use case? In other words, what is not covered by Qt signals, so you have to rely on this specific XCB event? -
@Eric-Yin
Out of interest: what is your use case? In other words, what is not covered by Qt signals, so you have to rely on this specific XCB event?@Axel-Spoerl i'm trying to set some window to be always on top, because X Window does not support Qt WindowStaysOnTopHint flag, i believe the way to do it is to receive this event and call raise() function.
-
@Axel-Spoerl i'm trying to set some window to be always on top, because X Window does not support Qt WindowStaysOnTopHint flag, i believe the way to do it is to receive this event and call raise() function.
@Eric-Yin
I see. That's the squaring of the circle. I have seen many implementations of that requirement, depending on the use case.If you want a window to stay on top within a Qt-Application, you can use the hover event to call
raise()
.
The shotgun version of this is aQTimer
firingraise()
periodically.From the top of my mind, I would avoid descending into native XCB events for that purpose. More complication without benefit.
-
@Eric-Yin
I see. That's the squaring of the circle. I have seen many implementations of that requirement, depending on the use case.If you want a window to stay on top within a Qt-Application, you can use the hover event to call
raise()
.
The shotgun version of this is aQTimer
firingraise()
periodically.From the top of my mind, I would avoid descending into native XCB events for that purpose. More complication without benefit.
@Axel-Spoerl My team already discussed the QTimer
option, that will be the last option if there is no other option. -
@Eric-Yin
I see. That's the squaring of the circle. I have seen many implementations of that requirement, depending on the use case.If you want a window to stay on top within a Qt-Application, you can use the hover event to call
raise()
.
The shotgun version of this is aQTimer
firingraise()
periodically.From the top of my mind, I would avoid descending into native XCB events for that purpose. More complication without benefit.
@Axel-Spoerl @Axel-Spoerl do you have any other option besides the QTimer without using native XCB event? thanks.
-
@Axel-Spoerl @Axel-Spoerl do you have any other option besides the QTimer without using native XCB event? thanks.
@Eric-Yin
What exactly do you want to achieve?- that the user can't hide/close the window?
- that it can't be (partially) overlapped by other windows (of your app / other apps)?
-
@Eric-Yin
What exactly do you want to achieve?- that the user can't hide/close the window?
- that it can't be (partially) overlapped by other windows (of your app / other apps)?
@Axel-Spoerl yes, at Linux X Window environment :
-
that the user can't hide the window (can be closed)
-
that it can't be (partially) overlapped by other windows (of your app / other apps)
-
@Axel-Spoerl yes, at Linux X Window environment :
-
that the user can't hide the window (can be closed)
-
that it can't be (partially) overlapped by other windows (of your app / other apps)
@Eric-Yin
Ok, to begin with: One can't expect a client of a window manager to override the window manager's architecture.a) disable hide.
If it's a custom class, overrideQObject::event()
and interceptQEvent::Hide
. Accept the event and return true, without doing anything. You might want to check a bool member and dispatch toQWidget::hide()
. That leave a back door to hide programmatically, if required.
If it's not a custom class, install an eventFilter and do the same.b) partial overlap
You can't avoid that completely.
But you can interceptQEvent::HoverEnter
andQEvent::HowerMove
, just to callraise()
. But that covers only the case that the mouse curser actually enters the window. If the user is dragging another large window, it might overlap yous, while the mouse has not yet entered. -
-
@Eric-Yin
Ok, to begin with: One can't expect a client of a window manager to override the window manager's architecture.a) disable hide.
If it's a custom class, overrideQObject::event()
and interceptQEvent::Hide
. Accept the event and return true, without doing anything. You might want to check a bool member and dispatch toQWidget::hide()
. That leave a back door to hide programmatically, if required.
If it's not a custom class, install an eventFilter and do the same.b) partial overlap
You can't avoid that completely.
But you can interceptQEvent::HoverEnter
andQEvent::HowerMove
, just to callraise()
. But that covers only the case that the mouse curser actually enters the window. If the user is dragging another large window, it might overlap yous, while the mouse has not yet entered.@Axel-Spoerl just tested:
a) Disabling hide event won't work, i have another window that is bigger the always_on_top window, i can drag the bigger window over and cover the always_on_top window completely(no hide event is received), the always_on_top window is completely invisible.b) maybe Expose event can do that
-
@Axel-Spoerl just tested:
a) Disabling hide event won't work, i have another window that is bigger the always_on_top window, i can drag the bigger window over and cover the always_on_top window completely(no hide event is received), the always_on_top window is completely invisible.b) maybe Expose event can do that
@Eric-Yin
As I said, X11 doesn't support "allways on top". That issue can never be solved inside a client of X11. -
@Eric-Yin
As I said, X11 doesn't support "allways on top". That issue can never be solved inside a client of X11.@Axel-Spoerl I just need to receive XCB_VISIBILITY_NOTIFY event which correspond to VisibilityNotify event of X server, then I can call raise() based on this event, unless Qt does not support this event?
-
@Axel-Spoerl I just need to receive XCB_VISIBILITY_NOTIFY event which correspond to VisibilityNotify event of X server, then I can call raise() based on this event, unless Qt does not support this event?
@Eric-Yin said in XCB event XCB_VISIBILITY_NOTIFY not received:
nless Qt does not support this event?
I wonder how often @Axel-Spoerl has to tell you that this is not a Qt problem - if this event would be sent be the window manager then you would have get it in the native event filter.
-
@Axel-Spoerl I just need to receive XCB_VISIBILITY_NOTIFY event which correspond to VisibilityNotify event of X server, then I can call raise() based on this event, unless Qt does not support this event?
@Eric-Yin
Qt does not implement anything related to this event. However, just like for any other XCB event, the native eventFilter is called, if it arrives.On my local system, this event isn’t sent at all. As written before, I couldn’t find any documentation defining its nature and stating that it’s a mandatory event.
Which source tells you, what the event actually notifies and that it’s mandatory? Would be great if you share it.
-
@Eric-Yin
Qt does not implement anything related to this event. However, just like for any other XCB event, the native eventFilter is called, if it arrives.On my local system, this event isn’t sent at all. As written before, I couldn’t find any documentation defining its nature and stating that it’s a mandatory event.
Which source tells you, what the event actually notifies and that it’s mandatory? Would be great if you share it.
@Axel-Spoerl My current Linux X Window platform has some Motif Apps running which receive the VisibilityNotify event to make some Window stay_on_top. I'm working on to replace the Motif Apps with Qt. So the VisibilityNotify event is there.
So in Qt, all the X Window events should go through XCB to the Apps and there is no need to enable them, right? I'm asking because there is the function xcb_configure_window (xcb_connection_t *, winId(), XCB_CW_EVENT_MASK, XCB_EVENT_MASK_VISIBILITY_CHANGE ) that you can enable the events. I tried the function and it does not help.
-
@Axel-Spoerl My current Linux X Window platform has some Motif Apps running which receive the VisibilityNotify event to make some Window stay_on_top. I'm working on to replace the Motif Apps with Qt. So the VisibilityNotify event is there.
So in Qt, all the X Window events should go through XCB to the Apps and there is no need to enable them, right? I'm asking because there is the function xcb_configure_window (xcb_connection_t *, winId(), XCB_CW_EVENT_MASK, XCB_EVENT_MASK_VISIBILITY_CHANGE ) that you can enable the events. I tried the function and it does not help.