diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index d40f8a3be..05d86122e 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -103,7 +103,6 @@ Application::Application(not_null launcher) , _langCloudManager(std::make_unique(langpack())) , _emojiKeywords(std::make_unique()) , _audio(std::make_unique()) -, _notifications(std::make_unique()) , _logo(Window::LoadLogo()) , _logoNoMargin(Window::LoadLogoNoMargin()) , _autoLockTimer([=] { checkAutoLock(); }) { @@ -180,7 +179,10 @@ void Application::run() { ThirdParty::start(); Global::start(); - refreshGlobalProxy(); // Depends on Global::started(). + refreshGlobalProxy(); // Depends on Global::start(). + + // Depends on OpenSSL on macOS, so on ThirdParty::start(). + _notifications = std::make_unique(); startLocalStorage(); ValidateScale(); diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index f3abac6c0..fefedeb62 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -108,6 +108,8 @@ public: return *_animationsManager; } [[nodiscard]] Window::Notifications::System ¬ifications() const { + Expects(_notifications != nullptr); + return *_notifications; } @@ -305,7 +307,8 @@ private: const std::unique_ptr _audio; // Notifications should be destroyed before _audio. - const std::unique_ptr _notifications; + // Mutable because is created in run() after OpenSSL is inited. + std::unique_ptr _notifications; const QImage _logo; const QImage _logoNoMargin; diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h index feaca96cc..218323c53 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h @@ -156,7 +156,6 @@ private: bool _animatingMode = false; std::unique_ptr _connecting; - int _unreadCounterSubscription = 0; base::Timer _onlineUpdater; rpl::event_stream<> _forwardSelection; diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 2ec05db8e..c3a5a3f66 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -499,7 +499,6 @@ void Account::forcedLogOut() { void Account::loggedOut() { _loggingOut = false; Media::Player::mixer()->stopAndClear(); - Core::App().settings().setVoiceMsgPlaybackDoubled(false); // #TODO multi properly reset settings if (const auto window = Core::App().activeWindow()) { window->tempDirDelete(Local::ClearManagerAll); } diff --git a/Telegram/SourceFiles/main/main_domain.cpp b/Telegram/SourceFiles/main/main_domain.cpp index 12c923237..536a33164 100644 --- a/Telegram/SourceFiles/main/main_domain.cpp +++ b/Telegram/SourceFiles/main/main_domain.cpp @@ -66,6 +66,10 @@ void Domain::activateFromStorage(int index) { _accountToActivate = index; } +int Domain::activeForStorage() const { + return _accountToActivate; +} + void Domain::resetWithForgottenPasscode() { if (_accounts.empty()) { _local->startFromScratch(); diff --git a/Telegram/SourceFiles/main/main_domain.h b/Telegram/SourceFiles/main/main_domain.h index 9d572b123..96b9e681b 100644 --- a/Telegram/SourceFiles/main/main_domain.h +++ b/Telegram/SourceFiles/main/main_domain.h @@ -66,6 +66,7 @@ public: // Interface for Storage::Domain. void accountAddedInStorage(AccountWithIndex accountWithIndex); void activateFromStorage(int index); + [[nodiscard]] int activeForStorage() const; private: void activateAfterStarting(); diff --git a/Telegram/SourceFiles/main/main_session_settings.h b/Telegram/SourceFiles/main/main_session_settings.h index 22840e735..fde64675c 100644 --- a/Telegram/SourceFiles/main/main_session_settings.h +++ b/Telegram/SourceFiles/main/main_session_settings.h @@ -29,7 +29,7 @@ public: SessionSettings(); [[nodiscard]] QByteArray serialize() const; - [[nodiscard]] void addFromSerialized(const QByteArray &serialized); + void addFromSerialized(const QByteArray &serialized); void setSupportSwitch(Support::SwitchSettings value) { _supportSwitch = value; diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index 1a57be422..054c402c0 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/mac/base_utilities_mac.h" #include "history/history.h" #include "ui/empty_userpic.h" +#include "main/main_session.h" #include "mainwindow.h" #include "facades.h" #include "styles/style_window.h" @@ -91,28 +92,37 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm); return; } + NSNumber *selfObject = [notificationUserInfo objectForKey:@"self"]; + const auto notificationSelfId = selfObject ? [selfObject intValue] : 0; + if (!notificationSelfId) { + LOG(("App Error: A notification with unknown self was received")); + return; + } NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"]; - auto notificationPeerId = peerObject ? [peerObject unsignedLongLongValue] : 0ULL; + const auto notificationPeerId = peerObject ? [peerObject unsignedLongLongValue] : 0ULL; if (!notificationPeerId) { LOG(("App Error: A notification with unknown peer was received")); return; } NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"]; - auto notificationMsgId = msgObject ? [msgObject intValue] : 0; + const auto notificationMsgId = msgObject ? [msgObject intValue] : 0; + + const auto my = Window::Notifications::Manager::NotificationId{ + .peerId = notificationPeerId, + .msgId = notificationMsgId, + .selfId = notificationSelfId + }; if (notification.activationType == NSUserNotificationActivationTypeReplied) { const auto notificationReply = QString::fromUtf8([[[notification response] string] UTF8String]); const auto manager = _manager; crl::on_main(manager, [=] { - manager->notificationReplied( - notificationPeerId, - notificationMsgId, - { notificationReply, {} }); + manager->notificationReplied(my, { notificationReply, {} }); }); } else if (notification.activationType == NSUserNotificationActivationTypeContentsClicked) { const auto manager = _manager; crl::on_main(manager, [=] { - manager->notificationActivated(notificationPeerId, notificationMsgId); + manager->notificationActivated(my); }); } @@ -194,13 +204,16 @@ private: std::condition_variable _clearingCondition; struct ClearFromHistory { - PeerId peerId; + FullPeer fullPeer; + }; + struct ClearFromSession { + UserId selfId = 0; }; struct ClearAll { }; struct ClearFinish { }; - using ClearTask = base::variant; + using ClearTask = base::variant; std::vector _clearingTasks; }; @@ -236,7 +249,7 @@ void Manager::Private::showNotification( auto identifierValue = Q2NSString(identifier); [notification setIdentifier:identifierValue]; } - [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer->id],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:_managerId],@"manager",nil]]; + [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer->session().userId()],@"self",[NSNumber numberWithUnsignedLongLong:peer->id],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:_managerId],@"manager",nil]]; [notification setTitle:Q2NSString(title)]; [notification setSubtitle:Q2NSString(subtitle)]; @@ -265,7 +278,8 @@ void Manager::Private::clearingThreadLoop() { auto finished = false; while (!finished) { auto clearAll = false; - auto clearFromPeers = std::set(); // Better to use flatmap. + auto clearFromPeers = base::flat_set(); + auto clearFromSessions = base::flat_set(); { std::unique_lock lock(_clearingMutex); @@ -279,17 +293,25 @@ void Manager::Private::clearingThreadLoop() { } else if (base::get_if(&task)) { clearAll = true; } else if (auto fromHistory = base::get_if(&task)) { - clearFromPeers.insert(fromHistory->peerId); + clearFromPeers.emplace(fromHistory->fullPeer); + } else if (auto fromSession = base::get_if(&task)) { + clearFromSessions.emplace(fromSession->selfId); } } _clearingTasks.clear(); } - auto clearByPeer = [&clearFromPeers](NSDictionary *notificationUserInfo) { + auto clearBySpecial = [&](NSDictionary *notificationUserInfo) { + NSNumber *selfObject = [notificationUserInfo objectForKey:@"self"]; + const auto notificationSelfId = selfObject ? [selfObject intValue] : 0; + if (!notificationSelfId) { + return true; + } if (NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"]) { - auto notificationPeerId = [peerObject unsignedLongLongValue]; + const auto notificationPeerId = [peerObject unsignedLongLongValue]; if (notificationPeerId) { - return (clearFromPeers.find(notificationPeerId) != clearFromPeers.cend()); + return clearFromSessions.contains(notificationSelfId) + || clearFromPeers.contains(FullPeer{ notificationPeerId, notificationSelfId }); } } return true; @@ -302,7 +324,7 @@ void Manager::Private::clearingThreadLoop() { NSNumber *managerIdObject = [notificationUserInfo objectForKey:@"manager"]; auto notificationManagerId = managerIdObject ? [managerIdObject unsignedLongLongValue] : 0ULL; if (notificationManagerId == _managerId) { - if (clearAll || clearByPeer(notificationUserInfo)) { + if (clearAll || clearBySpecial(notificationUserInfo)) { [center removeDeliveredNotification:notification]; } } @@ -326,11 +348,11 @@ void Manager::Private::clearAll() { } void Manager::Private::clearFromHistory(not_null history) { - putClearTask(ClearFromHistory { history->peer->id }); + putClearTask(ClearFromHistory { FullPeer{ history->peer->id, history->session().userId() } }); } void Manager::Private::clearFromSession(not_null session) { - putClearTask(); // #TODO multi + putClearTask(ClearFromSession { session->userId() }); } void Manager::Private::updateDelegate() { diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.mm b/Telegram/SourceFiles/platform/mac/specific_mac.mm index 00ab6fec0..d3668173f 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac.mm @@ -12,11 +12,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_widget.h" #include "core/crash_reports.h" #include "core/sandbox.h" +#include "core/application.h" +#include "core/core_settings.h" #include "storage/localstorage.h" #include "mainwindow.h" #include "history/history_location_manager.h" #include "base/platform/mac/base_utilities_mac.h" -#include "facades.h" #include #include @@ -279,7 +280,7 @@ void psSendToMenu(bool send, bool silent) { } void psDownloadPathEnableAccess() { - objc_downloadPathEnableAccess(Global::DownloadPathBookmark()); + objc_downloadPathEnableAccess(Core::App().settings().downloadPathBookmark()); } QByteArray psDownloadPathBookmark(const QString &path) { diff --git a/Telegram/SourceFiles/platform/mac/window_title_mac.mm b/Telegram/SourceFiles/platform/mac/window_title_mac.mm index b5428524f..22b88eabf 100644 --- a/Telegram/SourceFiles/platform/mac/window_title_mac.mm +++ b/Telegram/SourceFiles/platform/mac/window_title_mac.mm @@ -42,7 +42,7 @@ TitleWidget::TitleWidget(MainWindow *parent, int height) _font = st::normalFont; } - Core::App().unreadBadgeValue( + Core::App().unreadBadgeChanges( ) | rpl::start_with_next([=] { update(); }, lifetime()); diff --git a/Telegram/SourceFiles/settings/settings_calls.cpp b/Telegram/SourceFiles/settings/settings_calls.cpp index b5cf1d3c1..68f14a305 100644 --- a/Telegram/SourceFiles/settings/settings_calls.cpp +++ b/Telegram/SourceFiles/settings/settings_calls.cpp @@ -293,12 +293,12 @@ void Calls::setupContent() { tr::lng_settings_call_audio_ducking(), st::settingsButton )->toggleOn( - rpl::single(Global::CallAudioDuckingEnabled()) + rpl::single(settings.callAudioDuckingEnabled()) )->toggledValue() | rpl::filter([](bool enabled) { - return (enabled != Global::CallAudioDuckingEnabled()); + return (enabled != Core::App().settings().callAudioDuckingEnabled()); }) | rpl::start_with_next([=](bool enabled) { - Global::SetCallAudioDuckingEnabled(enabled); - _controller->session().saveSettingsDelayed(); + Core::App().settings().setCallAudioDuckingEnabled(enabled); + Core::App().saveSettingsDelayed(); if (const auto call = _controller->session().calls().currentCall()) { call->setAudioDuckingEnabled(enabled); } diff --git a/Telegram/SourceFiles/storage/storage_domain.cpp b/Telegram/SourceFiles/storage/storage_domain.cpp index c3ac61a36..bdfb8d33b 100644 --- a/Telegram/SourceFiles/storage/storage_domain.cpp +++ b/Telegram/SourceFiles/storage/storage_domain.cpp @@ -222,18 +222,12 @@ void Domain::writeAccounts() { auto keySize = sizeof(qint32) + sizeof(qint32) * list.size(); - const auto active = &_owner->active(); - auto activeIndex = -1; - EncryptedDescriptor keyData(keySize); keyData.stream << qint32(list.size()); for (const auto &[index, account] : list) { - if (active == account.get()) { - activeIndex = index; - } keyData.stream << qint32(index); } - keyData.stream << qint32(activeIndex); + keyData.stream << qint32(_owner->activeForStorage()); key.writeEncrypted(keyData, _localKey); } diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index b89bc969a..b450964dc 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -535,13 +535,17 @@ void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) { _themeTile = themeTile; } -void ChatBackground::start() { +void ChatBackground::initialRead() { if (!Data::details::IsUninitializedWallPaper(_paper)) { return; } if (!Local::readBackground()) { set(Data::ThemeWallPaper()); } +} + +void ChatBackground::start() { + initialRead(); Core::App().domain().activeSessionValue( ) | rpl::filter([=](Main::Session *session) { @@ -851,16 +855,16 @@ bool ChatBackground::isMonoColorImage() const { return _isMonoColorImage; } -void ChatBackground::ensureStarted() { +void ChatBackground::ensureInitialRead() { if (_pixmap.isNull() && !_paper.backgroundColor()) { // We should start first, otherwise the default call - // to start() will reset this value to _themeTile. - start(); + // to initialRead() will reset this value to _themeTile. + initialRead(); } } void ChatBackground::setTile(bool tile) { - ensureStarted(); + ensureInitialRead(); const auto old = this->tile(); if (nightMode()) { setTileNightValue(tile); @@ -877,12 +881,12 @@ void ChatBackground::setTile(bool tile) { } void ChatBackground::setTileDayValue(bool tile) { - ensureStarted(); + ensureInitialRead(); _tileDayValue = tile; } void ChatBackground::setTileNightValue(bool tile) { - ensureStarted(); + ensureInitialRead(); _tileNightValue = tile; } @@ -917,7 +921,7 @@ void ChatBackground::reset() { } void ChatBackground::saveForRevert() { - ensureStarted(); + ensureInitialRead(); if (!Data::details::IsTestingThemeWallPaper(_paper) && !Data::details::IsTestingDefaultWallPaper(_paper)) { _paperForRevert = _paper; @@ -1009,7 +1013,7 @@ void ChatBackground::keepApplied(const Object &object, bool write) { } bool ChatBackground::isNonDefaultThemeOrBackground() { - start(); + initialRead(); return nightMode() ? (_themeObject.pathAbsolute != NightThemePath() || !Data::IsThemeWallPaper(_paper)) @@ -1018,7 +1022,7 @@ bool ChatBackground::isNonDefaultThemeOrBackground() { } bool ChatBackground::isNonDefaultBackground() { - start(); + initialRead(); return _themeObject.pathAbsolute.isEmpty() ? !Data::IsDefaultWallPaper(_paper) : !Data::IsThemeWallPaper(_paper); diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index be9833fb9..71715cbe2 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -129,11 +129,12 @@ class ChatBackground public: ChatBackground(); + void start(); + // This method is allowed to (and should) be called before start(). void setThemeData(QImage &&themeImage, bool themeTile); // This method is setting the default (themed) image if none was set yet. - void start(); void set(const Data::WallPaper &paper, QImage image = QImage()); void setTile(bool tile); void setTileDayValue(bool tile); @@ -177,7 +178,8 @@ private: QColor original; }; - void ensureStarted(); + void initialRead(); + void ensureInitialRead(); void saveForRevert(); void setPreparedImage(QImage original, QImage prepared); void preparePixmaps(QImage image); diff --git a/Telegram/SourceFiles/window/window_title.h b/Telegram/SourceFiles/window/window_title.h index 50260a354..3226b3763 100644 --- a/Telegram/SourceFiles/window/window_title.h +++ b/Telegram/SourceFiles/window/window_title.h @@ -26,9 +26,9 @@ enum class HitTestResult { TopLeft, }; -class TitleWidget : public TWidget { +class TitleWidget : public Ui::RpWidget { public: - using TWidget::TWidget; + using RpWidget::RpWidget; virtual void init() { }