src/gui/util/qsystemtrayicon.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.h"
       
    43 #include "qsystemtrayicon_p.h"
       
    44 
       
    45 #ifndef QT_NO_SYSTEMTRAYICON
       
    46 
       
    47 #include "qmenu.h"
       
    48 #include "qevent.h"
       
    49 #include "qpoint.h"
       
    50 #include "qlabel.h"
       
    51 #include "qpushbutton.h"
       
    52 #include "qpainterpath.h"
       
    53 #include "qpainter.h"
       
    54 #include "qstyle.h"
       
    55 #include "qgridlayout.h"
       
    56 #include "qapplication.h"
       
    57 #include "qdesktopwidget.h"
       
    58 #include "qbitmap.h"
       
    59 #include "private/qlabel_p.h"
       
    60 #include "qapplication.h"
       
    61 
       
    62 QT_BEGIN_NAMESPACE
       
    63 
       
    64 /*!
       
    65     \class QSystemTrayIcon
       
    66     \brief The QSystemTrayIcon class provides an icon for an application in the system tray.
       
    67     \since 4.2
       
    68     \ingroup desktop
       
    69 
       
    70     Modern operating systems usually provide a special area on the desktop,
       
    71     called the \e{system tray} or \e{notification area}, where long-running
       
    72     applications can display icons and short messages.
       
    73 
       
    74     \image system-tray.png The system tray on Windows XP.
       
    75 
       
    76     The QSystemTrayIcon class can be used on the following platforms:
       
    77 
       
    78     \list
       
    79     \o All supported versions of Windows.
       
    80     \o All window managers for X11 that implement the \l{freedesktop.org} system
       
    81        tray specification, including recent versions of KDE and GNOME.
       
    82     \o All supported versions of Mac OS X. Note that the Growl
       
    83        notification system must be installed for
       
    84        QSystemTrayIcon::showMessage() to display messages.
       
    85     \endlist
       
    86 
       
    87     To check whether a system tray is present on the user's desktop,
       
    88     call the QSystemTrayIcon::isSystemTrayAvailable() static function.
       
    89 
       
    90     To add a system tray entry, create a QSystemTrayIcon object, call setContextMenu()
       
    91     to provide a context menu for the icon, and call show() to make it visible in the
       
    92     system tray. Status notification messages ("balloon messages") can be displayed at
       
    93     any time using showMessage().
       
    94 
       
    95     If the system tray is unavailable when a system tray icon is constructed, but
       
    96     becomes available later, QSystemTrayIcon will automatically add an entry for the
       
    97     application in the system tray if the icon is \l visible.
       
    98 
       
    99     The activated() signal is emitted when the user activates the icon.
       
   100 
       
   101     Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent
       
   102     of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of
       
   103     type QEvent::Wheel. These are not supported on any other platform.
       
   104 
       
   105     \sa QDesktopServices, QDesktopWidget, {Desktop Integration}, {System Tray Icon Example}
       
   106 */
       
   107 
       
   108 /*!
       
   109     \enum QSystemTrayIcon::MessageIcon
       
   110 
       
   111     This enum describes the icon that is shown when a balloon message is displayed.
       
   112 
       
   113     \value NoIcon      No icon is shown.
       
   114     \value Information An information icon is shown.
       
   115     \value Warning     A standard warning icon is shown.
       
   116     \value Critical    A critical warning icon is shown.
       
   117 
       
   118     \sa QMessageBox
       
   119 */
       
   120 
       
   121 /*!
       
   122     Constructs a QSystemTrayIcon object with the given \a parent.
       
   123 
       
   124     The icon is initially invisible.
       
   125 
       
   126     \sa visible
       
   127 */
       
   128 QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
       
   129 : QObject(*new QSystemTrayIconPrivate(), parent)
       
   130 {
       
   131 }
       
   132 
       
   133 /*!
       
   134     Constructs a QSystemTrayIcon object with the given \a icon and \a parent.
       
   135 
       
   136     The icon is initially invisible.
       
   137 
       
   138     \sa visible
       
   139 */
       
   140 QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
       
   141 : QObject(*new QSystemTrayIconPrivate(), parent)
       
   142 {
       
   143     setIcon(icon);
       
   144 }
       
   145 
       
   146 /*!
       
   147     Removes the icon from the system tray and frees all allocated resources.
       
   148 */
       
   149 QSystemTrayIcon::~QSystemTrayIcon()
       
   150 {
       
   151     Q_D(QSystemTrayIcon);
       
   152     d->remove_sys();
       
   153 }
       
   154 
       
   155 #ifndef QT_NO_MENU
       
   156 
       
   157 /*!
       
   158     Sets the specified \a menu to be the context menu for the system tray icon.
       
   159 
       
   160     The menu will pop up when the user requests the context menu for the system
       
   161     tray icon by clicking the mouse button.
       
   162 
       
   163     On Mac OS X, this is currenly converted to a NSMenu, so the
       
   164     aboutToHide() signal is not emitted.
       
   165 
       
   166     \note The system tray icon does not take ownership of the menu. You must
       
   167     ensure that it is deleted at the appropriate time by, for example, creating
       
   168     the menu with a suitable parent object.
       
   169 */
       
   170 void QSystemTrayIcon::setContextMenu(QMenu *menu)
       
   171 {
       
   172     Q_D(QSystemTrayIcon);
       
   173     d->menu = menu;
       
   174     d->updateMenu_sys();
       
   175 }
       
   176 
       
   177 /*!
       
   178     Returns the current context menu for the system tray entry.
       
   179 */
       
   180 QMenu* QSystemTrayIcon::contextMenu() const
       
   181 {
       
   182     Q_D(const QSystemTrayIcon);
       
   183     return d->menu;
       
   184 }
       
   185 
       
   186 #endif // QT_NO_MENU
       
   187 
       
   188 /*!
       
   189     \property QSystemTrayIcon::icon
       
   190     \brief the system tray icon
       
   191 
       
   192     On Windows, the system tray icon size is 16x16; on X11, the preferred size is
       
   193     22x22. The icon will be scaled to the appropriate size as necessary.
       
   194 */
       
   195 void QSystemTrayIcon::setIcon(const QIcon &icon)
       
   196 {
       
   197     Q_D(QSystemTrayIcon);
       
   198     d->icon = icon;
       
   199     d->updateIcon_sys();
       
   200 }
       
   201 
       
   202 QIcon QSystemTrayIcon::icon() const
       
   203 {
       
   204     Q_D(const QSystemTrayIcon);
       
   205     return d->icon;
       
   206 }
       
   207 
       
   208 /*!
       
   209     \property QSystemTrayIcon::toolTip
       
   210     \brief the tooltip for the system tray entry
       
   211 
       
   212     On some systems, the tooltip's length is limited. The tooltip will be truncated
       
   213     if necessary.
       
   214 */
       
   215 void QSystemTrayIcon::setToolTip(const QString &tooltip)
       
   216 {
       
   217     Q_D(QSystemTrayIcon);
       
   218     d->toolTip = tooltip;
       
   219     d->updateToolTip_sys();
       
   220 }
       
   221 
       
   222 QString QSystemTrayIcon::toolTip() const
       
   223 {
       
   224     Q_D(const QSystemTrayIcon);
       
   225     return d->toolTip;
       
   226 }
       
   227 
       
   228 /*!
       
   229     \fn void QSystemTrayIcon::show()
       
   230 
       
   231     Shows the icon in the system tray.
       
   232 
       
   233     \sa hide(), visible
       
   234 */
       
   235 
       
   236 /*!
       
   237     \fn void QSystemTrayIcon::hide()
       
   238 
       
   239     Hides the system tray entry.
       
   240 
       
   241     \sa show(), visible
       
   242 */
       
   243 
       
   244 /*!
       
   245     \since 4.3
       
   246     Returns the geometry of the system tray icon in screen coordinates.
       
   247 
       
   248     \sa visible
       
   249 */
       
   250 QRect QSystemTrayIcon::geometry() const
       
   251 {
       
   252     Q_D(const QSystemTrayIcon);
       
   253     if (!d->visible)
       
   254         return QRect();
       
   255     return d->geometry_sys();
       
   256 }
       
   257 
       
   258 /*!
       
   259     \property QSystemTrayIcon::visible
       
   260     \brief whether the system tray entry is visible
       
   261 
       
   262     Setting this property to true or calling show() makes the system tray icon
       
   263     visible; setting this property to false or calling hide() hides it.
       
   264 */
       
   265 void QSystemTrayIcon::setVisible(bool visible)
       
   266 {
       
   267     Q_D(QSystemTrayIcon);
       
   268     if (visible == d->visible)
       
   269         return;
       
   270     if (d->icon.isNull() && visible)
       
   271         qWarning("QSystemTrayIcon::setVisible: No Icon set");
       
   272     d->visible = visible;
       
   273     if (d->visible)
       
   274         d->install_sys();
       
   275     else
       
   276         d->remove_sys();
       
   277 }
       
   278 
       
   279 bool QSystemTrayIcon::isVisible() const
       
   280 {
       
   281     Q_D(const QSystemTrayIcon);
       
   282     return d->visible;
       
   283 }
       
   284 
       
   285 /*!
       
   286   \reimp
       
   287 */
       
   288 bool QSystemTrayIcon::event(QEvent *e)
       
   289 {
       
   290 #if defined(Q_WS_X11)
       
   291     if (e->type() == QEvent::ToolTip) {
       
   292         Q_D(QSystemTrayIcon);
       
   293         return d->sys->deliverToolTipEvent(e);
       
   294     }
       
   295 #endif
       
   296     return QObject::event(e);
       
   297 }
       
   298 
       
   299 /*!
       
   300     \enum QSystemTrayIcon::ActivationReason
       
   301 
       
   302      This enum describes the reason the system tray was activated.
       
   303 
       
   304      \value Unknown     Unknown reason
       
   305      \value Context     The context menu for the system tray entry was requested
       
   306      \value DoubleClick The system tray entry was double clicked
       
   307      \value Trigger     The system tray entry was clicked
       
   308      \value MiddleClick The system tray entry was clicked with the middle mouse button
       
   309 
       
   310      \sa activated()
       
   311 */
       
   312 
       
   313 /*!
       
   314     \fn void QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)
       
   315 
       
   316     This signal is emitted when the user activates the system tray icon. \a reason
       
   317     specifies the reason for activation. QSystemTrayIcon::ActivationReason enumerates
       
   318     the various reasons.
       
   319 
       
   320     \sa QSystemTrayIcon::ActivationReason
       
   321 */
       
   322 
       
   323 /*!
       
   324     \fn void QSystemTrayIcon::messageClicked()
       
   325 
       
   326     This signal is emitted when the message displayed using showMessage()
       
   327     was clicked by the user.
       
   328 
       
   329     Currently this signal is not sent on Mac OS X.
       
   330 
       
   331     \note We follow Microsoft Windows XP/Vista behavior, so the
       
   332     signal is also emitted when the user clicks on a tray icon with
       
   333     a balloon message displayed.
       
   334 
       
   335     \sa activated()
       
   336 */
       
   337 
       
   338 
       
   339 /*!
       
   340     Returns true if the system tray is available; otherwise returns false.
       
   341 
       
   342     If the system tray is currently unavailable but becomes available later,
       
   343     QSystemTrayIcon will automatically add an entry in the system tray if it
       
   344     is \l visible.
       
   345 */
       
   346 
       
   347 bool QSystemTrayIcon::isSystemTrayAvailable()
       
   348 {
       
   349     return QSystemTrayIconPrivate::isSystemTrayAvailable_sys();
       
   350 }
       
   351 
       
   352 /*!
       
   353     Returns true if the system tray supports balloon messages; otherwise returns false.
       
   354 
       
   355     \sa showMessage()
       
   356 */
       
   357 bool QSystemTrayIcon::supportsMessages()
       
   358 {
       
   359 #if defined(Q_WS_QWS)
       
   360     return false;
       
   361 #endif
       
   362     return true;
       
   363 }
       
   364 
       
   365 /*!
       
   366     \fn void QSystemTrayIcon::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint)
       
   367     \since 4.3
       
   368 
       
   369     Shows a balloon message for the entry with the given \a title, \a message and
       
   370     \a icon for the time specified in \a millisecondsTimeoutHint. \a title and \a message
       
   371     must be plain text strings.
       
   372 
       
   373     Message can be clicked by the user; the messageClicked() signal will emitted when
       
   374     this occurs.
       
   375 
       
   376     Note that display of messages are dependent on the system configuration and user
       
   377     preferences, and that messages may not appear at all. Hence, it should not be
       
   378     relied upon as the sole means for providing critical information.
       
   379 
       
   380     On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
       
   381     when the application has focus.
       
   382 
       
   383     \sa show() supportsMessages()
       
   384   */
       
   385 void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
       
   386                             QSystemTrayIcon::MessageIcon icon, int msecs)
       
   387 {
       
   388     Q_D(QSystemTrayIcon);
       
   389     if (d->visible)
       
   390         d->showMessage_sys(title, msg, icon, msecs);
       
   391 }
       
   392 
       
   393 //////////////////////////////////////////////////////////////////////
       
   394 static QBalloonTip *theSolitaryBalloonTip = 0;
       
   395 
       
   396 void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
       
   397                               const QString& message, QSystemTrayIcon *trayIcon,
       
   398                               const QPoint& pos, int timeout, bool showArrow)
       
   399 {
       
   400     hideBalloon();
       
   401     if (message.isEmpty() && title.isEmpty())
       
   402         return;
       
   403 
       
   404     theSolitaryBalloonTip = new QBalloonTip(icon, title, message, trayIcon);
       
   405     if (timeout < 0)
       
   406         timeout = 10000; //10 s default
       
   407     theSolitaryBalloonTip->balloon(pos, timeout, showArrow);
       
   408 }
       
   409 
       
   410 void QBalloonTip::hideBalloon()
       
   411 {
       
   412     if (!theSolitaryBalloonTip)
       
   413         return;
       
   414     theSolitaryBalloonTip->hide();
       
   415     delete theSolitaryBalloonTip;
       
   416     theSolitaryBalloonTip = 0;
       
   417 }
       
   418 
       
   419 bool QBalloonTip::isBalloonVisible()
       
   420 {
       
   421     return theSolitaryBalloonTip;
       
   422 }
       
   423 
       
   424 QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
       
   425                          const QString& message, QSystemTrayIcon *ti)
       
   426     : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1)
       
   427 {
       
   428     setAttribute(Qt::WA_DeleteOnClose);
       
   429     QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close()));
       
   430 
       
   431     QLabel *titleLabel = new QLabel;
       
   432     titleLabel->installEventFilter(this);
       
   433     titleLabel->setText(title);
       
   434     QFont f = titleLabel->font();
       
   435     f.setBold(true);
       
   436 #ifdef Q_WS_WINCE
       
   437     f.setPointSize(f.pointSize() - 2);
       
   438 #endif
       
   439     titleLabel->setFont(f);
       
   440     titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows
       
   441 
       
   442 #ifdef Q_WS_WINCE
       
   443     const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
       
   444     const int closeButtonSize = style()->pixelMetric(QStyle::PM_SmallIconSize) - 2;
       
   445 #else
       
   446     const int iconSize = 18;
       
   447     const int closeButtonSize = 15;
       
   448 #endif
       
   449 
       
   450     QPushButton *closeButton = new QPushButton;
       
   451     closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
       
   452     closeButton->setIconSize(QSize(closeButtonSize, closeButtonSize));
       
   453     closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
       
   454     closeButton->setFixedSize(closeButtonSize, closeButtonSize);
       
   455     QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
       
   456 
       
   457     QLabel *msgLabel = new QLabel;
       
   458 #ifdef Q_WS_WINCE
       
   459     f.setBold(false);
       
   460     msgLabel->setFont(f);
       
   461 #endif
       
   462     msgLabel->installEventFilter(this);
       
   463     msgLabel->setText(message);
       
   464     msgLabel->setTextFormat(Qt::PlainText);
       
   465     msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
       
   466 
       
   467     // smart size for the message label
       
   468 #ifdef Q_WS_WINCE
       
   469     int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 2;
       
   470 #else
       
   471     int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3;
       
   472 #endif
       
   473     if (msgLabel->sizeHint().width() > limit) {
       
   474         msgLabel->setWordWrap(true);
       
   475         if (msgLabel->sizeHint().width() > limit) {
       
   476             msgLabel->d_func()->ensureTextControl();
       
   477             if (QTextControl *control = msgLabel->d_func()->control) {
       
   478                 QTextOption opt = control->document()->defaultTextOption();
       
   479                 opt.setWrapMode(QTextOption::WrapAnywhere);
       
   480                 control->document()->setDefaultTextOption(opt);
       
   481             }
       
   482         }
       
   483 #ifdef Q_WS_WINCE
       
   484         // Make sure that the text isn't wrapped "somewhere" in the balloon widget
       
   485         // in the case that we have a long title label.
       
   486         setMaximumWidth(limit);
       
   487 #else
       
   488         // Here we allow the text being much smaller than the balloon widget
       
   489         // to emulate the weird standard windows behavior.
       
   490         msgLabel->setFixedSize(limit, msgLabel->heightForWidth(limit));
       
   491 #endif
       
   492     }
       
   493 
       
   494     QIcon si;
       
   495     switch (icon) {
       
   496     case QSystemTrayIcon::Warning:
       
   497         si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
       
   498         break;
       
   499     case QSystemTrayIcon::Critical:
       
   500 	si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
       
   501         break;
       
   502     case QSystemTrayIcon::Information:
       
   503 	si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
       
   504         break;
       
   505     case QSystemTrayIcon::NoIcon:
       
   506     default:
       
   507         break;
       
   508     }
       
   509 
       
   510     QGridLayout *layout = new QGridLayout;
       
   511     if (!si.isNull()) {
       
   512         QLabel *iconLabel = new QLabel;
       
   513         iconLabel->setPixmap(si.pixmap(iconSize, iconSize));
       
   514         iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
       
   515         iconLabel->setMargin(2);
       
   516         layout->addWidget(iconLabel, 0, 0);
       
   517         layout->addWidget(titleLabel, 0, 1);
       
   518     } else {
       
   519         layout->addWidget(titleLabel, 0, 0, 1, 2);
       
   520     }
       
   521 
       
   522     layout->addWidget(closeButton, 0, 2);
       
   523     layout->addWidget(msgLabel, 1, 0, 1, 3);
       
   524     layout->setSizeConstraint(QLayout::SetFixedSize);
       
   525     layout->setMargin(3);
       
   526     setLayout(layout);
       
   527 
       
   528     QPalette pal = palette();
       
   529     pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
       
   530     pal.setColor(QPalette::WindowText, Qt::black);
       
   531     setPalette(pal);
       
   532 }
       
   533 
       
   534 QBalloonTip::~QBalloonTip()
       
   535 {
       
   536     theSolitaryBalloonTip = 0;
       
   537 }
       
   538 
       
   539 void QBalloonTip::paintEvent(QPaintEvent *)
       
   540 {
       
   541     QPainter painter(this);
       
   542     painter.drawPixmap(rect(), pixmap);
       
   543 }
       
   544 
       
   545 void QBalloonTip::resizeEvent(QResizeEvent *ev)
       
   546 {
       
   547     QWidget::resizeEvent(ev);
       
   548 }
       
   549 
       
   550 void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
       
   551 {
       
   552     QRect scr = QApplication::desktop()->screenGeometry(pos);
       
   553     QSize sh = sizeHint();
       
   554     const int border = 1;
       
   555     const int ah = 18, ao = 18, aw = 18, rc = 7;
       
   556     bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height());
       
   557     bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width());
       
   558     setContentsMargins(border + 3,  border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2);
       
   559     updateGeometry();
       
   560     sh  = sizeHint();
       
   561 
       
   562     int ml, mr, mt, mb;
       
   563     QSize sz = sizeHint();
       
   564     if (!arrowAtTop) {
       
   565         ml = mt = 0;
       
   566         mr = sz.width() - 1;
       
   567         mb = sz.height() - ah - 1;
       
   568     } else {
       
   569         ml = 0;
       
   570         mt = ah;
       
   571         mr = sz.width() - 1;
       
   572         mb = sz.height() - 1;
       
   573     }
       
   574 
       
   575     QPainterPath path;
       
   576 #if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
       
   577     // XShape is required for setting the mask, so we just
       
   578     // draw an ugly square when its not available
       
   579     path.moveTo(0, 0);
       
   580     path.lineTo(sz.width() - 1, 0);
       
   581     path.lineTo(sz.width() - 1, sz.height() - 1);
       
   582     path.lineTo(0, sz.height() - 1);
       
   583     path.lineTo(0, 0);
       
   584     move(qMax(pos.x() - sz.width(), scr.left()), pos.y());
       
   585 #else
       
   586     path.moveTo(ml + rc, mt);
       
   587     if (arrowAtTop && arrowAtLeft) {
       
   588         if (showArrow) {
       
   589             path.lineTo(ml + ao, mt);
       
   590             path.lineTo(ml + ao, mt - ah);
       
   591             path.lineTo(ml + ao + aw, mt);
       
   592         }
       
   593         move(qMax(pos.x() - ao, scr.left() + 2), pos.y());
       
   594     } else if (arrowAtTop && !arrowAtLeft) {
       
   595         if (showArrow) {
       
   596             path.lineTo(mr - ao - aw, mt);
       
   597             path.lineTo(mr - ao, mt - ah);
       
   598             path.lineTo(mr - ao, mt);
       
   599         }
       
   600         move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y());
       
   601     }
       
   602     path.lineTo(mr - rc, mt);
       
   603     path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90);
       
   604     path.lineTo(mr, mb - rc);
       
   605     path.arcTo(QRect(mr - rc*2, mb - rc*2, rc*2, rc*2), 0, -90);
       
   606     if (!arrowAtTop && !arrowAtLeft) {
       
   607         if (showArrow) {
       
   608             path.lineTo(mr - ao, mb);
       
   609             path.lineTo(mr - ao, mb + ah);
       
   610             path.lineTo(mr - ao - aw, mb);
       
   611         }
       
   612         move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2),
       
   613              pos.y() - sh.height());
       
   614     } else if (!arrowAtTop && arrowAtLeft) {
       
   615         if (showArrow) {
       
   616             path.lineTo(ao + aw, mb);
       
   617             path.lineTo(ao, mb + ah);
       
   618             path.lineTo(ao, mb);
       
   619         }
       
   620         move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height());
       
   621     }
       
   622     path.lineTo(ml + rc, mb);
       
   623     path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90);
       
   624     path.lineTo(ml, mt + rc);
       
   625     path.arcTo(QRect(ml, mt, rc*2, rc*2), 180, -90);
       
   626 
       
   627     // Set the mask
       
   628     QBitmap bitmap = QBitmap(sizeHint());
       
   629     bitmap.fill(Qt::color0);
       
   630     QPainter painter1(&bitmap);
       
   631     painter1.setPen(QPen(Qt::color1, border));
       
   632     painter1.setBrush(QBrush(Qt::color1));
       
   633     painter1.drawPath(path);
       
   634     setMask(bitmap);
       
   635 #endif
       
   636 
       
   637     // Draw the border
       
   638     pixmap = QPixmap(sz);
       
   639     QPainter painter2(&pixmap);
       
   640     painter2.setPen(QPen(palette().color(QPalette::Window).darker(160), border));
       
   641     painter2.setBrush(palette().color(QPalette::Window));
       
   642     painter2.drawPath(path);
       
   643 
       
   644     if (msecs > 0)
       
   645         timerId = startTimer(msecs);
       
   646     show();
       
   647 }
       
   648 
       
   649 void QBalloonTip::mousePressEvent(QMouseEvent *e)
       
   650 {
       
   651     close();
       
   652     if(e->button() == Qt::LeftButton)
       
   653         emit trayIcon->messageClicked();
       
   654 }
       
   655 
       
   656 void QBalloonTip::timerEvent(QTimerEvent *e)
       
   657 {
       
   658     if (e->timerId() == timerId) {
       
   659         killTimer(timerId);
       
   660         if (!underMouse())
       
   661             close();
       
   662         return;
       
   663     }
       
   664     QWidget::timerEvent(e);
       
   665 }
       
   666 
       
   667 void qtsystray_sendActivated(QSystemTrayIcon *i, int r)
       
   668 {
       
   669     emit i->activated((QSystemTrayIcon::ActivationReason)r);
       
   670 }
       
   671 
       
   672 QT_END_NAMESPACE
       
   673 
       
   674 #endif // QT_NO_SYSTEMTRAYICON