From c737e2f91bcc8f9c8c320e01bd3ae15f45ac282a Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 3 Feb 2023 20:48:12 +0400 Subject: [PATCH] Track window activation history. --- Telegram/SourceFiles/core/application.cpp | 54 ++++++++++++++++++----- Telegram/SourceFiles/core/application.h | 1 + Telegram/SourceFiles/mainwidget.cpp | 2 + 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index f771af00f..5a33ab1d0 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -191,6 +191,7 @@ Application::~Application() { Local::writeSettings(); } + _windowStack.clear(); setLastActiveWindow(nullptr); _windowInSettings = _lastActivePrimaryWindow = nullptr; _closingAsyncWindows.clear(); @@ -514,18 +515,26 @@ void Application::startTray() { } void Application::activate() { - const auto last = _lastActiveWindow; - const auto primary = _lastActivePrimaryWindow; - enumerateWindows([&](not_null w) { - if (w != last && w != primary) { - w->widget()->showFromTray(); + for (const auto &window : _windowStack) { + if (window == _lastActiveWindow) { + break; + } + const auto widget = window->widget(); + const auto wasHidden = !widget->isVisible(); + const auto state = widget->windowState(); + if (state & Qt::WindowMinimized) { + widget->setWindowState(state & ~Qt::WindowMinimized); + } + widget->setVisible(true); + widget->activateWindow(); + if (wasHidden) { + if (const auto session = window->sessionController()) { + session->content()->windowShown(); + } } - }); - if (primary) { - primary->widget()->showFromTray(); } - if (last && last != primary) { - last->widget()->showFromTray(); + if (_lastActiveWindow) { + _lastActiveWindow->widget()->showFromTray(); } } @@ -1312,6 +1321,14 @@ void Application::setLastActiveWindow(Window::Controller *window) { } } _lastActiveWindow = window; + if (window) { + const auto i = ranges::find(_windowStack, not_null(window)); + if (i == end(_windowStack)) { + _windowStack.push_back(window); + } else if (i + 1 != end(_windowStack)) { + std::rotate(i, i + 1, end(_windowStack)); + } + } if (!window) { _floatPlayers = nullptr; return; @@ -1333,17 +1350,32 @@ void Application::setLastActiveWindow(Window::Controller *window) { } void Application::closeWindow(not_null window) { - const auto next = (_primaryWindows.front().second.get() != window) + const auto stackIt = ranges::find(_windowStack, window); + const auto nextFromStack = _windowStack.empty() + ? nullptr + : (stackIt == end(_windowStack) || stackIt + 1 != end(_windowStack)) + ? _windowStack.back().get() + : (_windowStack.size() > 1) + ? (stackIt - 1)->get() + : nullptr; + const auto next = nextFromStack + ? nextFromStack + : (_primaryWindows.front().second.get() != window) ? _primaryWindows.front().second.get() : (_primaryWindows.back().second.get() != window) ? _primaryWindows.back().second.get() : nullptr; + Assert(next != window); + if (_lastActivePrimaryWindow == window) { _lastActivePrimaryWindow = next; } if (_windowInSettings == window) { _windowInSettings = next; } + if (stackIt != end(_windowStack)) { + _windowStack.erase(stackIt); + } if (_lastActiveWindow == window) { setLastActiveWindow(next); if (_lastActiveWindow) { diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index 462e4370b..8671b89d7 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -397,6 +397,7 @@ private: base::flat_map< not_null, std::unique_ptr> _secondaryWindows; + std::vector> _windowStack; Window::Controller *_lastActiveWindow = nullptr; Window::Controller *_lastActivePrimaryWindow = nullptr; Window::Controller *_windowInSettings = nullptr; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index e6f4ba5c6..d787bc21f 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1287,6 +1287,8 @@ bool MainWidget::showHistoryInDifferentWindow( return true; } return false; + } else if (!peerId) { + return true; } else if (singlePeer()->id == peerId) { return false; }