src/gui/util/qsystemtrayicon_win.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qsystemtrayicon_p.h"
       
    43 #ifndef QT_NO_SYSTEMTRAYICON
       
    44 #define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE
       
    45 
       
    46 //missing defines for MINGW :
       
    47 #ifndef NIN_BALLOONTIMEOUT
       
    48 #define NIN_BALLOONTIMEOUT  (WM_USER + 4)
       
    49 #endif
       
    50 #ifndef NIN_BALLOONUSERCLICK
       
    51 #define NIN_BALLOONUSERCLICK (WM_USER + 5)
       
    52 #endif
       
    53 
       
    54 #include <qt_windows.h>
       
    55 #include <commctrl.h>
       
    56 #include <shlwapi.h>
       
    57 #include <QBitmap>
       
    58 #include <QLibrary>
       
    59 #include <QApplication>
       
    60 #include <QToolTip>
       
    61 #include <QDesktopWidget>
       
    62 #include <QSettings>
       
    63 
       
    64 #if defined(Q_WS_WINCE) && !defined(STANDARDSHELL_UI_MODEL)
       
    65 #   include <streams.h>
       
    66 #endif
       
    67 
       
    68 QT_BEGIN_NAMESPACE
       
    69 
       
    70 #if defined(Q_WS_WINCE)
       
    71 static const UINT q_uNOTIFYICONID = 13;     // IDs from 0 to 12 are reserved on WinCE.
       
    72 #else
       
    73 static const UINT q_uNOTIFYICONID = 0;
       
    74 #endif
       
    75 
       
    76 static uint MYWM_TASKBARCREATED = 0;
       
    77 #define MYWM_NOTIFYICON (WM_APP+101)
       
    78 
       
    79 struct Q_NOTIFYICONIDENTIFIER {
       
    80     DWORD cbSize;
       
    81     HWND hWnd;
       
    82     UINT uID;
       
    83     GUID guidItem;
       
    84 };
       
    85 
       
    86 typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation);
       
    87 
       
    88 class QSystemTrayIconSys : QWidget
       
    89 {
       
    90 public:
       
    91     QSystemTrayIconSys(QSystemTrayIcon *object);
       
    92     ~QSystemTrayIconSys();
       
    93     bool winEvent( MSG *m, long *result );
       
    94     bool trayMessage(DWORD msg);
       
    95     bool iconDrawItem(LPDRAWITEMSTRUCT lpdi);
       
    96     void setIconContents(NOTIFYICONDATA &data);
       
    97     bool showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs);
       
    98     bool allowsMessages();
       
    99     bool supportsMessages();
       
   100     QRect findIconGeometry(const int a_iButtonID);
       
   101     void createIcon();
       
   102     HICON hIcon;
       
   103     QPoint globalPos;
       
   104     QSystemTrayIcon *q;
       
   105 private:
       
   106     uint notifyIconSize;
       
   107     int maxTipLength;
       
   108     bool ignoreNextMouseRelease;
       
   109 };
       
   110 
       
   111 bool QSystemTrayIconSys::allowsMessages()
       
   112 {
       
   113 #ifndef QT_NO_SETTINGS
       
   114     QSettings settings(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft"
       
   115                                       "\\Windows\\CurrentVersion\\Explorer\\Advanced"), QSettings::NativeFormat);
       
   116     return settings.value(QLatin1String("EnableBalloonTips"), true).toBool();
       
   117 #else
       
   118     return false;
       
   119 #endif
       
   120 }
       
   121 
       
   122 bool QSystemTrayIconSys::supportsMessages()
       
   123 {
       
   124 #ifndef Q_OS_WINCE
       
   125     return allowsMessages();
       
   126 #endif
       
   127     return false;
       
   128 }
       
   129 
       
   130 QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
       
   131     : hIcon(0), q(object), ignoreNextMouseRelease(false)
       
   132 
       
   133 {
       
   134 #ifndef Q_OS_WINCE
       
   135     notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, guidItem); // NOTIFYICONDATAW_V2_SIZE;
       
   136     maxTipLength = 128;
       
   137 #else
       
   138     notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, szTip[64]); // NOTIFYICONDATAW_V1_SIZE;
       
   139     maxTipLength = 64;
       
   140 #endif
       
   141 
       
   142     // For restoring the tray icon after explorer crashes
       
   143     if (!MYWM_TASKBARCREATED) {
       
   144         MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
       
   145     }
       
   146 }
       
   147 
       
   148 QSystemTrayIconSys::~QSystemTrayIconSys()
       
   149 {
       
   150     if (hIcon)
       
   151         DestroyIcon(hIcon);
       
   152 }
       
   153 
       
   154 void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd)
       
   155 {
       
   156     tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
       
   157     tnd.uCallbackMessage = MYWM_NOTIFYICON;
       
   158     tnd.hIcon = hIcon;
       
   159     QString tip = q->toolTip();
       
   160 
       
   161     if (!tip.isNull()) {
       
   162         tip = tip.left(maxTipLength - 1) + QChar();
       
   163         memcpy(tnd.szTip, tip.utf16(), qMin(tip.length() + 1, maxTipLength) * sizeof(wchar_t));
       
   164     }
       
   165 }
       
   166 
       
   167 static int iconFlag( QSystemTrayIcon::MessageIcon icon )
       
   168 {
       
   169 #if NOTIFYICON_VERSION >= 3
       
   170     switch (icon) {
       
   171         case QSystemTrayIcon::Information:
       
   172             return NIIF_INFO;
       
   173         case QSystemTrayIcon::Warning:
       
   174             return NIIF_WARNING;
       
   175         case QSystemTrayIcon::Critical:
       
   176             return NIIF_ERROR;
       
   177         case QSystemTrayIcon::NoIcon:
       
   178             return NIIF_NONE;
       
   179         default:
       
   180             Q_ASSERT_X(false, "QSystemTrayIconSys::showMessage", "Invalid QSystemTrayIcon::MessageIcon value");
       
   181             return NIIF_NONE;
       
   182     }
       
   183 #else
       
   184     Q_UNUSED(icon);
       
   185     return 0;
       
   186 #endif
       
   187 }
       
   188 
       
   189 bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs)
       
   190 {
       
   191 #if NOTIFYICON_VERSION >= 3
       
   192     NOTIFYICONDATA tnd;
       
   193     memset(&tnd, 0, notifyIconSize);
       
   194     Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
   195 
       
   196     setIconContents(tnd);
       
   197     memcpy(tnd.szInfo, message.utf16(), qMin(message.length() + 1, 256) * sizeof(wchar_t));
       
   198     memcpy(tnd.szInfoTitle, title.utf16(), qMin(title.length() + 1, 64) * sizeof(wchar_t));
       
   199 
       
   200     tnd.uID = q_uNOTIFYICONID;
       
   201     tnd.dwInfoFlags = iconFlag(type);
       
   202     tnd.cbSize = notifyIconSize;
       
   203     tnd.hWnd = winId();
       
   204     tnd.uTimeout = uSecs;
       
   205     tnd.uFlags = NIF_INFO;
       
   206 
       
   207     return Shell_NotifyIcon(NIM_MODIFY, &tnd);
       
   208 #else
       
   209     Q_UNUSED(title);
       
   210     Q_UNUSED(message);
       
   211     Q_UNUSED(type);
       
   212     Q_UNUSED(uSecs);
       
   213     return false;
       
   214 #endif
       
   215 }
       
   216 
       
   217 bool QSystemTrayIconSys::trayMessage(DWORD msg)
       
   218 {
       
   219     NOTIFYICONDATA tnd;
       
   220     memset(&tnd, 0, notifyIconSize);
       
   221     tnd.uID = q_uNOTIFYICONID;
       
   222     tnd.cbSize = notifyIconSize;
       
   223     tnd.hWnd = winId();
       
   224 
       
   225     Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
   226 
       
   227     if (msg != NIM_DELETE) {
       
   228         setIconContents(tnd);
       
   229     }
       
   230 
       
   231     return Shell_NotifyIcon(msg, &tnd);
       
   232 }
       
   233 
       
   234 bool QSystemTrayIconSys::iconDrawItem(LPDRAWITEMSTRUCT lpdi)
       
   235 {
       
   236     if (!hIcon)
       
   237         return false;
       
   238 
       
   239     DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon, 0, 0, 0, 0, DI_NORMAL);
       
   240     return true;
       
   241 }
       
   242 
       
   243 void QSystemTrayIconSys::createIcon()
       
   244 {
       
   245     hIcon = 0;
       
   246     QIcon icon = q->icon();
       
   247     if (icon.isNull())
       
   248         return;
       
   249 
       
   250     const int iconSizeX = GetSystemMetrics(SM_CXSMICON);
       
   251     const int iconSizeY = GetSystemMetrics(SM_CYSMICON);
       
   252     QSize size = icon.actualSize(QSize(iconSizeX, iconSizeY));
       
   253     QPixmap pm = icon.pixmap(size);
       
   254     if (pm.isNull())
       
   255         return;
       
   256 
       
   257     hIcon = pm.toWinHICON();
       
   258 }
       
   259 
       
   260 bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
       
   261 {
       
   262     switch(m->message) {
       
   263     case WM_CREATE:
       
   264 #ifdef GWLP_USERDATA
       
   265         SetWindowLongPtr(winId(), GWLP_USERDATA, (LONG_PTR)((CREATESTRUCTW*)m->lParam)->lpCreateParams);
       
   266 #else
       
   267         SetWindowLong(winId(), GWL_USERDATA, (LONG)((CREATESTRUCTW*)m->lParam)->lpCreateParams);
       
   268 #endif
       
   269         break;
       
   270 
       
   271     case WM_DRAWITEM:
       
   272         return iconDrawItem((LPDRAWITEMSTRUCT)m->lParam);
       
   273 
       
   274     case MYWM_NOTIFYICON:
       
   275         {
       
   276             RECT r;
       
   277             GetWindowRect(winId(), &r);
       
   278             QEvent *e = 0;
       
   279             Qt::KeyboardModifiers keys = QApplication::keyboardModifiers();
       
   280             QPoint gpos = QCursor::pos();
       
   281 
       
   282             switch (m->lParam) {
       
   283             case WM_LBUTTONUP:
       
   284                 if (ignoreNextMouseRelease)
       
   285                     ignoreNextMouseRelease = false;
       
   286                 else 
       
   287                     emit q->activated(QSystemTrayIcon::Trigger);
       
   288                 break;
       
   289 
       
   290             case WM_LBUTTONDBLCLK:
       
   291                 ignoreNextMouseRelease = true; // Since DBLCLICK Generates a second mouse 
       
   292                                                // release we must ignore it
       
   293                 emit q->activated(QSystemTrayIcon::DoubleClick);
       
   294                 break;
       
   295 
       
   296             case WM_RBUTTONUP:
       
   297                 if (q->contextMenu()) {
       
   298                     q->contextMenu()->popup(gpos);
       
   299 #if defined(Q_WS_WINCE)
       
   300                     // We must ensure that the popup menu doesn't show up behind the task bar.
       
   301                     QRect desktopRect = qApp->desktop()->availableGeometry();
       
   302                     int maxY = desktopRect.y() + desktopRect.height() - q->contextMenu()->height();
       
   303                     if (gpos.y() > maxY) {
       
   304                         gpos.ry() = maxY;
       
   305                         q->contextMenu()->move(gpos);
       
   306                     }
       
   307 #endif
       
   308                     q->contextMenu()->activateWindow();
       
   309                     //Must be activated for proper keyboardfocus and menu closing on windows:
       
   310                 }
       
   311                 emit q->activated(QSystemTrayIcon::Context);
       
   312                 break;
       
   313 
       
   314 #if !defined(Q_WS_WINCE)
       
   315             case NIN_BALLOONUSERCLICK:
       
   316                 emit q->messageClicked();
       
   317                 break;
       
   318 #endif
       
   319 
       
   320             case WM_MBUTTONUP:
       
   321                 emit q->activated(QSystemTrayIcon::MiddleClick);
       
   322                 break;
       
   323             default:
       
   324                         break;
       
   325             }
       
   326             if (e) {
       
   327                 bool res = QApplication::sendEvent(q, e);
       
   328                 delete e;
       
   329                 return res;
       
   330             }
       
   331             break;
       
   332         }
       
   333     default:
       
   334         if (m->message == MYWM_TASKBARCREATED)
       
   335             trayMessage(NIM_ADD);
       
   336         else
       
   337             return QWidget::winEvent(m, result);
       
   338         break;
       
   339     }
       
   340     return 0;
       
   341 }
       
   342 
       
   343 void QSystemTrayIconPrivate::install_sys()
       
   344 {
       
   345     Q_Q(QSystemTrayIcon);
       
   346     if (!sys) {
       
   347         sys = new QSystemTrayIconSys(q);
       
   348         sys->createIcon();
       
   349         sys->trayMessage(NIM_ADD);
       
   350     }
       
   351 }
       
   352 
       
   353 /*
       
   354 * This function tries to determine the icon geometry from the tray
       
   355 *
       
   356 * If it fails an invalid rect is returned.
       
   357 */
       
   358 QRect QSystemTrayIconSys::findIconGeometry(const int iconId)
       
   359 {
       
   360     static PtrShell_NotifyIconGetRect Shell_NotifyIconGetRect =
       
   361         (PtrShell_NotifyIconGetRect)QLibrary::resolve(QLatin1String("shell32"), "Shell_NotifyIconGetRect");
       
   362 
       
   363     if (Shell_NotifyIconGetRect) {
       
   364         Q_NOTIFYICONIDENTIFIER nid;
       
   365         memset(&nid, 0, sizeof(nid));
       
   366         nid.cbSize = sizeof(nid);
       
   367         nid.hWnd = winId();
       
   368         nid.uID = iconId;
       
   369 
       
   370         RECT rect;
       
   371         HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect);
       
   372         if (SUCCEEDED(hr)) {
       
   373             return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
       
   374         }
       
   375     }
       
   376 
       
   377     QRect ret;
       
   378 
       
   379     TBBUTTON buttonData;
       
   380     DWORD processID = 0;
       
   381     HWND trayHandle = FindWindow(L"Shell_TrayWnd", NULL);
       
   382 
       
   383     //find the toolbar used in the notification area
       
   384     if (trayHandle) {
       
   385 #if defined(Q_OS_WINCE)
       
   386         trayHandle = FindWindow(L"TrayNotifyWnd", NULL);
       
   387 #else
       
   388         trayHandle = FindWindowEx(trayHandle, NULL, L"TrayNotifyWnd", NULL);
       
   389 #endif
       
   390         if (trayHandle) {
       
   391 #if defined(Q_OS_WINCE)
       
   392             HWND hwnd = FindWindow(L"SysPager", NULL);
       
   393 #else
       
   394             HWND hwnd = FindWindowEx(trayHandle, NULL, L"SysPager", NULL);
       
   395 #endif
       
   396             if (hwnd) {
       
   397 #if defined(Q_OS_WINCE)
       
   398                 hwnd = FindWindow(L"ToolbarWindow32", NULL);
       
   399 #else
       
   400                 hwnd = FindWindowEx(hwnd, NULL, L"ToolbarWindow32", NULL);
       
   401 #endif
       
   402                 if (hwnd)
       
   403                     trayHandle = hwnd;
       
   404             }
       
   405         }
       
   406     }
       
   407 
       
   408     if (!trayHandle)
       
   409         return ret;
       
   410 
       
   411     GetWindowThreadProcessId(trayHandle, &processID);
       
   412     if (processID <= 0)
       
   413         return ret;
       
   414 
       
   415     HANDLE trayProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, 0, processID);
       
   416     if (!trayProcess)
       
   417         return ret;
       
   418 
       
   419     int buttonCount = SendMessage(trayHandle, TB_BUTTONCOUNT, 0, 0);
       
   420 #if defined(Q_OS_WINCE)
       
   421     LPVOID data = VirtualAlloc(NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
       
   422 #else
       
   423     LPVOID data = VirtualAllocEx(trayProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
       
   424 #endif
       
   425 
       
   426     if ( buttonCount < 1 || !data ) {
       
   427         CloseHandle(trayProcess);
       
   428         return ret;
       
   429     }
       
   430 
       
   431     //search for our icon among all toolbar buttons
       
   432     for (int toolbarButton = 0; toolbarButton  < buttonCount; ++toolbarButton ) {
       
   433         SIZE_T numBytes = 0;
       
   434         DWORD appData[2] = { 0, 0 };
       
   435         SendMessage(trayHandle, TB_GETBUTTON, toolbarButton , (LPARAM)data);
       
   436 
       
   437         if (!ReadProcessMemory(trayProcess, data, &buttonData, sizeof(TBBUTTON), &numBytes))
       
   438             continue;
       
   439 
       
   440         if (!ReadProcessMemory(trayProcess, (LPVOID) buttonData.dwData, appData, sizeof(appData), &numBytes))
       
   441             continue;
       
   442 
       
   443         int currentIconId = appData[1];
       
   444         HWND currentIconHandle = (HWND) appData[0];
       
   445         bool isHidden = buttonData.fsState & TBSTATE_HIDDEN;
       
   446 
       
   447         if (currentIconHandle == winId() &&
       
   448             currentIconId == iconId && !isHidden) {
       
   449             SendMessage(trayHandle, TB_GETITEMRECT, toolbarButton , (LPARAM)data);
       
   450             RECT iconRect = {0, 0};
       
   451             if(ReadProcessMemory(trayProcess, data, &iconRect, sizeof(RECT), &numBytes)) {
       
   452                 MapWindowPoints(trayHandle, NULL, (LPPOINT)&iconRect, 2);
       
   453                 QRect geometry(iconRect.left + 1, iconRect.top + 1,
       
   454                                 iconRect.right - iconRect.left - 2,
       
   455                                 iconRect.bottom - iconRect.top - 2);
       
   456                 if (geometry.isValid())
       
   457                     ret = geometry;
       
   458                 break;
       
   459             }
       
   460         }
       
   461     }
       
   462 #if defined(Q_OS_WINCE)
       
   463     VirtualFree(data, 0, MEM_RELEASE);
       
   464 #else
       
   465     VirtualFreeEx(trayProcess, data, 0, MEM_RELEASE);
       
   466 #endif
       
   467     CloseHandle(trayProcess);
       
   468     return ret;
       
   469 }
       
   470 
       
   471 void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, int timeOut)
       
   472 {
       
   473     if (!sys || !sys->allowsMessages())
       
   474         return;
       
   475 
       
   476     uint uSecs = 0;
       
   477     if ( timeOut < 0)
       
   478         uSecs = 10000; //10 sec default
       
   479     else uSecs = (int)timeOut;
       
   480 
       
   481     //message is limited to 255 chars + NULL
       
   482     QString messageString;
       
   483     if (message.isEmpty() && !title.isEmpty())
       
   484         messageString = QLatin1Char(' '); //ensures that the message shows when only title is set
       
   485     else
       
   486         messageString = message.left(255) + QChar();
       
   487 
       
   488     //title is limited to 63 chars + NULL
       
   489     QString titleString = title.left(63) + QChar();
       
   490 
       
   491     if (sys->supportsMessages()) {
       
   492         sys->showMessage(titleString, messageString, type, (unsigned int)uSecs);
       
   493     } else {
       
   494         //use fallback
       
   495         QRect iconPos = sys->findIconGeometry(q_uNOTIFYICONID);
       
   496         if (iconPos.isValid()) {
       
   497             QBalloonTip::showBalloon(type, title, message, sys->q, iconPos.center(), uSecs, true);
       
   498         }
       
   499     }
       
   500 }
       
   501 
       
   502 QRect QSystemTrayIconPrivate::geometry_sys() const
       
   503 {
       
   504     if (!sys)
       
   505         return QRect();
       
   506     return sys->findIconGeometry(q_uNOTIFYICONID);
       
   507 }
       
   508 
       
   509 void QSystemTrayIconPrivate::remove_sys()
       
   510 {
       
   511     if (!sys)
       
   512         return;
       
   513 
       
   514     sys->trayMessage(NIM_DELETE);
       
   515     delete sys;
       
   516     sys = 0;
       
   517 }
       
   518 
       
   519 void QSystemTrayIconPrivate::updateIcon_sys()
       
   520 {
       
   521     if (!sys)
       
   522         return;
       
   523 
       
   524     HICON hIconToDestroy = sys->hIcon;
       
   525 
       
   526     sys->createIcon();
       
   527     sys->trayMessage(NIM_MODIFY);
       
   528 
       
   529     if (hIconToDestroy)
       
   530         DestroyIcon(hIconToDestroy);
       
   531 }
       
   532 
       
   533 void QSystemTrayIconPrivate::updateMenu_sys()
       
   534 {
       
   535 
       
   536 }
       
   537 
       
   538 void QSystemTrayIconPrivate::updateToolTip_sys()
       
   539 {
       
   540 #ifdef Q_WS_WINCE
       
   541     // Calling sys->trayMessage(NIM_MODIFY) on an existing icon is broken on Windows CE.
       
   542     // So we need to call updateIcon_sys() which creates a new icon handle.
       
   543     updateIcon_sys();
       
   544 #else
       
   545     if (!sys)
       
   546         return;
       
   547 
       
   548     sys->trayMessage(NIM_MODIFY);
       
   549 #endif
       
   550 }
       
   551 
       
   552 bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
       
   553 {
       
   554     return true;
       
   555 }
       
   556 
       
   557 QT_END_NAMESPACE
       
   558 
       
   559 #endif