Bring window to front -> raise(),show(),activateWindow() don't work on Windows



  • I open a URL in the default-browser.
    Afterwards I want to bring the main-window of my application to the front again.

    I tried all approaches I could find but none worked. All it does is blink in the taskbar (of Window 7)
    Here's an example:

    @this->viewer->show();
    this->viewer->raise();
    this->viewer->activateWindow();@



  • Why do you call viewer, not window instance?



  • I forgot to mention *viewer is a pointer to a QmlApplicationViewer which is derived from QDeclarativeView



  • Is the viewer a top-level window? Make sure it has no parent window.



  • It's the only window my program has.



  • In windows, an application can't rais itself in front of the currently active window and it can't pull the focus to itself :-(
    What you can do is make it topmost (--> brings it to front) and remove tompost flag afterwards. But it will not get the input focus.



  • I don't care about input-focus as I only want to know my user to see that amazing QML-animation I crafted (and see that they succeeded to authorize my application to use Twitter).

    How do I make it topmost?



  • You should try:

    @
    Qt::WindowFlags eFlags = windowFlags ();
    eFlags |= Qt::WindowStaysOnTopHint;
    setWindowFlags(eFlags);
    @

    and then remove it again



  • Ah thanks. That works.

    One general question though.
    How do I remove the flag? I'm not much familiar with bit by bit manipulation.



  • @
    eFlags &= ~Qt::WindowStaysOnTopHint;
    @



  • Thank you but there must be something wrong with this code.
    The window comes to the front and instantly gets hidden completely. It doesn't even show up in the taskbar anymore.

    @ Qt::WindowFlags eFlags = this->viewer->windowFlags();
    eFlags |= Qt::WindowStaysOnTopHint;
    this->viewer->setWindowFlags(eFlags);
    this->viewer->show();
    eFlags &= ~Qt::WindowStaysOnTopHint;
    this->viewer->setWindowFlags(eFlags);@



  • If you will look into assistant you will find there next info
    "Note: This function calls setParent() when changing the flags for a window, causing the widget to be hidden. You must call show() to make the widget visible again."

    So you need to call show() again after second setWindowFlags()



  • Ah, sorry.

    The problem is that the window is behind the browser again after calling show() so if there isn't another solution I can only keep the window topmost (not really an option).



  • you can do it with windows API:

    @
    ::SetWindowPos(winID(), HWND_TOP, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)
    @

    If this does not work, first call it with HWND_TOPMOST, and then this one.



  • Do I need to trigger something else as well?

    I tried:

    @ SetWindowPos(this->viewer->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    SetWindowPos(this->viewer->winId(), HWND_TOP, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);@

    but nothing happened.



  • Hi Hege,

    I digged a bit, this is what I did:

    @
    // HACK: bringing window to top
    // from QT documentation:
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // void QWidget::activateWindow ()
    // ...
    // On Windows, if you are calling this when the application is not currently
    // the active one then it will not make it the active window. It will change
    // the color of the taskbar entry to indicate that the window has changed in
    // some way. This is because Microsoft do not allow an application to
    // interrupt what the user is currently doing in another application.
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // This hack does not give the focus to the app but brings it to front so
    // the user sees it.
    ::SetWindowPos(effectiveWinId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    ::SetWindowPos(effectiveWinId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    // HACK END

        raise();
        show();
        activateWindow();
    

    @

    This brings the window to front. Is your browser perhaps a topmost window? Or a child of yours?



  • Hmm that doesn't work either.

    My browser is opened via QDesktopServices like this:

    @QDesktopServices::openUrl(openWebPageUrl);@



  • perhaps that makes it a child of your window and therefore on top of your app.
    Can you bring your window to front by mouse?



  • If the browser is not maximized, yes.



  • I would kick out the native browser and put everything in a "QWebView":http://doc.qt.nokia.com/4.7/qwebview.html. You have control of the window then.

    Is there anything that hinders you from doing it this way (despite having to pack QtWebkit.dll and bloating the package)?



  • I would re-think the design criteria. There is a reason window managers don't allow windows of not-active applications to put themselves at the foreground. Why try to circumvent that? What makes your application so super-extra-special that it would need to go around these intentional limitations?



  • @Volker:
    I still work on z/OS and like my applications slim, so having a QtWebkit just for that purpose isn't an option.

    @Ander:
    My application isn't super special but it brings the browser in front of itself as well. It would be ok if it was possible to start the browser behind it (my application is only like 300 x 400 pixels, not resizeable).

    An option would be to keep it topmost until the user either allows access to Twitter via oAuth v1 or the request times out but I don't really want to play with the topmost-property as that is what I consider a design-fault.



  • Maybe "QTextBrowser":http://doc.qt.nokia.com/4.7/qtextbrowser.html fits your needs already. It does not need webkit and is included in QtGui module, that you need anyways.



  • Good idea, but the user needs to click on a button (image) on the webpage that opens to authorize my application to aborminate his Twitter-account.



  • The text browser class does not handle network access by default, so you would have to add this yourself. I don't know if that's worth the effort. I personally would just include webkit and don't care for the size of the application (bandwidth is barely a problem nowadays...)



  • To start the browser in background why don't you try something like this ?

    @
    QLabel* label = new QLabel("Hi");
    label->show();

    QProcess* p = new QProcess();
    QObject::connect(p,SIGNAL(started()),label,SLOT(raise()));
    p->start("firefox");
    @

    So as soon as the browser starts your application will be brought to front.

    EDIT: Replace raise() with your customized function which you're using to bring window to top.



  • @situ117:

    I don't know how that works with the users default browser.

    @Volker:

    The tool is 1.2 MB right now (.NET, I know that doesn't cut) and was 1.8MB when I coded it first in Object Pascal (yeah I really wrote it three times).

    The Qt-Version on Windows is 7.5MB due to my custom dll's. The users are likely to ask how I justify that increased size. I really want it to be as small as possible.



  • I'd say having it cross platform does count :-)


Log in to reply
 

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