Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Focus problems when embedding a native window



  • Hello,
    In our application we embed content that is not necessarily Qt-based, such as WPF or custom windows (we don't control how these windows are created, we just receive a native handle).
    To do this, we use this kind of code:

    // In our widget embedding the non-Qt content
    m_window = QWindow::fromWinId((WId)hwnd);
    m_window->setFlags(Qt::FramelessWindowHint);
    m_window->show();
    m_windowContainer = QWidget::createWindowContainer(m_window, this, Qt::FramelessWindowHint);
    m_windowContainer->setParent(this);
    m_windowContainer->show();
    

    It seems to work fine, however we experience focus problems, such as mouse wheel not working.
    When the application is unfocused, then focused again by clicking first on our embedded window, it's like we clicked on the QMainWindow instead...
    By hooking the WindowProc of one of our HWND, we noticed it never receives WM_FOCUS back.

    We tried to override focusInEvent() in our widget, however it doesn't get any event, since the embedded content is placed in front of it...

    I know there are limitations when doing this, however that's not what I expected by reading the doc. I found several topics more or less related to this issue, but couldn't find an answer yet. Is there something to do we missed?


  • Moderators

    Hi,

    @Zylann said:

    It seems to work fine, however we experience focus problems, such as mouse wheel not working.
    When the application is unfocused, then focused again by clicking first on our embedded window, it's like we clicked on the QMainWindow instead...
    By hooking the WindowProc of one of our HWND, we noticed it nev

    Unfortunately, there are multiple issues with embedding external windows into QWidgets, but they're not being actively addressed. See https://bugreports.qt.io/browse/QTBUG-40320



  • @JKSH there might be a slight difference in my case actually:
    I'm not trying to embed a window from another application, but a HWND created by my own.
    Does it makes a difference, or the problem is the same?


  • Moderators

    @Zylann said:

    @JKSH there might be a slight difference in my case actually:
    I'm not trying to embed a window from another application, but a HWND created by my own.
    Does it makes a difference, or the problem is the same?

    Same problems. By "external", I meant "not made by Qt Widgets".



  • This thread is 4 years old, but I want to give a solution anyway.
    I spent the past 2 months trying to figure out how to do this, and all the threads I found are talking about issues but nobody gave me a solution.

    Actually, the QWidget you create has its own focus but is not "parent" of the HWND you are embedding on it, so you have to make the keyboard focus by yourself.

    The best way to do that is by using the SetFocus function of the winuser library (WinUser.h):
    https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setfocus

    Like, in example:

    m_qwindow	= QWindow::fromWinId(m_handle);
    m_widget	= QWidget::createWindowContainer(m_qwindow, this);
    
    // tell the os to focus the viewport window
    SetFocus(m_handle);
    

    with m_handle being the HWND (or WId) used to create the QWindow.

    Unfortunately, this solution works only on windows (but maybe there are equivalents on another os).
    It also doesn't work when clicking on the embedded window, because it isn't owned by Qt.
    maybe you can try to mess with QFocusFrame (I haven't tried this at all, but it should be a way to use it as a fix by putting it over the embedded window)
    or, if the window you are embedding is one of your creations, put the SetFocus() function in its code, as a callback when clicked.

    I hope that even with 4 years late, this solution is still helping the desperate developers like who I was the past two months.


Log in to reply