From 1a3253ae8b537a756c3bd06a5f5ceef471548d52 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 23 Feb 2021 04:55:14 +0400 Subject: [PATCH] Implement three items tray menu on Linux --- Telegram/SourceFiles/core/application.cpp | 11 ------ Telegram/SourceFiles/mainwindow.cpp | 39 ++++++++----------- Telegram/SourceFiles/mainwindow.h | 2 +- .../platform/linux/main_window_linux.cpp | 7 +--- .../platform/mac/main_window_mac.mm | 27 ++++++++----- Telegram/SourceFiles/window/main_window.cpp | 4 -- Telegram/SourceFiles/window/main_window.h | 2 +- .../window/notifications_manager.cpp | 1 - 8 files changed, 36 insertions(+), 57 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 3b5d6fb981..c1eea20a17 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -137,17 +137,6 @@ Application::Application(not_null launcher) UpdateChecker().setMtproto(session); } }, _lifetime); - - _domain->activeValue( - ) | rpl::filter(rpl::mappers::_1 != nullptr - ) | rpl::take(1) | rpl::start_with_next([=] { - if (_window) { - // Global::DesktopNotify is used in updateTrayMenu. - // This should be called when user settings are read. - // Right now after they are read the startMtp() is called. - _window->widget()->updateTrayMenu(); - } - }, _lifetime); } Application::~Application() { diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 39c2a4fd04..9bad8c5f5a 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -138,18 +138,17 @@ void MainWindow::createTrayIconMenu() { trayIconMenu->deleteOnHide(false); #else // Q_OS_WIN trayIconMenu = new QMenu(this); + + connect(trayIconMenu, &QMenu::aboutToShow, [=] { + updateIsActive(); + updateTrayMenu(); + }); #endif // else for Q_OS_WIN auto notificationActionText = Core::App().settings().desktopNotify() ? tr::lng_disable_notifications_from_tray(tr::now) : tr::lng_enable_notifications_from_tray(tr::now); - if (Platform::IsLinux() && !Platform::IsWayland()) { - trayIconMenu->addAction(tr::lng_open_from_tray(tr::now), [=] { - showFromTray(); - }); - } - const auto showLifetime = std::make_shared(); trayIconMenu->addAction(tr::lng_minimize_to_tray(tr::now), [=] { if (_activeForTrayIconAction) { minimizeToTray(); @@ -205,7 +204,6 @@ void MainWindow::finishFirstShow() { applyInitialWorkMode(); createGlobalMenu(); firstShadowsUpdate(); - updateTrayMenu(); windowDeactivateEvents( ) | rpl::start_with_next([=] { @@ -644,24 +642,19 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) { return Platform::MainWindow::eventFilter(object, e); } -void MainWindow::updateTrayMenu(bool force) { - if (!trayIconMenu || (Platform::IsWindows() && !force)) return; +void MainWindow::updateTrayMenu() { + if (!trayIconMenu) return; auto actions = trayIconMenu->actions(); - if (Platform::IsLinux() && !Platform::IsWayland()) { - const auto minimizeAction = actions.at(1); - minimizeAction->setEnabled(isVisible()); - } else { - const auto active = isActiveForTrayMenu(); - if (_activeForTrayIconAction != active) { - _activeForTrayIconAction = active; - const auto toggleAction = actions.at(0); - toggleAction->setText(_activeForTrayIconAction - ? tr::lng_minimize_to_tray(tr::now) - : tr::lng_open_from_tray(tr::now)); - } + const auto active = isActiveForTrayMenu(); + if (_activeForTrayIconAction != active) { + _activeForTrayIconAction = active; + const auto toggleAction = actions.at(0); + toggleAction->setText(_activeForTrayIconAction + ? tr::lng_minimize_to_tray(tr::now) + : tr::lng_open_from_tray(tr::now)); } - auto notificationAction = actions.at(Platform::IsLinux() && !Platform::IsWayland() ? 2 : 1); + auto notificationAction = actions.at(1); auto notificationActionText = Core::App().settings().desktopNotify() ? tr::lng_disable_notifications_from_tray(tr::now) : tr::lng_enable_notifications_from_tray(tr::now); @@ -691,7 +684,7 @@ void MainWindow::handleTrayIconActication( return; } if (reason == QSystemTrayIcon::Context) { - updateTrayMenu(true); + updateTrayMenu(); base::call_delayed(1, this, [=] { psShowTrayMenu(); }); diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index f47d016890..4cecda0ccc 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -79,7 +79,7 @@ public: } void showMainMenu(); - void updateTrayMenu(bool force = false) override; + void updateTrayMenu() override; void fixOrder() override; void showSpecialLayer( diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 23b036f356..8353d703b3 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -628,11 +628,6 @@ void MainWindow::psShowTrayMenu() { } void MainWindow::psTrayMenuUpdated() { -#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION - if (_sniTrayIcon && trayIconMenu) { - _sniTrayIcon->setContextMenu(trayIconMenu); - } -#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION } #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION @@ -692,7 +687,6 @@ void MainWindow::attachToSNITrayIcon() { handleTrayIconActication(QSystemTrayIcon::MiddleClick); }); }); - updateTrayMenu(); } void MainWindow::sniSignalEmitted( @@ -804,6 +798,7 @@ void MainWindow::psSetupTrayIcon() { this); _sniTrayIcon->setTitle(AppName.utf16()); + _sniTrayIcon->setContextMenu(trayIconMenu); setSNITrayIcon(counter, muted); attachToSNITrayIcon(); diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 6adde8c140..d583fe442f 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -525,6 +525,18 @@ void MainWindow::stateChangedHook(Qt::WindowState state) { void MainWindow::handleActiveChangedHook() { InvokeQueued(this, [this] { _private->updateNativeTitle(); }); + + // 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 (isActiveForTrayMenu()) { + if (trayIcon + && trayIconMenu + && trayIcon->contextMenu() != trayIconMenu) { + trayIcon->setContextMenu(trayIconMenu); + } + } else if (trayIcon) { + trayIcon->setContextMenu(nullptr); + } } void MainWindow::initHook() { @@ -555,16 +567,6 @@ void MainWindow::psShowTrayMenu() { } void MainWindow::psTrayMenuUpdated() { - // 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 (isActive()) { - if (trayIcon && trayIconMenu - && trayIcon->contextMenu() != trayIconMenu) { - trayIcon->setContextMenu(trayIconMenu); - } - } else if (trayIcon) { - trayIcon->setContextMenu(nullptr); - } } void MainWindow::psSetupTrayIcon() { @@ -573,6 +575,11 @@ void MainWindow::psSetupTrayIcon() { trayIcon->setIcon(generateIconForTray( Core::App().unreadBadge(), Core::App().unreadBadgeMuted())); + if (isActiveForTrayMenu()) { + trayIcon->setContextMenu(trayIconMenu); + } else { + trayIcon->setContextMenu(nullptr); + } attachToTrayIcon(trayIcon); } else { updateIconCounters(); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index ccd0d047a8..154f030e45 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -280,7 +280,6 @@ void MainWindow::handleActiveChanged() { Core::App().checkMediaViewActivation(); } base::call_delayed(1, this, [this] { - updateTrayMenu(); handleActiveChangedHook(); }); } @@ -300,7 +299,6 @@ void MainWindow::handleVisibleChanged(bool visible) { void MainWindow::showFromTray() { base::call_delayed(1, this, [this] { - updateTrayMenu(); updateGlobalMenu(); }); activate(); @@ -556,7 +554,6 @@ void MainWindow::attachToTrayIcon(not_null icon) { handleTrayIconActication(reason); }); }); - App::wnd()->updateTrayMenu(); } void MainWindow::paintEvent(QPaintEvent *e) { @@ -694,7 +691,6 @@ bool MainWindow::minimizeToTray() { closeWithoutDestroy(); controller().updateIsActiveBlur(); - updateTrayMenu(); updateGlobalMenu(); showTrayTooltip(); return true; diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index a6ab3749e0..811752a656 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -90,7 +90,7 @@ public: // Returns how much could the window get extended. int tryToExtendWidthBy(int addToWidth); - virtual void updateTrayMenu(bool force = false) { + virtual void updateTrayMenu() { } virtual void fixOrder() { } diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 324aad458e..55e8031e68 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -54,7 +54,6 @@ System::System() , _waitForAllGroupedTimer([=] { showGrouped(); }) { subscribe(settingsChanged(), [=](ChangeType type) { if (type == ChangeType::DesktopEnabled) { - App::wnd()->updateTrayMenu(); clearAll(); } else if (type == ChangeType::ViewParams) { updateAll();