Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.8.6, 4.8.7, 5.3.1, 5.4.0 RC
-
None
-
OS X (all versions)
-
-
qt4: eb55d48d1035d06408ffe73696223464957aa71d Qt 5: 0647f24c7ddd73b1c4e273a71497f852573b4911
Description
QAction objects can be rendered with or without icon. There is a special switch, `IconVisibleInMenu` which controls whether that icon is to be rendered when the QAction is used as a menu item.
This switch is not checked properly when displaying a system tray menu (i.e. the context menu of a QSystemTrayIcon). The exact behaviour depends on the Qt version.
- Qt 4.8.6 does not check the switch at all, so systray menu items always show an icon if the QAction has one. This is easy to correct with a single additional test in QNSMenu:menuNeedsUpdate: (in qsystemtrayicon.mm). I've attached a patch, and a testcase based on the systray example.
- Qt 5.3 does respect the switch when adding a QAction to a menu, but fails to handle subsequent visibility changes properly. Specifically, there will be no icon shown if IconVisibleInMenu is false when the QAction is added to a menu. However, when it is set to false when the menu item already exist in the menu, the item will continue to show the last icon that was used.
I think that this is because QCocoaMenuItem::sync uses the same logic as QNSMenu:menuNeedsUpdate: used: it calls setImage: if there's a non-empty icon associated with the menu item without bothering to check if the icon should be shown:if (!m_icon.isNull()) { NSImage *img = qt_mac_create_nsimage(m_icon); [img setSize:NSMakeSize(16, 16)]; [m_native setImage: img]; [img release]; }
I am unable to build Qt 5.3 on OS X 10.6.8 so I cannot test a patch. Also, it looks like such a patch would require to add a reference to the QAction to the QCocoaMenuItem class (or proxy IconVisibleInMenu).
I've attached a Qt5 version of the systray-based test case.
The testcase bluntly adds an icon to the minimise menu action, visible initially following the relevant global setting. The icon is cycled like the systemtray icon, but is set to be invisible when the "bad" icon is selected.