Search code examples
macosqtminimizetrayicon

Minimize to tray on MacOSX


Good morning, in my application on MacOSX I want to give the user the option "minimize to tray". I use Qt5 and I rewrote the

changeEvent(QEvent *event)

function. There I do something like

switch( event->type() )
{
case QEvent::WindowStateChange:
    {
        if ( this->windowState() & Qt::WindowMinimized ) {
            if( *option minimize to tray enable* ) {
                event->ignore();
                QTimer::singleShot(0, this, SLOT(hide()));
            }
        }
        break;
    }
default:
    break;
}

Well, it works on Linux and Windows but the problem is that in MacOSX this code does not work properly and creates a bug. Indeed the window is still minimized in the taskbar (apart from the dock) and furthermore, if the window is resized from the taskbar instead of the tray icon, the GUI is blocked and does not change. The GUI can still send signals but it can not change. I have to reshow the window from the tray icon to unblock the GUI.

Then the question: How can I avoid to minimize the Window in the TaskBar on MacOSX?

Another related question: I have read some forum where some user speaks about a "standard behaviour" in MacOSX, as for example not to close the application when the "x" button is clicked, or not to use tray icon ecc. ecc.... Someone can post a official link how an application should behaves in MacOSX?

Thanks very much to everyone


Solution

  • Well, I don't know Qt, but I know Cocoa quite well. Speaking in terms of the Objective-C API, your hide() call is probably doing the equivalent of -orderOut:. Unfortunately, -orderOut: doesn't work properly for minimized windows. It leaves a "ghost" window in the Dock, which can be unminimized to an actual ghost window. That is, it's just an image of the window, it's not the actual live window.

    It does work to call -close. I don't know what the Qt equivalent would be. You have to be careful to avoid some of the secondary consequences that -close has beyond those of -orderOut:, though. For example, some windows are set to release themselves on close, which you'd want to disable. Also, the window delegate's -windowWillClose: method will be called and it should do nothing for a not-really-closing call.

    Don't worry that "closing" is more severe or permanent than "hiding" or "ordering out". It's really much the same thing, other than the above-mentioned additional consequences. For example, it is still possible to re-show a window that's been closed, etc.

    The question is, does Qt give you the flexibility to do it. Alternatively, this can be considered a bug in Qt, that its hide() implementation uses -orderOut: rather than -close on minimized windows.

    Finally, I'll ask if you really want to implement this feature. It's going to confuse users. When you minimize a window, it animates the minimization to the Dock. That gives the user a strong impression of where to find the window. If the window is not subsequently found where it went, the user is not going to know to look elsewhere. Likewise, Exposé/Mission Control shows users the minimized windows of an app in addition to the normal windows. Your supposedly minimized-to-tray windows won't show up there because they're no longer really minimized.

    Perhaps just disable minimization. Have the user simply close the window when they're done with it and re-open it from your status item menu.