Cannot forward key events to QQuickWindow



  • Hi all!

    Let me describe the situation before I proceed asking the actual question:

    1. I am using a QQuickWindow, QQuickRenderControl and a QOffscreenSurface to render a Qml scene into a OpenGL framebuffer object.
    2. 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:

    1. Focussing the QQuickWindow::contentItem(). This surpringly worked while having a debugger attached and having a breakpoint at a specific location in qquickwindow.cpp (lol).
    2. Spamming events of type FocusIn and FocusAboutToChange (absolutely no effect).
    3. 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!
    4. 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...


  • Moderators

    @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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.