Solved Cannot forward key events to QQuickWindow
-
Hi all!
Let me describe the situation before I proceed asking the actual question:
- I am using a QQuickWindow, QQuickRenderControl and a QOffscreenSurface to render a Qml scene into a OpenGL framebuffer object.
- I am rendering the contents of the FBO into a separate QOpenGLWindow.
The rendering is working perfectly fine, but what would a Gui be without being able to interact with it? So I thought about simply forwarding all the events my QOpenGLWindow receives to the QQuickWindow:
void Window::dispatchEvents(QEvent* event) { for (GuiManager* w : m_guiWindows) { // w->window() yields a pointer to a QQuickWindow. QCoreApplication::sendEvent(w->window(), event); } }
Strangely, all of my mouse events are forwarded without a problem, but key events are ignored completely. After debugging the Qt sources for quite a while, I figured it was a Focus issue. I tried several things now:
- Focussing the QQuickWindow::contentItem(). This surpringly worked while having a debugger attached and having a breakpoint at a specific location in qquickwindow.cpp (lol).
- Spamming events of type FocusIn and FocusAboutToChange (absolutely no effect).
- Actually showing the underlying QQuickWindow (although not required). When I focused it, the cursor of the TextField suddenly appeared in the other window and I could write some text, without any problems!
- Last but not least, trying to take a peek into the Qt sources to find possible code snippets that mess with input stuff in QApplication and QQuickWindow. I found some, but unfortunately they are all inaccessible so I couldn't try them...
Does anyone have an idea what could be going wrong here or more importantly, why does focussing the actual QQuickWindow suddenly work?
Thanks in advance!
-
Solved it. Ugly, but works.
Right before sendEvent, put a QQuickWindow::requestActivate() call. This way, the Qml scene is finally focused. Disadvantage: Main window is now deactivated, causing undesired visual flaws in the window frame.
I hope they implement a functionality like this in future Qt versions, without having to deactivate the main window...
-
@Nicolas-Kogler Glad you solved it. :)
When learning QML I had a lot of issues with keyboard events and focus.
I came up with a lot of hacky solutions to bypass the problems. I found out later that it was just me and how I created objects and when they were focused. Once I started dealing with my focus issues properly I noticed my key events being handled much better.
I wish I could be more explicit but I'm still learning QML so I'm not good enough to give solid details. :) Just wanted to throw it out there that QML is incredibly picky about focus and who gets key events, even in the seemingly "same" window.
-
@ambershark When using the QQuickWindow "as intended", everything works fine. But I am basically trying to have a QOpenGLWindow act as if it was the QQuickWindow containing the items. The Qt developers kicked ass for giving the possibility to render your QtQuick scene into a framebuffer, but unfortunately they didn't think about that someone wants to integrate the QtQuick scene into a QWindow and possibly use multiple scenes in a single window...
-
Little update for anyone who faces the same problem.
The flickering of the window title bar can be solved doing the following:if (hitbox.contains(localMousePos.x(), localMousePos.y())) { m_activeGui = w; m_fakeFocusOut = true; m_activeGui->window()->requestActivate(); // Gui focused; disable the ability to focus main window setFlags(flags() | Qt::WindowDoesNotAcceptFocus); } else { if (m_activeGui == w) { m_activeGui = nullptr; m_fakeFocusOut = false; // No Gui active; enable ability to focus again setFlags(flags() & ~Qt::WindowDoesNotAcceptFocus); requestActivate(); } }
This works because whenever I issue a mouse click on my main window, the window manager tries to focus the window. In my event handler, though, I immediately focus a Gui again, causing the main window to be active for a split second. When I disable the ability to focus using the respective Qt flag, it works!
Tired of hacking already haha :-).
-
@Nicolas-Kogler this is a really clear post, very detailed by the way, congratulations. I have the same issue, doing the same offscreen rendering and event forwarding however this trick is not working for me. What I could find from this issue is that I'm receiving InputMethod and InputMethodQuery events but no Key Event at all. Did it happen to you? Thanks in advance