Implement three items tray menu on Linux

This commit is contained in:
Ilya Fedin 2021-02-23 04:55:14 +04:00 committed by John Preston
parent bb119ca967
commit 1a3253ae8b
8 changed files with 36 additions and 57 deletions

View file

@ -137,17 +137,6 @@ Application::Application(not_null<Launcher*> launcher)
UpdateChecker().setMtproto(session); UpdateChecker().setMtproto(session);
} }
}, _lifetime); }, _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() { Application::~Application() {

View file

@ -138,18 +138,17 @@ void MainWindow::createTrayIconMenu() {
trayIconMenu->deleteOnHide(false); trayIconMenu->deleteOnHide(false);
#else // Q_OS_WIN #else // Q_OS_WIN
trayIconMenu = new QMenu(this); trayIconMenu = new QMenu(this);
connect(trayIconMenu, &QMenu::aboutToShow, [=] {
updateIsActive();
updateTrayMenu();
});
#endif // else for Q_OS_WIN #endif // else for Q_OS_WIN
auto notificationActionText = Core::App().settings().desktopNotify() auto notificationActionText = Core::App().settings().desktopNotify()
? tr::lng_disable_notifications_from_tray(tr::now) ? tr::lng_disable_notifications_from_tray(tr::now)
: tr::lng_enable_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<rpl::lifetime>();
trayIconMenu->addAction(tr::lng_minimize_to_tray(tr::now), [=] { trayIconMenu->addAction(tr::lng_minimize_to_tray(tr::now), [=] {
if (_activeForTrayIconAction) { if (_activeForTrayIconAction) {
minimizeToTray(); minimizeToTray();
@ -205,7 +204,6 @@ void MainWindow::finishFirstShow() {
applyInitialWorkMode(); applyInitialWorkMode();
createGlobalMenu(); createGlobalMenu();
firstShadowsUpdate(); firstShadowsUpdate();
updateTrayMenu();
windowDeactivateEvents( windowDeactivateEvents(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
@ -644,14 +642,10 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) {
return Platform::MainWindow::eventFilter(object, e); return Platform::MainWindow::eventFilter(object, e);
} }
void MainWindow::updateTrayMenu(bool force) { void MainWindow::updateTrayMenu() {
if (!trayIconMenu || (Platform::IsWindows() && !force)) return; if (!trayIconMenu) return;
auto actions = trayIconMenu->actions(); auto actions = trayIconMenu->actions();
if (Platform::IsLinux() && !Platform::IsWayland()) {
const auto minimizeAction = actions.at(1);
minimizeAction->setEnabled(isVisible());
} else {
const auto active = isActiveForTrayMenu(); const auto active = isActiveForTrayMenu();
if (_activeForTrayIconAction != active) { if (_activeForTrayIconAction != active) {
_activeForTrayIconAction = active; _activeForTrayIconAction = active;
@ -660,8 +654,7 @@ void MainWindow::updateTrayMenu(bool force) {
? tr::lng_minimize_to_tray(tr::now) ? tr::lng_minimize_to_tray(tr::now)
: tr::lng_open_from_tray(tr::now)); : tr::lng_open_from_tray(tr::now));
} }
} auto notificationAction = actions.at(1);
auto notificationAction = actions.at(Platform::IsLinux() && !Platform::IsWayland() ? 2 : 1);
auto notificationActionText = Core::App().settings().desktopNotify() auto notificationActionText = Core::App().settings().desktopNotify()
? tr::lng_disable_notifications_from_tray(tr::now) ? tr::lng_disable_notifications_from_tray(tr::now)
: tr::lng_enable_notifications_from_tray(tr::now); : tr::lng_enable_notifications_from_tray(tr::now);
@ -691,7 +684,7 @@ void MainWindow::handleTrayIconActication(
return; return;
} }
if (reason == QSystemTrayIcon::Context) { if (reason == QSystemTrayIcon::Context) {
updateTrayMenu(true); updateTrayMenu();
base::call_delayed(1, this, [=] { base::call_delayed(1, this, [=] {
psShowTrayMenu(); psShowTrayMenu();
}); });

View file

@ -79,7 +79,7 @@ public:
} }
void showMainMenu(); void showMainMenu();
void updateTrayMenu(bool force = false) override; void updateTrayMenu() override;
void fixOrder() override; void fixOrder() override;
void showSpecialLayer( void showSpecialLayer(

View file

@ -628,11 +628,6 @@ void MainWindow::psShowTrayMenu() {
} }
void MainWindow::psTrayMenuUpdated() { 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 #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
@ -692,7 +687,6 @@ void MainWindow::attachToSNITrayIcon() {
handleTrayIconActication(QSystemTrayIcon::MiddleClick); handleTrayIconActication(QSystemTrayIcon::MiddleClick);
}); });
}); });
updateTrayMenu();
} }
void MainWindow::sniSignalEmitted( void MainWindow::sniSignalEmitted(
@ -804,6 +798,7 @@ void MainWindow::psSetupTrayIcon() {
this); this);
_sniTrayIcon->setTitle(AppName.utf16()); _sniTrayIcon->setTitle(AppName.utf16());
_sniTrayIcon->setContextMenu(trayIconMenu);
setSNITrayIcon(counter, muted); setSNITrayIcon(counter, muted);
attachToSNITrayIcon(); attachToSNITrayIcon();

View file

@ -525,6 +525,18 @@ void MainWindow::stateChangedHook(Qt::WindowState state) {
void MainWindow::handleActiveChangedHook() { void MainWindow::handleActiveChangedHook() {
InvokeQueued(this, [this] { _private->updateNativeTitle(); }); 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() { void MainWindow::initHook() {
@ -555,16 +567,6 @@ void MainWindow::psShowTrayMenu() {
} }
void MainWindow::psTrayMenuUpdated() { 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() { void MainWindow::psSetupTrayIcon() {
@ -573,6 +575,11 @@ void MainWindow::psSetupTrayIcon() {
trayIcon->setIcon(generateIconForTray( trayIcon->setIcon(generateIconForTray(
Core::App().unreadBadge(), Core::App().unreadBadge(),
Core::App().unreadBadgeMuted())); Core::App().unreadBadgeMuted()));
if (isActiveForTrayMenu()) {
trayIcon->setContextMenu(trayIconMenu);
} else {
trayIcon->setContextMenu(nullptr);
}
attachToTrayIcon(trayIcon); attachToTrayIcon(trayIcon);
} else { } else {
updateIconCounters(); updateIconCounters();

View file

@ -280,7 +280,6 @@ void MainWindow::handleActiveChanged() {
Core::App().checkMediaViewActivation(); Core::App().checkMediaViewActivation();
} }
base::call_delayed(1, this, [this] { base::call_delayed(1, this, [this] {
updateTrayMenu();
handleActiveChangedHook(); handleActiveChangedHook();
}); });
} }
@ -300,7 +299,6 @@ void MainWindow::handleVisibleChanged(bool visible) {
void MainWindow::showFromTray() { void MainWindow::showFromTray() {
base::call_delayed(1, this, [this] { base::call_delayed(1, this, [this] {
updateTrayMenu();
updateGlobalMenu(); updateGlobalMenu();
}); });
activate(); activate();
@ -556,7 +554,6 @@ void MainWindow::attachToTrayIcon(not_null<QSystemTrayIcon*> icon) {
handleTrayIconActication(reason); handleTrayIconActication(reason);
}); });
}); });
App::wnd()->updateTrayMenu();
} }
void MainWindow::paintEvent(QPaintEvent *e) { void MainWindow::paintEvent(QPaintEvent *e) {
@ -694,7 +691,6 @@ bool MainWindow::minimizeToTray() {
closeWithoutDestroy(); closeWithoutDestroy();
controller().updateIsActiveBlur(); controller().updateIsActiveBlur();
updateTrayMenu();
updateGlobalMenu(); updateGlobalMenu();
showTrayTooltip(); showTrayTooltip();
return true; return true;

View file

@ -90,7 +90,7 @@ public:
// Returns how much could the window get extended. // Returns how much could the window get extended.
int tryToExtendWidthBy(int addToWidth); int tryToExtendWidthBy(int addToWidth);
virtual void updateTrayMenu(bool force = false) { virtual void updateTrayMenu() {
} }
virtual void fixOrder() { virtual void fixOrder() {
} }

View file

@ -54,7 +54,6 @@ System::System()
, _waitForAllGroupedTimer([=] { showGrouped(); }) { , _waitForAllGroupedTimer([=] { showGrouped(); }) {
subscribe(settingsChanged(), [=](ChangeType type) { subscribe(settingsChanged(), [=](ChangeType type) {
if (type == ChangeType::DesktopEnabled) { if (type == ChangeType::DesktopEnabled) {
App::wnd()->updateTrayMenu();
clearAll(); clearAll();
} else if (type == ChangeType::ViewParams) { } else if (type == ChangeType::ViewParams) {
updateAll(); updateAll();