Fix tray icon menu display in Fedora (Qt 5.6.2 broke it).

When activeChanged() is emitted we call updateTrayMenu(), that
always called trayIcon->setContextMenu(), which was hiding the
just-shown tray icon menu in case of right click with main
window being active. Now we call trayIcon->setContextMenu()
only if the contextMenu value has really changed for trayIcon.
This commit is contained in:
John Preston 2016-10-19 15:24:39 +03:00
parent 40fc7379bc
commit 3503be03c9
3 changed files with 137 additions and 118 deletions

View File

@ -167,7 +167,7 @@ void MainWindow::init() {
Application::instance()->installEventFilter(this); Application::instance()->installEventFilter(this);
connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onStateChanged(Qt::WindowState))); connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onStateChanged(Qt::WindowState)));
connect(windowHandle(), SIGNAL(activeChanged()), this, SLOT(checkHistoryActivation()), Qt::QueuedConnection); connect(windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()), Qt::QueuedConnection);
QPalette p(palette()); QPalette p(palette());
p.setColor(QPalette::Window, st::windowBg->c); p.setColor(QPalette::Window, st::windowBg->c);
@ -178,24 +178,32 @@ void MainWindow::init() {
psInitSize(); psInitSize();
} }
void MainWindow::onWindowActiveChanged() {
checkHistoryActivation();
QTimer::singleShot(1, this, SLOT(updateTrayMenu()));
}
void MainWindow::firstShow() { void MainWindow::firstShow() {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
trayIconMenu = new PopupMenu(); trayIconMenu = new PopupMenu();
trayIconMenu->deleteOnHide(false); trayIconMenu->deleteOnHide(false);
#else #else // Q_OS_WIN
trayIconMenu = new QMenu(this); trayIconMenu = new QMenu(this);
#endif #endif // else for Q_OS_WIN
auto notificationItem = lang(Global::DesktopNotify()
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) { auto isLinux = (cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64);
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true); auto notificationActionText = lang(Global::DesktopNotify()
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true); ? lng_disable_notifications_from_tray
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true); : lng_enable_notifications_from_tray);
} else {
if (isLinux) {
trayIconMenu->addAction(lang(lng_open_from_tray), this, SLOT(showFromTray()))->setEnabled(true); trayIconMenu->addAction(lang(lng_open_from_tray), this, SLOT(showFromTray()))->setEnabled(true);
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true); trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true); trayIconMenu->addAction(notificationActionText, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true);
} else {
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
trayIconMenu->addAction(notificationActionText, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true); trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true);
} }
psUpdateWorkmode(); psUpdateWorkmode();
@ -594,7 +602,6 @@ void MainWindow::checkHistoryActivation() {
if (main && MTP::authedId() && doWeReadServerHistory()) { if (main && MTP::authedId() && doWeReadServerHistory()) {
main->markActiveHistoryAsRead(); main->markActiveHistoryAsRead();
} }
QTimer::singleShot(1, this, SLOT(updateTrayMenu()));
} }
void MainWindow::layerHidden() { void MainWindow::layerHidden() {
@ -744,7 +751,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
case QEvent::ApplicationActivate: case QEvent::ApplicationActivate:
if (obj == Application::instance()) { if (obj == Application::instance()) {
psUserActionDone(); psUserActionDone();
QTimer::singleShot(1, this, SLOT(checkHistoryActivation())); QTimer::singleShot(1, this, SLOT(onWindowActiveChanged()));
} }
break; break;
@ -817,29 +824,37 @@ bool MainWindow::minimizeToTray() {
void MainWindow::updateTrayMenu(bool force) { void MainWindow::updateTrayMenu(bool force) {
if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return; if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return;
bool active = isActive(false); auto iconMenu = trayIconMenu;
QString notificationItem = lang(Global::DesktopNotify() auto actions = iconMenu->actions();
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray); auto isLinux = (cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64);
if (isLinux) {
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) { auto minimizeAction = actions.at(1);
QAction *toggle = trayIconMenu->actions().at(0); minimizeAction->setDisabled(!isVisible());
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray()));
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(showFromTray()));
connect(toggle, SIGNAL(triggered(bool)), this, active ? SLOT(minimizeToTray()) : SLOT(showFromTray()));
toggle->setText(lang(active ? lng_minimize_to_tray : lng_open_from_tray));
trayIconMenu->actions().at(1)->setText(notificationItem);
} else { } else {
QAction *minimize = trayIconMenu->actions().at(1); auto active = isActive(false);
minimize->setDisabled(!isVisible()); auto toggleAction = actions.at(0);
disconnect(toggleAction, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray()));
disconnect(toggleAction, SIGNAL(triggered(bool)), this, SLOT(showFromTray()));
connect(toggleAction, SIGNAL(triggered(bool)), this, active ? SLOT(minimizeToTray()) : SLOT(showFromTray()));
toggleAction->setText(lang(active ? lng_minimize_to_tray : lng_open_from_tray));
trayIconMenu->actions().at(2)->setText(notificationItem); // On macOS just remove trayIcon menu if the window is not active.
// So we will activate the window on click instead of showing the menu.
if (!active && (cPlatform() == dbipMac || cPlatform() == dbipMacOld)) {
iconMenu = nullptr;
} }
}
auto notificationAction = actions.at(isLinux ? 2 : 1);
auto notificationActionText = lang(Global::DesktopNotify()
? lng_disable_notifications_from_tray
: lng_enable_notifications_from_tray);
notificationAction->setText(notificationActionText);
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
if (trayIcon) { if (trayIcon && trayIcon->contextMenu() != iconMenu) {
trayIcon->setContextMenu((active || cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64) ? trayIconMenu : 0); trayIcon->setContextMenu(iconMenu);
} }
#endif #endif // !Q_OS_WIN
psTrayMenuUpdated(); psTrayMenuUpdated();
} }
@ -902,7 +917,7 @@ void MainWindow::activate() {
void MainWindow::noIntro(IntroWidget *was) { void MainWindow::noIntro(IntroWidget *was) {
if (was == intro) { if (was == intro) {
intro = 0; intro = nullptr;
} }
} }

View File

@ -126,6 +126,8 @@ public:
void noLayerStack(LayerStackWidget *was); void noLayerStack(LayerStackWidget *was);
void layerFinishedHide(LayerStackWidget *was); void layerFinishedHide(LayerStackWidget *was);
void checkHistoryActivation();
void fixOrder(); void fixOrder();
enum TempDirState { enum TempDirState {
@ -178,8 +180,6 @@ public:
public slots: public slots:
void updateIsActive(int timeout = 0); void updateIsActive(int timeout = 0);
void checkHistoryActivation();
void checkAutoLock(); void checkAutoLock();
void showSettings(); void showSettings();
@ -222,6 +222,8 @@ private slots:
void onStateChanged(Qt::WindowState state); void onStateChanged(Qt::WindowState state);
void onSettingsDestroyed(QObject *was); void onSettingsDestroyed(QObject *was);
void onWindowActiveChanged();
private: private:
void showConnecting(const QString &text, const QString &reconnect = QString()); void showConnecting(const QString &text, const QString &reconnect = QString());
void hideConnecting(); void hideConnecting();

View File

@ -237,9 +237,9 @@ void MainWindow::psSetupTrayIcon() {
if (!cSupportTray()) return; if (!cSupportTray()) return;
psUpdateCounter(); psUpdateCounter();
} else { } else {
LOG(("Using Qt tray icon."));
if (!trayIcon) { if (!trayIcon) {
trayIcon = new QSystemTrayIcon(this); trayIcon = new QSystemTrayIcon(this);
QIcon icon; QIcon icon;
QFileInfo iconFile(_trayIconImageFile()); QFileInfo iconFile(_trayIconImageFile());
if (iconFile.exists()) { if (iconFile.exists()) {
@ -532,7 +532,7 @@ void MainWindow::psCreateTrayIcon() {
QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); QByteArray path = QFile::encodeName(iconFile.absoluteFilePath());
_trayIndicator = Libs::app_indicator_new("Telegram Desktop", path.constData(), APP_INDICATOR_CATEGORY_APPLICATION_STATUS); _trayIndicator = Libs::app_indicator_new("Telegram Desktop", path.constData(), APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
if (_trayIndicator) { if (_trayIndicator) {
DEBUG_LOG(("Created appindicator!")); LOG(("Using appindicator tray icon."));
} else { } else {
DEBUG_LOG(("Failed to app_indicator_new()!")); DEBUG_LOG(("Failed to app_indicator_new()!"));
} }
@ -565,6 +565,8 @@ void MainWindow::psCreateTrayIcon() {
_trayIcon = Libs::gtk_status_icon_new_from_pixbuf(_trayPixbuf); _trayIcon = Libs::gtk_status_icon_new_from_pixbuf(_trayPixbuf);
} }
if (_trayIcon) { if (_trayIcon) {
LOG(("Using GTK status tray icon."));
Libs::g_signal_connect_helper(_trayIcon, "popup-menu", GCallback(_trayIconPopup), _trayMenu); Libs::g_signal_connect_helper(_trayIcon, "popup-menu", GCallback(_trayIconPopup), _trayMenu);
Libs::g_signal_connect_helper(_trayIcon, "activate", GCallback(_trayIconActivate), _trayMenu); Libs::g_signal_connect_helper(_trayIcon, "activate", GCallback(_trayIconActivate), _trayMenu);
Libs::g_signal_connect_helper(_trayIcon, "size-changed", GCallback(_trayIconResized), _trayMenu); Libs::g_signal_connect_helper(_trayIcon, "size-changed", GCallback(_trayIconResized), _trayMenu);