QSystemTrayIcon/X11: Create tray icon window when system tray appears
... and destroy it otherwise. Fixes: QTBUG-61898 Fixes: QTBUG-73459 Done-with: Gatis Paeglis <gatis.paeglis@qt.io> Change-Id: I6bd8f397f7ccdb123f6a60d4fa466f7b0d760dfc Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
parent
de854aa37f
commit
2947435d87
@ -69,6 +69,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QSystemTrayIconSys;
|
class QSystemTrayIconSys;
|
||||||
|
class QSystemTrayWatcher;
|
||||||
class QPlatformSystemTrayIcon;
|
class QPlatformSystemTrayIcon;
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
@ -90,6 +91,8 @@ public:
|
|||||||
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
|
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
|
||||||
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
|
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
|
||||||
|
|
||||||
|
void destroyIcon();
|
||||||
|
|
||||||
static bool isSystemTrayAvailable_sys();
|
static bool isSystemTrayAvailable_sys();
|
||||||
static bool supportsMessages_sys();
|
static bool supportsMessages_sys();
|
||||||
|
|
||||||
@ -101,6 +104,7 @@ public:
|
|||||||
QSystemTrayIconSys *sys;
|
QSystemTrayIconSys *sys;
|
||||||
QPlatformSystemTrayIcon *qpa_sys;
|
QPlatformSystemTrayIcon *qpa_sys;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
QSystemTrayWatcher *trayWatcher;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void install_sys_qpa();
|
void install_sys_qpa();
|
||||||
|
@ -92,9 +92,6 @@ protected:
|
|||||||
virtual void resizeEvent(QResizeEvent *) override;
|
virtual void resizeEvent(QResizeEvent *) override;
|
||||||
virtual void moveEvent(QMoveEvent *) override;
|
virtual void moveEvent(QMoveEvent *) override;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void systemTrayWindowChanged(QScreen *screen);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSystemTrayIcon *q;
|
QSystemTrayIcon *q;
|
||||||
};
|
};
|
||||||
@ -116,15 +113,6 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
|
|||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
|
|
||||||
{
|
|
||||||
if (!locateSystemTray()) {
|
|
||||||
QBalloonTip::hideBalloon();
|
|
||||||
hide(); // still no luck
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect QSystemTrayIconSys::globalGeometry() const
|
QRect QSystemTrayIconSys::globalGeometry() const
|
||||||
{
|
{
|
||||||
return QRect(mapToGlobal(QPoint(0, 0)), size());
|
return QRect(mapToGlobal(QPoint(0, 0)), size());
|
||||||
@ -199,10 +187,41 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *event)
|
|||||||
}
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class QSystemTrayWatcher: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QSystemTrayWatcher(QSystemTrayIcon *trayIcon)
|
||||||
|
: QObject(trayIcon)
|
||||||
|
, mTrayIcon(trayIcon)
|
||||||
|
{
|
||||||
|
// This code uses string-based syntax because we want to connect to a signal
|
||||||
|
// which is defined in XCB plugin - QXcbNativeInterface::systemTrayWindowChanged().
|
||||||
|
connect(qGuiApp->platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
|
||||||
|
this, SLOT(systemTrayWindowChanged(QScreen*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void systemTrayWindowChanged(QScreen *)
|
||||||
|
{
|
||||||
|
auto icon = static_cast<QSystemTrayIconPrivate *>(QObjectPrivate::get(mTrayIcon));
|
||||||
|
icon->destroyIcon();
|
||||||
|
if (icon->visible && locateSystemTray()) {
|
||||||
|
icon->sys = new QSystemTrayIconSys(mTrayIcon);
|
||||||
|
icon->sys->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSystemTrayIcon *mTrayIcon = nullptr;
|
||||||
|
};
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
|
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
|
||||||
: sys(0),
|
: sys(0),
|
||||||
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
|
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
|
||||||
visible(false)
|
visible(false),
|
||||||
|
trayWatcher(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,18 +232,23 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
|
|||||||
|
|
||||||
void QSystemTrayIconPrivate::install_sys()
|
void QSystemTrayIconPrivate::install_sys()
|
||||||
{
|
{
|
||||||
|
Q_Q(QSystemTrayIcon);
|
||||||
|
|
||||||
if (qpa_sys) {
|
if (qpa_sys) {
|
||||||
install_sys_qpa();
|
install_sys_qpa();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_Q(QSystemTrayIcon);
|
|
||||||
if (!sys && locateSystemTray()) {
|
if (!sys) {
|
||||||
|
if (!trayWatcher)
|
||||||
|
trayWatcher = new QSystemTrayWatcher(q);
|
||||||
|
|
||||||
|
if (locateSystemTray()) {
|
||||||
sys = new QSystemTrayIconSys(q);
|
sys = new QSystemTrayIconSys(q);
|
||||||
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
|
|
||||||
sys, SLOT(systemTrayWindowChanged(QScreen*)));
|
|
||||||
sys->show();
|
sys->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QRect QSystemTrayIconPrivate::geometry_sys() const
|
QRect QSystemTrayIconPrivate::geometry_sys() const
|
||||||
{
|
{
|
||||||
@ -241,14 +265,21 @@ void QSystemTrayIconPrivate::remove_sys()
|
|||||||
remove_sys_qpa();
|
remove_sys_qpa();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSystemTrayIconPrivate::destroyIcon()
|
||||||
|
{
|
||||||
if (!sys)
|
if (!sys)
|
||||||
return;
|
return;
|
||||||
QBalloonTip::hideBalloon();
|
QBalloonTip::hideBalloon();
|
||||||
sys->hide(); // this should do the trick, but...
|
sys->hide();
|
||||||
delete sys; // wm may resize system tray only for DestroyEvents
|
delete sys;
|
||||||
sys = 0;
|
sys = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QSystemTrayIconPrivate::updateIcon_sys()
|
void QSystemTrayIconPrivate::updateIcon_sys()
|
||||||
{
|
{
|
||||||
if (qpa_sys) {
|
if (qpa_sys) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user