mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-06 11:52:58 +00:00
Close editors on session destructions.
This commit is contained in:
@@ -46,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "iv/iv_delegate_impl.h"
|
||||
#include "iv/iv_instance.h"
|
||||
#include "iv/iv_data.h"
|
||||
#include "iv/editor/iv_editor_session.h"
|
||||
#include "lang/lang_translator.h"
|
||||
#include "lang/lang_cloud_manager.h"
|
||||
#include "lang/lang_hardcoded.h"
|
||||
@@ -214,6 +215,7 @@ void Application::closeAdditionalWindows() {
|
||||
}
|
||||
}
|
||||
_iv->closeAll();
|
||||
Iv::Editor::CloseAllWindows();
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
|
||||
@@ -983,6 +983,7 @@ private:
|
||||
|
||||
void showWindow() {
|
||||
_backgroundHold = shared_from_this();
|
||||
registerLiveAndTrackSession();
|
||||
auto descriptor = ShowWindowDescriptor{
|
||||
.session = _session,
|
||||
.peer = _peer,
|
||||
@@ -1039,6 +1040,63 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static void CloseAll() {
|
||||
auto live = std::vector<std::weak_ptr<ArticleSession>>();
|
||||
std::swap(live, Live());
|
||||
for (const auto &weak : live) {
|
||||
if (const auto strong = weak.lock()) {
|
||||
strong->forceClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Registry of all editor sessions that currently own a window, so that
|
||||
// they can be force-closed on session clear or application shutdown.
|
||||
[[nodiscard]] static std::vector<std::weak_ptr<ArticleSession>> &Live() {
|
||||
static auto result = std::vector<std::weak_ptr<ArticleSession>>();
|
||||
return result;
|
||||
}
|
||||
|
||||
void registerLiveAndTrackSession() {
|
||||
auto &live = Live();
|
||||
live.erase(
|
||||
std::remove_if(
|
||||
live.begin(),
|
||||
live.end(),
|
||||
[](const std::weak_ptr<ArticleSession> &weak) {
|
||||
return weak.expired();
|
||||
}),
|
||||
live.end());
|
||||
live.push_back(weak_from_this());
|
||||
|
||||
_session->data().sessionDataAboutToBeCleared(
|
||||
) | rpl::on_next([weak = weak_from_this()] {
|
||||
// Holds a strong reference for the duration of the call, so that
|
||||
// dropping the self-hold inside forceClose() doesn't run
|
||||
// ~ArticleSession re-entrantly while this handler is on the stack.
|
||||
if (const auto strong = weak.lock()) {
|
||||
strong->forceClose();
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
// Destroys the editor window synchronously and releases the self-hold.
|
||||
// The caller must hold a strong reference (see CloseAll() and the session
|
||||
// clear handler) so that the eventual ~ArticleSession runs after this
|
||||
// returns rather than re-entrantly.
|
||||
void forceClose() {
|
||||
if (!_windowHost && !_backgroundHold) {
|
||||
return;
|
||||
}
|
||||
_editor = nullptr;
|
||||
_submitButton = nullptr;
|
||||
_windowHost = nullptr;
|
||||
_editorShow = nullptr;
|
||||
_backgroundHold = nullptr;
|
||||
}
|
||||
|
||||
void handleMediaDialogResult(
|
||||
QPointer<Widget> editor,
|
||||
FileDialog::OpenResult &&result) {
|
||||
@@ -1931,4 +1989,8 @@ void ShowEditBox(
|
||||
});
|
||||
}
|
||||
|
||||
void CloseAllWindows() {
|
||||
ArticleSession::CloseAll();
|
||||
}
|
||||
|
||||
} // namespace Iv::Editor
|
||||
|
||||
@@ -29,4 +29,10 @@ void ShowEditBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item);
|
||||
|
||||
// Synchronously destroys all open editor windows. Called on application
|
||||
// shutdown (before ~Sandbox) so that no editor top-level widget survives
|
||||
// to be destroyed from ~QApplication, where the lib_ui native event filter
|
||||
// would re-enter the already destroyed Sandbox machinery and crash.
|
||||
void CloseAllWindows();
|
||||
|
||||
} // namespace Iv::Editor
|
||||
|
||||
Reference in New Issue
Block a user