QSystemTrayIcon OSX questions



  • I've implemented QSystemTrayIcon for our app and it seems to work fine on Windows - the Minimize/Maximiz/Restore/Quit tray menu shows up when it is right clicked on and the app hides when closed and shows up when the icon is clicked. But the tray icon doesn't show up on the Mac and the hidden app doesn't show when the icon is clicked. Any known issues with the Mac and the QSystemTrayIcon object I should know about? Keep in mind, I don't know anything about the Mac, or even how it is supposed to behave on it.



  • On Mac OS X, the tray is usually the area in the top right corner of the main screen.

    The tray in OS X does not support min/max/hide functions, but provides a menu to common functions, that should be available, even when the app is not in the foreground (such as setting the status in some instant messaging program or something like that).

    Bringing the application to the forground/minimizing/maximizing is done in the Dock on the mac (the collection of icons, usually on the bottom of the main screen).

    This is a sample code that works for me:

    @
    QSystemTrayIcon *sti = new QSystemTrayIcon(this);

    QIcon xmediaIcon("/path/to/your/icon");
    sti->setIcon(xmediaIcon);
    sti->setVisible(true);

    QMenu *stiMenu = new QMenu(this);
    sti->setContextMenu(stiMenu);

    QAction *a1 = new QAction("tray menu item 1", this);
    stiMenu->addAction(a1);
    connect(a1, SIGNAL(triggered()), this, SLOT(action1Fired()));

    QAction *a2 = new QAction("tray menu item 2", this);
    stiMenu->addAction(a2);
    connect(a2, SIGNAL(triggered()), this, SLOT(action2Fired()));
    @



  • According to the Mac users, clicking on the icon in the Dock menu doesn't restore the app. Right click brings up the Mac system menu for dock apps.



  • What do you mean by "Dock menu"? I'm not aware of such a thing.

    The Mac OS X Dock is a collection of application icons and looks like this:

    !http://upload.wikimedia.org/wikipedia/en/7/79/Mac_OS_X_10.5_3D_Dock.png!

    If you want a custom menu to be shown when a user right-clicks on an icon in the dock, you can use "qt_mac_set_dock_menu() ":http://doc.qt.nokia.com/latest/exportedfunctions.html#void-qt-mac-set-dock-menu-qmenu-menu like this:

    @
    // This is available through a C++ function, but is not in a header,
    // so you need to extern it yourself
    extern void qt_mac_set_dock_menu(QMenu *menu);

    void MyClass::myFunction()
    {
    QMenu *dockMenu = new QMenu(this);
    // add some menu items and actions here

    qt_mac_set_dock_menu(dockMenu);
    

    }
    @

    On my OS X machine single left-click on an application or window icon in the doc starts the application respectively restores a previously hidden or minimized window.

    [edit: wrong wording, volker]



  • Sorry, that's what I meant - a single (or even double) left click on OS X Dock icon for my app doesn't bring it back up. If I select quit from the right click menu, it goes away, so there is something going on.



  • That's strange, as it is something that is handled by OS X itself. How does your app go out of focus? Do you hide the window (with Cmd-H) or do you close it (with Cmd-W)? If it is hidden, it should reappear. If it is closed, it can be that the application itself still runs, but has no window to show. Does the menu on the top of the screen change, when you left-click the icon in the dock? If yes, then your application is active but has no windows to show, if no something strange is going on.



  • I click the Close button on the app window, which I thought by default just hides a window (like it does on Windows). But maybe it actually closes the window? If I select "Hide" from the right click dock menu, it works fine. Do I need to do something special in order to not close the window on the Mac?



  • No, I take that back. The window handles the close event thusly:

    @void visimeet::closeEvent(QCloseEvent* event)
    {
    if (trayIcon->isVisible() && !qApp->closingDown()) {
    if ( trayWarning )
    {
    QMessageBox::information(this, tr("Visimeet"),
    tr("The program will keep running in the "
    "system tray. To terminate the program, "
    "choose <b>Quit</b> in the context menu "
    "of the system tray entry."));
    trayWarning = false;
    }

        hide();
        event->ignore();
    }
    

    }
    @

    And I get the warning message and the window goes away.



  • There seems to be a difference if the window is hidden programmatically with hide() or by the window system with Cmd-H. In the first case the window is hidden permanently and can only be restored with calling show() again, whereas in the second case the window can be restored by clicking on the dock icon.

    You can achieve a similar behaviour if you call showMinimized() instead of hide(). In this case you get an additional icon in the dock for the hidden window (in addition to the application's icon).



  • That's not really all that great though. That means that close & minimize work the same. It certainly isn't a desired behavior on Windows, as it stays in the task bar. Is this a Qt bug or can programs not hide themselves on the Mac?



  • Programs can hide themselves on the mac, just use hide(). The only drawback of this method is that they cannot be restored using the dock.

    You can of course add a menu to the dock icon, and in the slots, that menu is connected to, you can redisplay the window by calling show().

    How to do this in detail depends on your application design: do you have multiple main windows of the same type, multiple main windows of different types that can only be instantiated once, only one main window, etc.? This influences how and where the dock menu is populated and its actions are executed.



  • We just have a single main window. Guess I'm confused about the different places for where the icon shows up on the Mac.



  • Do you have a screenshot to illustrate what's drivin' you crazy?



  • I had a similar problem. I solved it by instead of calling hide() when the user clicks x (see tray sample) we call

    ProcessSerialNumber pn;
    GetFrontProcess (&pn);
    ShowHideProcess(&pn,false);

    Now the window is closed and clicking on the dock icon works as expected.


Log in to reply
 

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