diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 01c5ab5cc..ada8cd6ed 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -229,12 +229,22 @@ void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) { } void MainWindow::unreadCounterChangedHook() { - updateIconCounters(); + updateUnityCounter(); } -void MainWindow::updateIconCounters() { - updateWindowIcon(); +void MainWindow::updateWindowIcon() { + const auto session = sessionController() + ? &sessionController()->session() + : nullptr; + const auto supportIcon = session && session->supportMode(); + if (supportIcon != _usingSupportIcon || _icon.isNull()) { + _icon = Window::CreateIcon(session); + _usingSupportIcon = supportIcon; + } + setWindowIcon(_icon); +} +void MainWindow::updateUnityCounter() { #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION const auto launcherUrl = Glib::ustring( "application://" diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index aa563d423..8b74da57d 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -21,9 +21,10 @@ namespace Platform { class MainWindow : public Window::MainWindow { public: explicit MainWindow(not_null controller); - ~MainWindow(); + void updateWindowIcon() override; + protected: bool eventFilter(QObject *obj, QEvent *evt) override; @@ -35,6 +36,9 @@ protected: void createGlobalMenu() override; private: + void updateUnityCounter(); + void handleNativeSurfaceChanged(bool exist); + QMenuBar *psMainMenu = nullptr; QAction *psLogout = nullptr; QAction *psUndo = nullptr; @@ -56,8 +60,8 @@ private: QAction *psMonospace = nullptr; QAction *psClearFormat = nullptr; - void updateIconCounters(); - void handleNativeSurfaceChanged(bool exist); + QIcon _icon; + bool _usingSupportIcon = false; }; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 065e747cd..56674dc3a 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -50,7 +50,7 @@ private: friend class Private; void hideAndDeactivate(); - void updateIconCounters(); + void updateDockCounter(); std::unique_ptr _private; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index e865cd228..d6210917f 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -270,10 +270,10 @@ bool MainWindow::preventsQuit(Core::QuitReason reason) { } void MainWindow::unreadCounterChangedHook() { - updateIconCounters(); + updateDockCounter(); } -void MainWindow::updateIconCounters() { +void MainWindow::updateDockCounter() { const auto counter = Core::App().unreadBadge(); const auto string = !counter diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index e83517446..65d5b8468 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -228,16 +228,19 @@ int32 MainWindow::screenNameChecksum(const QString &name) const { void MainWindow::forceIconRefresh() { const auto refresher = std::make_unique(this); - refresher->setWindowFlags(static_cast(Qt::Tool) | Qt::FramelessWindowHint); + refresher->setWindowFlags( + static_cast(Qt::Tool) | Qt::FramelessWindowHint); refresher->setGeometry(x() + 1, y() + 1, 1, 1); auto palette = refresher->palette(); - palette.setColor(QPalette::Window, (isActiveWindow() ? st::titleBgActive : st::titleBg)->c); + palette.setColor( + QPalette::Window, + (isActiveWindow() ? st::titleBgActive : st::titleBg)->c); refresher->setPalette(palette); refresher->show(); refresher->raise(); refresher->activateWindow(); - updateIconCounters(); + updateTaskbarAndIconCounters(); } void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) { @@ -309,7 +312,7 @@ QRect MainWindow::computeDesktopRect() const { } void MainWindow::updateWindowIcon() { - updateIconCounters(); + updateTaskbarAndIconCounters(); } bool MainWindow::isActiveForTrayMenu() { @@ -318,10 +321,10 @@ bool MainWindow::isActiveForTrayMenu() { } void MainWindow::unreadCounterChangedHook() { - updateIconCounters(); + updateTaskbarAndIconCounters(); } -void MainWindow::updateIconCounters() { +void MainWindow::updateTaskbarAndIconCounters() { const auto counter = Core::App().unreadBadge(); const auto muted = Core::App().unreadBadgeMuted(); const auto controller = sessionController(); diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index baab0669a..ec480fa4e 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -51,7 +51,7 @@ private: struct Private; void setupNativeWindowFrame(); - void updateIconCounters(); + void updateTaskbarAndIconCounters(); void validateWindowTheme(bool native, bool night); void forceIconRefresh(); diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp index d0dbbaa09..5a0896923 100644 --- a/Telegram/SourceFiles/settings/settings_experimental.cpp +++ b/Telegram/SourceFiles/settings/settings_experimental.cpp @@ -139,7 +139,6 @@ void SetupExperimental( addToggle(ChatHelpers::kOptionTabbedPanelShowOnClick); addToggle(Window::kOptionViewProfileInChatsListContextMenu); addToggle(Dialogs::kOptionCtrlClickChatNewWindow); - addToggle(Window::kOptionShowChatNameInNewWindow); addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL); addToggle(Ui::kOptionUseSmallMsgBubbleRadius); addToggle(Media::Player::kOptionDisableAutoplayNext); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index b2b19fad1..d8b9fe617 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/sandbox.h" #include "lang/lang_keys.h" #include "data/data_session.h" +#include "data/data_forum_topic.h" #include "main/main_session.h" #include "main/main_session_settings.h" #include "base/options.h" @@ -49,16 +50,8 @@ namespace { constexpr auto kSaveWindowPositionTimeout = crl::time(1000); -base::options::toggle ShowChatNameInNewWindow({ - .id = kOptionShowChatNameInNewWindow, - .name = "Chat name in window title", - .description = "Show chat name in the additional windows titles.", -}); - } // namespace -const char kOptionShowChatNameInNewWindow[] = "show-chat-name-in-new-window"; - const QImage &Logo() { static const auto result = QImage(u":/gui/art/logo_256.png"_q); return result; @@ -329,7 +322,9 @@ MainWindow::MainWindow(not_null controller) Core::App().unreadBadgeChanges( ) | rpl::start_with_next([=] { - updateUnreadCounter(); + updateTitle(); + unreadCounterChangedHook(); + Core::App().tray().updateIconCounters(); }, lifetime()); Core::App().settings().workModeChanges( @@ -421,18 +416,6 @@ bool MainWindow::computeIsActive() const { return isActiveWindow() && isVisible() && !(windowState() & Qt::WindowMinimized); } -void MainWindow::updateWindowIcon() { - const auto session = sessionController() - ? &sessionController()->session() - : nullptr; - const auto supportIcon = session && session->supportMode(); - if (supportIcon != _usingSupportIcon || _icon.isNull()) { - _icon = CreateIcon(session); - _usingSupportIcon = supportIcon; - } - setWindowIcon(_icon); -} - QRect MainWindow::desktopRect() const { const auto now = crl::now(); if (!_monitorLastGot || now >= _monitorLastGot + crl::time(1000)) { @@ -446,7 +429,6 @@ void MainWindow::init() { createWinId(); initHook(); - updateWindowIcon(); // Non-queued activeChanged handlers must use QtSignalProducer. connect( @@ -478,7 +460,8 @@ void MainWindow::init() { refreshTitleWidget(); initGeometry(); - updateUnreadCounter(); + updateTitle(); + updateWindowIcon(); } void MainWindow::handleStateChanged(Qt::WindowState state) { @@ -522,7 +505,8 @@ void MainWindow::showFromTray() { updateGlobalMenu(); }); activate(); - updateUnreadCounter(); + unreadCounterChangedHook(); + Core::App().tray().updateIconCounters(); } void MainWindow::quitFromTray() { @@ -801,30 +785,34 @@ void MainWindow::updateControlsGeometry() { _body->setGeometry(bodyLeft, bodyTop, bodyWidth, inner.height() - (bodyTop - inner.y())); } -void MainWindow::updateUnreadCounter() { +void MainWindow::updateTitle() { if (Core::Quitting()) { return; } - if (ShowChatNameInNewWindow.value() && singlePeer()) { - const auto peer = singlePeer(); - const auto history = peer->owner().history(peer); - const auto name = peer->isSelf() - ? tr::lng_saved_messages(tr::now) - : peer->name(); - const auto counter = history->unreadCount(); - setTitle((counter > 0) - ? u"(%1) %2 \u2013 Telegram"_q.arg(QString::number(counter), name) - : u"%1 \u2013 Telegram"_q.arg(name)); - } else { - const auto counter = Core::App().unreadBadge(); - setTitle((counter > 0) - ? u"Telegram (%1)"_q.arg(counter) - : u"Telegram"_q); + const auto counter = Core::App().unreadBadge(); + const auto basic = (counter > 0) + ? u"Telegram (%1)"_q.arg(counter) + : u"Telegram"_q; + const auto session = _controller->sessionController(); + const auto key = session ? session->activeChatCurrent() : Dialogs::Key(); + const auto thread = key ? key.thread() : nullptr; + if (!thread) { + setTitle(basic); + return; } - - Core::App().tray().updateIconCounters(); - unreadCounterChangedHook(); + const auto history = thread->owningHistory(); + const auto topic = thread->asTopic(); + const auto name = topic + ? topic->title() + : history->peer->isSelf() + ? tr::lng_saved_messages(tr::now) + : history->peer->name(); + const auto threadCounter = thread->chatListBadgesState().unreadCounter; + const auto primary = (threadCounter > 0) + ? u"(%1) %2"_q.arg(threadCounter).arg(name) + : name; + setTitle(primary + u" \u2013 "_q + basic); } QRect MainWindow::computeDesktopRect() const { diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index e1a268362..882b828ab 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -55,8 +55,6 @@ struct CounterLayerArgs { [[nodiscard]] QImage GenerateCounterLayer(CounterLayerArgs &&args); [[nodiscard]] QImage WithSmallCounter(QImage image, CounterLayerArgs &&args); -extern const char kOptionShowChatNameInNewWindow[]; - class MainWindow : public Ui::RpWindow { public: explicit MainWindow(not_null controller); @@ -121,7 +119,8 @@ public: rpl::producer<> leaveEvents() const; - virtual void updateWindowIcon(); + virtual void updateWindowIcon() = 0; + void updateTitle(); void clearWidgets(); @@ -184,7 +183,6 @@ protected: virtual int32 screenNameChecksum(const QString &name) const; void setPositionInited(); - void updateUnreadCounter(); virtual QRect computeDesktopRect() const; @@ -209,9 +207,6 @@ private: object_ptr _body; object_ptr _rightColumn = { nullptr }; - QIcon _icon; - bool _usingSupportIcon = false; - bool _isActive = false; rpl::event_stream<> _leaveEvents; diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index 1557f8a3d..3d4fa8fa4 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -62,6 +62,9 @@ Controller::~Controller() { // We want to delete all widgets before the _sessionController. _widget.ui_hideSettingsAndLayer(anim::type::instant); _widget.clearWidgets(); + _accountLifetime.destroy(); + _sessionControllerValue = nullptr; + _sessionController = nullptr; } void Controller::showAccount(not_null account) { @@ -103,6 +106,8 @@ void Controller::showAccount( _sessionController = session ? std::make_unique(session, this) : nullptr; + _sessionControllerValue = _sessionController.get(); + auto oldContentCache = _widget.grabForSlideAnimation(); _widget.updateWindowIcon(); if (session) { @@ -124,6 +129,14 @@ void Controller::showAccount( widget()->setInnerFocus(); + _sessionController->activeChatChanges( + ) | rpl::start_with_next([=] { + _widget.updateTitle(); + }, _sessionController->lifetime()); + if (_sessionController->activeChatCurrent().thread()) { + _widget.updateTitle(); + } + session->updates().updateOnline(crl::now()); } else { sideBarChanged(); @@ -254,6 +267,16 @@ Main::Session *Controller::maybeSession() const { return _account ? _account->maybeSession() : nullptr; } +auto Controller::sessionControllerValue() const +-> rpl::producer { + return _sessionControllerValue.value(); +} + +auto Controller::sessionControllerChanges() const +-> rpl::producer { + return _sessionControllerValue.changes(); +} + bool Controller::locked() const { if (Core::App().passcodeLocked()) { return true; diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index 076442b49..3fe280c9c 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -54,6 +54,10 @@ public: [[nodiscard]] SessionController *sessionController() const { return _sessionController.get(); } + [[nodiscard]] auto sessionControllerValue() const + -> rpl::producer; + [[nodiscard]] auto sessionControllerChanges() const + -> rpl::producer; [[nodiscard]] bool locked() const; [[nodiscard]] Adaptive &adaptive() const; @@ -144,6 +148,7 @@ private: ::MainWindow _widget; const std::unique_ptr _adaptive; std::unique_ptr _sessionController; + rpl::variable _sessionControllerValue; QPointer _termsBox; rpl::event_stream _openInMediaViewRequests; diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 33a4575da..08f7feb2a 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -943,25 +943,22 @@ void MainMenu::initResetScaleButton() { } OthersUnreadState OtherAccountsUnreadStateCurrent() { - auto &app = Core::App(); - const auto active = &app.activeAccount(); + auto &domain = Core::App().domain(); + const auto active = &domain.active(); + auto counter = 0; auto allMuted = true; - for (const auto &[index, account] : app.domain().accounts()) { + for (const auto &[index, account] : domain.accounts()) { if (account.get() == active) { continue; } else if (const auto session = account->maybeSession()) { + counter += session->data().unreadBadge(); if (!session->data().unreadBadgeMuted()) { allMuted = false; - break; } } } - // In case we are logging out in the last paint for the slide animation - // the account doesn't have the session here already. - const auto current = active->maybeSession(); return { - .count = (app.unreadBadge() - - (current ? current->data().unreadBadge() : 0)), + .count = counter, .allMuted = allMuted, }; }