Search code examples
qtevent-handlingwindowactivation

QT window ActivationChange event under linux


I have the following issue: I have a "splash" like window coming with my application and it has a few buttons on it for opening the last project, creating a new one, etc... On pressing, these buttons hide the window and do the stuff.

This window is created with the following code and flags:

void MainWindowButtonDialog::showMe()
{
    setModal(false);
    setWindowFlags(Qt::SplashScreen | Qt::CustomizeWindowHint |
                      Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
    show();
}

The window is called m_btnDlg.

Now, due to requests from the clients when the application loses focus I need to hide this window, and when the application gets focus I need to re-show it. This is done by the following code:

void MainWindow::changeEvent(QEvent *e)
{
    if( e->type() == QEvent::WindowStateChange )
    {
        if( isMinimized() )
        {
            if(m_btndlg && m_btndlg->isVisible())
            {
                m_btndlg->hide();
                m_splashWasVisible = true;
            }
        }
        else
        {
            if(m_splashWasVisible)
            {
                m_btndlg->show();
                m_splashWasVisible = false;
            }
        }
    }
    if(e->type() == QEvent::ActivationChange)
    {
        if(!isActiveWindow())
        {
            if(m_btndlg && m_btndlg->isVisible() && !m_btndlg->isActiveWindow())
            {
                m_btndlg->hide(); // *****
                m_splashWasVisible = true;
            }
        }
        else
        {
            if(m_splashWasVisible)
            {
                m_btndlg->show();
                m_splashWasVisible = false;
            }
        }
    }
    QMainWindow::changeEvent(e);
}

Now to the problem: the code above worked perfectly till now (both under Linux - Gnome 2.x on CentOS 5.x, and KDE 3.x and also Windows, all interesting versions). Recently the client has installed a few Fedora systems and Gnome 3, KDE 4, etc... suddenly the application behaves funnily. When I press the the button to create a new project it hides the splash window and nothing happens. The line marked with ** above is the one responsible. It seems that these new window managers send the activation events out of order.

Has anyone experience with this?

(More Code available on request). We use Qt 4.6.3 thanks.


Solution

  • You should try the application level events QEvent::ApplicationActivate and QEvent::ApplicationDeactivate with an event filter installed on qApp.
    These events are fired when the application focus changes or the application window is minimized.

    MainWindow::MainWindow() {
      qApp->installEventFilter(this);
    }
    
    bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
    {
        if(obj==qApp && ( evt->type() == QEvent::ApplicationActivate
                          || evt->type() == QEvent::ApplicationDeactivate))
        {
            bool shouldHide = evt->type() == QEvent::ApplicationDeactivate;
            if (shouldHide) {
                m_splashWasVisible = m_btndlg && m_btndlg->isVisible();
                if(m_splashWasVisible) 
                    m_btndlg->hide();
            } else {
                if(m_splashWasVisible) 
                    m_btndlg->show();
            }    
        }
        return QMainWindow::eventFilter(obj, evt);
    }
    

    Alternatively, you could display the splash window as part of the main window on top of all other widgets by setting the main window as its parent, and using QWidget::raise().