Unify behavior of QSystemTrayIcon::geometry for hidden icons on Windows

When a system tray icon on Windows wasn't visible (hidden behind the ^
icon in the task bar) our previous implementation gave different
results on Windows 10 and Windows 11.

On Windows 10 the geometry returned the geometry of the ^ icon itself
while we returned a geometry outside of the screen geometry on Windows
11 (that was what the Windows API gave us).

We work around this problem by using version specific hacks to be able
to check for the visibility of the system tray icon itself. If the icon
is hidden we just return QRect().

[ChangeLog][Windows] The geometry of a hidden QSystemTrayIcon was
unified over different Windows versions. It will always return QRect()
now.

Change-Id: Iee7dea184936a13a9221df9c421400ba304a4c38
Reviewed-by: Miguel Costa <miguel.costa@qt.io>
This commit is contained in:
Oliver Wolff 2024-03-28 07:22:43 +01:00
parent 8013b643c2
commit ca851b3317
2 changed files with 27 additions and 0 deletions

View File

@ -184,6 +184,9 @@ void QWindowsSystemTrayIcon::updateToolTip(const QString &tooltip)
QRect QWindowsSystemTrayIcon::geometry() const
{
if (!isIconVisible())
return QRect();
NOTIFYICONIDENTIFIER nid;
memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
@ -307,6 +310,29 @@ bool QWindowsSystemTrayIcon::setIconVisible(bool visible)
return Shell_NotifyIcon(NIM_MODIFY, &tnd) == TRUE;
}
bool QWindowsSystemTrayIcon::isIconVisible() const
{
NOTIFYICONIDENTIFIER nid;
memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
nid.hWnd = m_hwnd;
nid.uID = q_uNOTIFYICONID;
RECT rect;
const HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect);
// Windows 10 returns S_FALSE if the icon is hidden
if (FAILED(hr) || hr == S_FALSE)
return false;
HMONITOR monitor = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
// Windows 11 seems to return a geometry outside of the current monitor's geometry in case of
// the icon being hidden. As it's impossible to change the alignment of the task bar on Windows
// 11 this check should be fine.
return rect.bottom <= info.rcMonitor.bottom;
}
bool QWindowsSystemTrayIcon::sendTrayMessage(DWORD msg)
{
NOTIFYICONDATA tnd;

View File

@ -49,6 +49,7 @@ private:
void ensureCleanup();
bool sendTrayMessage(DWORD msg);
bool setIconVisible(bool visible);
bool isIconVisible() const;
HICON createIcon(const QIcon &icon);
QIcon m_icon;