Prevent Always On Top Window From Stealing Keyboard Focus



  • We have an application tailored to our clients that allows them to make the window restore with an "always on top" feature so that it stays on top and must be interacted with.

    This works as desired however in several cases this approach also steals keyboard focus, which is not desired.

    The following code is what we are using to invoke the always on top behavior. We have tried pretty much every variation we could find using Google, but we either end up fixing the keyboard focus issue and then break the always on top, or we maintain both features but then the window ends up in a frozen / bad state.

    void Monitor::alwaysOnTop(QWidget* mainWindow, bool enable)
    {
        mainWindow->showNormal();
    
        HWND hwnd = (HWND) mainWindow->winId();
        if (enable)
        {
            SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW);
        }
        else
        {
            SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW);
        }
    }
    

    What we've found is that the showNormal method seems to be what causes the keyboard focus to be stolen, but without it the window doesn't restore correctly from a minimized state.

    We've tried a bunch of the setAttributes, like the ones around no activation, we've tried different sequences of the calls, tried the focus policy, etc.

    Is it possible to invoke always on top functionality without stealing keyboard focus? If so, can anyone point us in the right direction? Thanks.



  • Just in case anyone is interested, we seemed to have solved our problem by switching back to the way we started using the Qt methods with setting flags as such:

    void Monitor::alwaysOnTop(QWidget* mainWindow, bool enable)
    {
        if (enable)
        {
            mainWindow->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
        }
        else
        {
            mainWindow->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Tool);
        }
    
       mainWindow->showNormal();
    }
    

    The key here is the Qt::Tool flag. This allows us to treat the window as a tooltip, which in effect isn't stealing the keyboard focus.


  • Qt Champions 2016

    @brixel
    Hi
    you did try setAttribute(Qt::WA_ShowWithoutActivating);
    but it did not help?



  • @mrjj

    Yes, we did try that, it did not work.


Log in to reply
 

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