summaryrefslogtreecommitdiffstats
path: root/src/widgets/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/util')
-rw-r--r--src/widgets/util/qcompleter.cpp50
-rw-r--r--src/widgets/util/qcompleter_p.h4
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp29
-rw-r--r--src/widgets/util/qsystemtrayicon_win.cpp600
-rw-r--r--src/widgets/util/util.pri4
5 files changed, 62 insertions, 625 deletions
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 3a287c5fa4..d444fe6053 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -158,6 +158,7 @@
#include "QtWidgets/qapplication.h"
#include "QtGui/qevent.h"
#include "QtWidgets/qdesktopwidget.h"
+#include <private/qdesktopwidget_p.h>
#if QT_CONFIG(lineedit)
#include "QtWidgets/qlineedit.h"
#endif
@@ -496,18 +497,25 @@ QMatchData QCompletionEngine::filterHistory()
}
// Returns a match hint from the cache by chopping the search string
-bool QCompletionEngine::matchHint(QString part, const QModelIndex& parent, QMatchData *hint)
+bool QCompletionEngine::matchHint(const QString &part, const QModelIndex &parent, QMatchData *hint) const
{
- if (c->cs == Qt::CaseInsensitive)
- part = std::move(part).toLower();
+ if (part.isEmpty())
+ return false; // early out to avoid cache[parent] lookup costs
- const CacheItem& map = cache[parent];
+ const auto cit = cache.find(parent);
+ if (cit == cache.end())
+ return false;
+
+ const CacheItem& map = *cit;
+ const auto mapEnd = map.end();
+
+ QString key = c->cs == Qt::CaseInsensitive ? part.toLower() : part;
- QString key = part;
while (!key.isEmpty()) {
key.chop(1);
- if (map.contains(key)) {
- *hint = map[key];
+ const auto it = map.find(key);
+ if (it != mapEnd) {
+ *hint = *it;
return true;
}
}
@@ -515,15 +523,25 @@ bool QCompletionEngine::matchHint(QString part, const QModelIndex& parent, QMatc
return false;
}
-bool QCompletionEngine::lookupCache(QString part, const QModelIndex& parent, QMatchData *m)
+bool QCompletionEngine::lookupCache(const QString &part, const QModelIndex &parent, QMatchData *m) const
{
- if (c->cs == Qt::CaseInsensitive)
- part = std::move(part).toLower();
- const CacheItem& map = cache[parent];
- if (!map.contains(part))
- return false;
- *m = map[part];
- return true;
+ if (part.isEmpty())
+ return false; // early out to avoid cache[parent] lookup costs
+
+ const auto cit = cache.find(parent);
+ if (cit == cache.end())
+ return false;
+
+ const CacheItem& map = *cit;
+
+ const QString key = c->cs == Qt::CaseInsensitive ? part.toLower() : part;
+
+ const auto it = map.find(key);
+ if (it == map.end())
+ return false;
+
+ *m = it.value();
+ return true;
}
// When the cache size exceeds 1MB, it clears out about 1/2 of the cache.
@@ -905,7 +923,7 @@ void QCompleterPrivate::_q_autoResizePopup()
void QCompleterPrivate::showPopup(const QRect& rect)
{
- const QRect screen = QApplication::desktop()->availableGeometry(widget);
+ const QRect screen = QDesktopWidgetPrivate::availableGeometry(widget);
Qt::LayoutDirection dir = widget->layoutDirection();
QPoint pos;
int rh, w;
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
index 5b89f9d8b5..e76dcdc8bc 100644
--- a/src/widgets/util/qcompleter_p.h
+++ b/src/widgets/util/qcompleter_p.h
@@ -153,10 +153,10 @@ public:
void filter(const QStringList &parts);
QMatchData filterHistory();
- bool matchHint(QString, const QModelIndex&, QMatchData*);
+ bool matchHint(const QString &part, const QModelIndex &parent, QMatchData *m) const;
void saveInCache(QString, const QModelIndex&, const QMatchData&);
- bool lookupCache(QString part, const QModelIndex& parent, QMatchData *m);
+ bool lookupCache(const QString &part, const QModelIndex &parent, QMatchData *m) const;
virtual void filterOnDemand(int) { }
virtual QMatchData filter(const QString&, const QModelIndex&, int) = 0;
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index f7d048edcd..447c7b2aeb 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -61,8 +61,12 @@
#include "qgridlayout.h"
#include "qapplication.h"
#include "qdesktopwidget.h"
+#include <private/qdesktopwidget_p.h>
#include "qbitmap.h"
+#include <private/qhighdpiscaling_p.h>
+#include <qpa/qplatformscreen.h>
+
QT_BEGIN_NAMESPACE
static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon)
@@ -198,8 +202,23 @@ QSystemTrayIcon::~QSystemTrayIcon()
void QSystemTrayIcon::setContextMenu(QMenu *menu)
{
Q_D(QSystemTrayIcon);
+ QMenu *oldMenu = d->menu.data();
d->menu = menu;
d->updateMenu_sys();
+ if (oldMenu != menu && d->qpa_sys) {
+ // Show the QMenu-based menu for QPA plugins that do not provide native menus
+ if (oldMenu && !oldMenu->platformMenu())
+ QObject::disconnect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, menu, nullptr);
+ if (menu && !menu->platformMenu()) {
+ QObject::connect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested,
+ menu,
+ [menu](QPoint globalNativePos, const QPlatformScreen *platformScreen)
+ {
+ QScreen *screen = platformScreen ? platformScreen->screen() : nullptr;
+ menu->popup(QHighDpi::fromNativePixels(globalNativePos, screen), nullptr);
+ });
+ }
+ }
}
/*!
@@ -325,7 +344,9 @@ bool QSystemTrayIcon::event(QEvent *e)
\value Unknown Unknown reason
\value Context The context menu for the system tray entry was requested
- \value DoubleClick The system tray entry was double clicked
+ \value DoubleClick The system tray entry was double clicked. \note On macOS, a
+ double click will only be emitted if no context menu is set, since the menu
+ opens on mouse press
\value Trigger The system tray entry was clicked
\value MiddleClick The system tray entry was clicked with the middle mouse button
@@ -350,7 +371,7 @@ bool QSystemTrayIcon::event(QEvent *e)
Currently this signal is not sent on \macos.
- \note We follow Microsoft Windows XP/Vista behavior, so the
+ \note We follow Microsoft Windows behavior, so the
signal is also emitted when the user clicks on a tray icon with
a balloon message displayed.
@@ -517,7 +538,7 @@ QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title,
msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
// smart size for the message label
- int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3;
+ int limit = QDesktopWidgetPrivate::availableGeometry(msgLabel).size().width() / 3;
if (msgLabel->sizeHint().width() > limit) {
msgLabel->setWordWrap(true);
if (msgLabel->sizeHint().width() > limit) {
@@ -584,7 +605,7 @@ void QBalloonTip::resizeEvent(QResizeEvent *ev)
void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
{
this->showArrow = showArrow;
- QRect scr = QApplication::desktop()->screenGeometry(pos);
+ QRect scr = QDesktopWidgetPrivate::screenGeometry(pos);
QSize sh = sizeHint();
const int border = 1;
const int ah = 18, ao = 18, aw = 18, rc = 7;
diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp
deleted file mode 100644
index 3f007f24c1..0000000000
--- a/src/widgets/util/qsystemtrayicon_win.cpp
+++ /dev/null
@@ -1,600 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsystemtrayicon_p.h"
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#if defined(_WIN32_IE) && _WIN32_IE < 0x0600
-# undef _WIN32_IE
-#endif
-#if !defined(_WIN32_IE)
-# define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE
-#endif
-
-#include <private/qsystemlibrary_p.h>
-#include <private/qguiapplication_p.h>
-#include <private/qhighdpiscaling_p.h>
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qplatformscreen.h>
-#include <QSettings>
-#include <QDebug>
-#include <QHash>
-
-#include <qt_windows.h>
-#include <commctrl.h>
-#include <windowsx.h>
-
-QT_BEGIN_NAMESPACE
-
-static const UINT q_uNOTIFYICONID = 0;
-
-static uint MYWM_TASKBARCREATED = 0;
-#define MYWM_NOTIFYICON (WM_APP+101)
-
-struct Q_NOTIFYICONIDENTIFIER {
- DWORD cbSize;
- HWND hWnd;
- UINT uID;
- GUID guidItem;
-};
-
-#ifndef NIN_KEYSELECT
-# define NIN_KEYSELECT (WM_USER + 1)
-#endif
-
-#ifdef Q_CC_MINGW
-# define NIN_SELECT (WM_USER + 0)
-# define NIN_BALLOONTIMEOUT (WM_USER + 4)
-# define NIN_BALLOONUSERCLICK (WM_USER + 5)
-# define NIF_SHOWTIP 0x00000080
-# define NIIF_LARGE_ICON 0x00000020
-# define NOTIFYICON_VERSION_4 4
-#endif
-
-#define Q_MSGFLT_ALLOW 1
-
-Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &);
-
-typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation);
-typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag);
-typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct);
-
-// Copy QString data to a limited wchar_t array including \0.
-static inline void qStringToLimitedWCharArray(QString in, wchar_t *target, int maxLength)
-{
- const int length = qMin(maxLength - 1, in.size());
- if (length < in.size())
- in.truncate(length);
- in.toWCharArray(target);
- target[length] = wchar_t(0);
-}
-
-class QSystemTrayIconSys
-{
-public:
- QSystemTrayIconSys(HWND hwnd, QSystemTrayIcon *object);
- ~QSystemTrayIconSys();
- bool trayMessage(DWORD msg);
- void setIconContents(NOTIFYICONDATA &data);
- bool showMessage(const QString &title, const QString &message, const QIcon &icon, uint uSecs);
- QRect findIconGeometry(UINT iconId);
- HICON createIcon();
- bool winEvent(MSG *m, long *result);
-
-private:
- const HWND m_hwnd;
- HICON hIcon;
- QPoint globalPos;
- QSystemTrayIcon *q;
- uint notifyIconSize;
- int version;
- bool ignoreNextMouseRelease;
-};
-
-static bool allowsMessages()
-{
-#ifndef QT_NO_SETTINGS
- const QString key = QStringLiteral("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced");
- const QSettings settings(key, QSettings::NativeFormat);
- return settings.value(QStringLiteral("EnableBalloonTips"), true).toBool();
-#else
- return false;
-#endif
-}
-
-typedef QHash<HWND, QSystemTrayIconSys *> HandleTrayIconHash;
-
-Q_GLOBAL_STATIC(HandleTrayIconHash, handleTrayIconHash)
-
-extern "C" LRESULT QT_WIN_CALLBACK qWindowsTrayconWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- if (message == MYWM_TASKBARCREATED || message == MYWM_NOTIFYICON) {
- if (QSystemTrayIconSys *trayIcon = handleTrayIconHash()->value(hwnd)) {
- MSG msg;
- msg.hwnd = hwnd; // re-create MSG structure
- msg.message = message; // time and pt fields ignored
- msg.wParam = wParam;
- msg.lParam = lParam;
- msg.pt.x = GET_X_LPARAM(lParam);
- msg.pt.y = GET_Y_LPARAM(lParam);
- long result = 0;
- if (trayIcon->winEvent(&msg, &result))
- return result;
- }
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
-}
-
-// Invoke a service of the native Windows interface to create
-// a non-visible toplevel window to receive tray messages.
-// Note: Message windows (HWND_MESSAGE) are not sufficient, they
-// will not receive the "TaskbarCreated" message.
-static inline HWND createTrayIconMessageWindow()
-{
- QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
- if (!ni)
- return 0;
- // Register window class in the platform plugin.
- QString className;
- void *wndProc = reinterpret_cast<void *>(qWindowsTrayconWndProc);
- if (!QMetaObject::invokeMethod(ni, "registerWindowClass", Qt::DirectConnection,
- Q_RETURN_ARG(QString, className),
- Q_ARG(QString, QStringLiteral("QTrayIconMessageWindowClass")),
- Q_ARG(void *, wndProc))) {
- return 0;
- }
- const wchar_t windowName[] = L"QTrayIconMessageWindow";
- return CreateWindowEx(0, (wchar_t*)className.utf16(),
- windowName, WS_OVERLAPPED,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
-}
-
-QSystemTrayIconSys::QSystemTrayIconSys(HWND hwnd, QSystemTrayIcon *object)
- : m_hwnd(hwnd), hIcon(0), q(object)
- , notifyIconSize(sizeof(NOTIFYICONDATA)), version(NOTIFYICON_VERSION_4)
- , ignoreNextMouseRelease(false)
-
-{
- handleTrayIconHash()->insert(m_hwnd, this);
-
- if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA) {
- notifyIconSize = NOTIFYICONDATA_V2_SIZE;
- version = NOTIFYICON_VERSION;
- }
-
- // For restoring the tray icon after explorer crashes
- if (!MYWM_TASKBARCREATED) {
- MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
- }
-
- // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows 7 and higher
- static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx =
- (PtrChangeWindowMessageFilterEx)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx");
-
- if (pChangeWindowMessageFilterEx) {
- // Call the safer ChangeWindowMessageFilterEx API if available (Windows 7 onwards)
- pChangeWindowMessageFilterEx(m_hwnd, MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0);
- } else {
- // Call the deprecated ChangeWindowMessageFilter API otherwise (Vista onwards)
- // May 2016: Still resolved at runtime since the definition is not present in MinGW 4.9.
- // TODO: Replace by direct invocation when upgrading MinGW.
- static PtrChangeWindowMessageFilter pChangeWindowMessageFilter =
- (PtrChangeWindowMessageFilter)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter");
-
- if (pChangeWindowMessageFilter)
- pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW);
- }
-}
-
-QSystemTrayIconSys::~QSystemTrayIconSys()
-{
- handleTrayIconHash()->remove(m_hwnd);
- if (hIcon)
- DestroyIcon(hIcon);
- DestroyWindow(m_hwnd);
-}
-
-void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd)
-{
- tnd.uFlags |= NIF_MESSAGE | NIF_ICON | NIF_TIP;
- tnd.uCallbackMessage = MYWM_NOTIFYICON;
- tnd.hIcon = hIcon;
- const QString tip = q->toolTip();
- if (!tip.isNull())
- qStringToLimitedWCharArray(tip, tnd.szTip, sizeof(tnd.szTip)/sizeof(wchar_t));
-}
-
-bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, const QIcon &icon, uint uSecs)
-{
- NOTIFYICONDATA tnd;
- memset(&tnd, 0, notifyIconSize);
- qStringToLimitedWCharArray(message, tnd.szInfo, 256);
- qStringToLimitedWCharArray(title, tnd.szInfoTitle, 64);
-
- tnd.uID = q_uNOTIFYICONID;
- tnd.dwInfoFlags = NIIF_USER;
-
- HICON *phIcon = &tnd.hIcon;
- QSize size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
- if (version == NOTIFYICON_VERSION_4) {
- const QSize largeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
- QSize more = icon.actualSize(largeIcon);
- if (more.height() > (largeIcon.height() * 3/4) || more.width() > (largeIcon.width() * 3/4)) {
- tnd.dwInfoFlags |= NIIF_LARGE_ICON;
- size = largeIcon;
- }
- phIcon = &tnd.hBalloonIcon;
- }
- QPixmap pm = icon.pixmap(size);
- if (pm.isNull()) {
- tnd.dwInfoFlags = NIIF_INFO;
- } else {
- if (pm.size() != size) {
- qWarning("QSystemTrayIcon::showMessage: Wrong icon size (%dx%d), please add standard one: %dx%d",
- pm.size().width(), pm.size().height(), size.width(), size.height());
- pm = pm.scaled(size, Qt::IgnoreAspectRatio);
- }
- *phIcon = qt_pixmapToWinHICON(pm);
- }
- tnd.cbSize = notifyIconSize;
- tnd.uVersion = version;
- tnd.hWnd = m_hwnd;
- tnd.uTimeout = uSecs;
- tnd.uFlags = NIF_INFO | NIF_SHOWTIP;
-
- return Shell_NotifyIcon(NIM_MODIFY, &tnd);
-}
-
-bool QSystemTrayIconSys::trayMessage(DWORD msg)
-{
- NOTIFYICONDATA tnd;
- memset(&tnd, 0, notifyIconSize);
-
- tnd.uID = q_uNOTIFYICONID;
- tnd.cbSize = notifyIconSize;
- tnd.hWnd = m_hwnd;
- tnd.uFlags = NIF_SHOWTIP;
- tnd.uVersion = version;
-
- if (msg == NIM_ADD || msg == NIM_MODIFY) {
- setIconContents(tnd);
- }
-
- bool success = Shell_NotifyIcon(msg, &tnd);
-
- if (msg == NIM_ADD)
- return success && Shell_NotifyIcon(NIM_SETVERSION, &tnd);
- else
- return success;
-}
-
-HICON QSystemTrayIconSys::createIcon()
-{
- const HICON oldIcon = hIcon;
- hIcon = 0;
- const QIcon icon = q->icon();
- if (icon.isNull())
- return oldIcon;
- const QSize requestedSize = QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA
- ? QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON))
- : QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
- const QSize size = icon.actualSize(requestedSize);
- const QPixmap pm = icon.pixmap(size);
- if (pm.isNull())
- return oldIcon;
- hIcon = qt_pixmapToWinHICON(pm);
- return oldIcon;
-}
-
-bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
-{
- *result = 0;
- switch(m->message) {
- case MYWM_NOTIFYICON:
- {
- int message = 0;
- QPoint gpos;
-
- if (version == NOTIFYICON_VERSION_4) {
- Q_ASSERT(q_uNOTIFYICONID == HIWORD(m->lParam));
- message = LOWORD(m->lParam);
- gpos = QPoint(GET_X_LPARAM(m->wParam), GET_Y_LPARAM(m->wParam));
- // Drop this chunk when merging to 5.10; code has been moved to Windows QPA.
- if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) {
- if (const QPlatformScreen *screen = primaryScreen->handle()->screenForPosition(gpos)) {
- gpos = QHighDpi::fromNative(gpos, QHighDpiScaling::factor(screen),
- screen->geometry().topLeft());
- }
- }
- } else {
- Q_ASSERT(q_uNOTIFYICONID == m->wParam);
- message = m->lParam;
- gpos = QCursor::pos();
- }
-
- switch (message) {
- case NIN_SELECT:
- case NIN_KEYSELECT:
- if (ignoreNextMouseRelease)
- ignoreNextMouseRelease = false;
- else
- emit q->activated(QSystemTrayIcon::Trigger);
- break;
-
- case WM_LBUTTONDBLCLK:
- ignoreNextMouseRelease = true; // Since DBLCLICK Generates a second mouse
- // release we must ignore it
- emit q->activated(QSystemTrayIcon::DoubleClick);
- break;
-
- case WM_CONTEXTMENU:
- if (q->contextMenu()) {
- q->contextMenu()->popup(gpos);
- q->contextMenu()->activateWindow();
- }
- emit q->activated(QSystemTrayIcon::Context);
- break;
-
- case NIN_BALLOONUSERCLICK:
- emit q->messageClicked();
- break;
-
- case WM_MBUTTONUP:
- emit q->activated(QSystemTrayIcon::MiddleClick);
- break;
-
- default:
- break;
- }
- break;
- }
- default:
- if (m->message == MYWM_TASKBARCREATED) // self-registered message id.
- trayMessage(NIM_ADD);
- break;
- }
- return false;
-}
-
-QSystemTrayIconPrivate::QSystemTrayIconPrivate()
- : sys(0),
- visible(false)
-{
-}
-
-QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
-{
-}
-
-void QSystemTrayIconPrivate::install_sys()
-{
- Q_Q(QSystemTrayIcon);
- if (!sys) {
- if (const HWND hwnd = createTrayIconMessageWindow()) {
- sys = new QSystemTrayIconSys(hwnd, q);
- sys->createIcon();
- sys->trayMessage(NIM_ADD);
- } else {
- qWarning("The platform plugin failed to create a message window.");
- }
- }
-}
-
-/*
-* This function tries to determine the icon geometry from the tray
-*
-* If it fails an invalid rect is returned.
-*/
-
-QRect QSystemTrayIconSys::findIconGeometry(UINT iconId)
-{
- struct AppData
- {
- HWND hwnd;
- UINT uID;
- };
-
- // Windows 7 onwards.
- static PtrShell_NotifyIconGetRect Shell_NotifyIconGetRect =
- (PtrShell_NotifyIconGetRect)QSystemLibrary::resolve(QLatin1String("shell32"),
- "Shell_NotifyIconGetRect");
-
- if (Shell_NotifyIconGetRect) {
- Q_NOTIFYICONIDENTIFIER nid;
- memset(&nid, 0, sizeof(nid));
- nid.cbSize = sizeof(nid);
- nid.hWnd = m_hwnd;
- nid.uID = iconId;
-
- RECT rect;
- HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect);
- if (SUCCEEDED(hr)) {
- return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
- }
- }
-
- QRect ret;
-
- TBBUTTON buttonData;
- DWORD processID = 0;
- HWND trayHandle = FindWindow(L"Shell_TrayWnd", NULL);
-
- //find the toolbar used in the notification area
- if (trayHandle) {
- trayHandle = FindWindowEx(trayHandle, NULL, L"TrayNotifyWnd", NULL);
- if (trayHandle) {
- HWND hwnd = FindWindowEx(trayHandle, NULL, L"SysPager", NULL);
- if (hwnd) {
- hwnd = FindWindowEx(hwnd, NULL, L"ToolbarWindow32", NULL);
- if (hwnd)
- trayHandle = hwnd;
- }
- }
- }
-
- if (!trayHandle)
- return ret;
-
- GetWindowThreadProcessId(trayHandle, &processID);
- if (processID <= 0)
- return ret;
-
- HANDLE trayProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, 0, processID);
- if (!trayProcess)
- return ret;
-
- int buttonCount = SendMessage(trayHandle, TB_BUTTONCOUNT, 0, 0);
- LPVOID data = VirtualAllocEx(trayProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
-
- if ( buttonCount < 1 || !data ) {
- CloseHandle(trayProcess);
- return ret;
- }
-
- //search for our icon among all toolbar buttons
- for (int toolbarButton = 0; toolbarButton < buttonCount; ++toolbarButton ) {
- SIZE_T numBytes = 0;
- AppData appData = { 0, 0 };
- SendMessage(trayHandle, TB_GETBUTTON, toolbarButton , (LPARAM)data);
-
- if (!ReadProcessMemory(trayProcess, data, &buttonData, sizeof(TBBUTTON), &numBytes))
- continue;
-
- if (!ReadProcessMemory(trayProcess, (LPVOID) buttonData.dwData, &appData, sizeof(AppData), &numBytes))
- continue;
-
- bool isHidden = buttonData.fsState & TBSTATE_HIDDEN;
-
- if (m_hwnd == appData.hwnd && appData.uID == iconId && !isHidden) {
- SendMessage(trayHandle, TB_GETITEMRECT, toolbarButton , (LPARAM)data);
- RECT iconRect = {0, 0, 0, 0};
- if(ReadProcessMemory(trayProcess, data, &iconRect, sizeof(RECT), &numBytes)) {
- MapWindowPoints(trayHandle, NULL, (LPPOINT)&iconRect, 2);
- QRect geometry(iconRect.left + 1, iconRect.top + 1,
- iconRect.right - iconRect.left - 2,
- iconRect.bottom - iconRect.top - 2);
- if (geometry.isValid())
- ret = geometry;
- break;
- }
- }
- }
- VirtualFreeEx(trayProcess, data, 0, MEM_RELEASE);
- CloseHandle(trayProcess);
- return ret;
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &title,
- const QString &messageIn,
- const QIcon &icon,
- QSystemTrayIcon::MessageIcon,
- int timeOut)
-{
- if (!sys || !allowsMessages())
- return;
-
- // 10 sec default
- const uint uSecs = timeOut < 0 ? uint(10000) : uint(timeOut);
- // For empty messages, ensures that they show when only title is set
- QString message = messageIn;
- if (message.isEmpty() && !title.isEmpty())
- message.append(QLatin1Char(' '));
-
- sys->showMessage(title, message, icon, uSecs);
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- if (!sys)
- return QRect();
-
- return sys->findIconGeometry(q_uNOTIFYICONID);
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
- if (!sys)
- return;
-
- sys->trayMessage(NIM_DELETE);
- delete sys;
- sys = 0;
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
- if (!sys)
- return;
-
- const HICON hIconToDestroy = sys->createIcon();
- sys->trayMessage(NIM_MODIFY);
-
- if (hIconToDestroy)
- DestroyIcon(hIconToDestroy);
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
-#if QT_CONFIG(menu)
-#endif
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
- if (!sys)
- return;
-
- sys->trayMessage(NIM_MODIFY);
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return true;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return allowsMessages();
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
index 0b654bbadd..a3bd8897f1 100644
--- a/src/widgets/util/util.pri
+++ b/src/widgets/util/util.pri
@@ -49,9 +49,7 @@ qtConfig(undoview) {
SOURCES += util/qundoview.cpp
}
-win32:!winrt {
- SOURCES += util/qsystemtrayicon_win.cpp
-} else: qtConfig(xcb) {
+qtConfig(xcb) {
SOURCES += util/qsystemtrayicon_x11.cpp
} else {
SOURCES += util/qsystemtrayicon_qpa.cpp