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...



  • @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 :-).


Log in to reply
 

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