From 338129faea87754560b1a8c8cbd42ddd28f26595 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 26 Nov 2018 15:00:31 +0400 Subject: [PATCH] Destroy boxes in Ui::hideLayer(). --- .../SourceFiles/boxes/add_contact_box.cpp | 25 ++-- Telegram/SourceFiles/boxes/confirm_box.cpp | 64 ++++++---- .../boxes/peer_list_controllers.cpp | 120 +++++++++--------- .../boxes/peers/edit_peer_info_box.cpp | 32 +++-- .../chat_helpers/stickers_list_widget.cpp | 1 + .../dialogs_search_from_controllers.cpp | 8 +- .../SourceFiles/dialogs/dialogs_widget.cpp | 5 +- Telegram/SourceFiles/facades.cpp | 6 - Telegram/SourceFiles/facades.h | 1 - .../SourceFiles/info/info_wrap_widget.cpp | 3 +- Telegram/SourceFiles/mainwindow.cpp | 10 +- Telegram/SourceFiles/mainwindow.h | 2 +- .../platform/linux/file_utilities_linux.cpp | 3 +- Telegram/SourceFiles/window/layer_widget.cpp | 110 ++++++---------- Telegram/SourceFiles/window/layer_widget.h | 16 +-- 15 files changed, 202 insertions(+), 204 deletions(-) diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index dea8d4bfa..4511ff6c5 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -412,7 +412,10 @@ void GroupInfoBox::submitName() { } } -void GroupInfoBox::createGroup(not_null selectUsersBox, const QString &title, const std::vector> &users) { +void GroupInfoBox::createGroup( + not_null selectUsersBox, + const QString &title, + const std::vector> &users) { if (_creationRequestId) return; auto inputs = QVector(); @@ -427,7 +430,11 @@ void GroupInfoBox::createGroup(not_null selectUsersBox, const QStr if (inputs.empty()) { return; } - _creationRequestId = request(MTPmessages_CreateChat(MTP_vector(inputs), MTP_string(title))).done([this](const MTPUpdates &result) { + _creationRequestId = request(MTPmessages_CreateChat( + MTP_vector(inputs), + MTP_string(title) + )).done([=](const MTPUpdates &result) { + auto image = _photo->takeResultImage(); Ui::hideLayer(); App::main()->sentUpdatesReceived(result); @@ -440,28 +447,30 @@ void GroupInfoBox::createGroup(not_null selectUsersBox, const QStr case mtpc_updatesCombined: return &updates->c_updatesCombined().vchats.v; } - LOG(("API Error: unexpected update cons %1 (GroupInfoBox::creationDone)").arg(updates->type())); + LOG(("API Error: unexpected update cons %1 " + "(GroupInfoBox::creationDone)").arg(updates->type())); return std::nullopt; } | [](auto chats) { - return (!chats->empty() && chats->front().type() == mtpc_chat) + return (!chats->empty() + && chats->front().type() == mtpc_chat) ? base::make_optional(chats) : std::nullopt; } | [](auto chats) { return App::chat(chats->front().c_chat().vid.v); } - | [this](not_null chat) { - auto image = _photo->takeResultImage(); + | [&](not_null chat) { if (!image.isNull()) { Auth().api().uploadPeerPhoto(chat, std::move(image)); } Ui::showPeerHistory(chat, ShowAtUnreadMsgId); }; if (!success) { - LOG(("API Error: chat not found in updates (ContactsBox::creationDone)")); + LOG(("API Error: chat not found in updates " + "(ContactsBox::creationDone)")); } - }).fail([this, selectUsersBox](const RPCError &error) { + }).fail([=](const RPCError &error) { _creationRequestId = 0; if (error.type() == qstr("NO_CHAT_TITLE")) { auto weak = make_weak(this); diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index ff09fe94e..cf5f7988b 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -27,6 +27,37 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "auth_session.h" #include "observer_peer.h" +namespace { + +void ConvertToSupergroupDone(const MTPUpdates &updates) { + App::main()->sentUpdatesReceived(updates); + + auto handleChats = [](const MTPVector &chats) { + for (const auto &chat : chats.v) { + if (chat.type() == mtpc_channel) { + const auto channel = App::channel(chat.c_channel().vid.v); + Ui::showPeerHistory(channel, ShowAtUnreadMsgId); + Auth().api().requestParticipantsCountDelayed(channel); + } + } + }; + + switch (updates.type()) { + case mtpc_updates: + handleChats(updates.c_updates().vchats); + break; + case mtpc_updatesCombined: + handleChats(updates.c_updatesCombined().vchats); + break; + default: + LOG(("API Error: unexpected update cons %1 " + "(ConvertToSupergroupBox::convertDone)").arg(updates.type())); + break; + } +} + +} // namespace + TextParseOptions _confirmBoxTextOptions = { TextParseLinks | TextParseMultiline | TextParseRichText, // flags 0, // maxw @@ -138,8 +169,10 @@ void ConfirmBox::prepare() { } boxClosing() | rpl::start_with_next([=] { - if (!_confirmed && (!_strictCancel || _cancelled) && _cancelledCallback) { - _cancelledCallback(); + if (!_confirmed && (!_strictCancel || _cancelled)) { + if (auto callback = std::move(_cancelledCallback)) { + callback(); + } } }, lifetime()); @@ -167,8 +200,8 @@ void ConfirmBox::textUpdated() { void ConfirmBox::confirmed() { if (!_confirmed) { _confirmed = true; - if (_confirmedCallback) { - _confirmedCallback(); + if (auto callback = std::move(_confirmedCallback)) { + callback(); } } } @@ -188,11 +221,12 @@ void ConfirmBox::mousePressEvent(QMouseEvent *e) { void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) { _lastMousePos = e->globalPos(); updateHover(); - if (auto activated = ClickHandler::unpressed()) { + if (const auto activated = ClickHandler::unpressed()) { Ui::hideLayer(); App::activateClickHandler(activated, e->button()); + return; } - return BoxContent::mouseReleaseEvent(e); + BoxContent::mouseReleaseEvent(e); } void ConfirmBox::leaveEventHook(QEvent *e) { @@ -359,23 +393,7 @@ void ConvertToSupergroupBox::convertToSupergroup() { void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) { Ui::hideLayer(); - App::main()->sentUpdatesReceived(updates); - - auto handleChats = [](auto &mtpChats) { - for_const (auto &mtpChat, mtpChats.v) { - if (mtpChat.type() == mtpc_channel) { - const auto channel = App::channel(mtpChat.c_channel().vid.v); - Ui::showPeerHistory(channel, ShowAtUnreadMsgId); - Auth().api().requestParticipantsCountDelayed(channel); - } - } - }; - - switch (updates.type()) { - case mtpc_updates: handleChats(updates.c_updates().vchats); break; - case mtpc_updatesCombined: handleChats(updates.c_updatesCombined().vchats); break; - default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break; - } + ConvertToSupergroupDone(updates); } bool ConvertToSupergroupBox::convertFail(const RPCError &error) { diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index ecc73b303..b0ca9d87b 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -42,6 +42,61 @@ base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { return {}; } +void ShareBotGame(not_null bot, not_null chat) { + const auto history = App::historyLoaded(chat); + const auto randomId = rand_value(); + const auto requestId = MTP::send( + MTPmessages_SendMedia( + MTP_flags(0), + chat->input, + MTP_int(0), + MTP_inputMediaGame( + MTP_inputGameShortName( + bot->inputUser, + MTP_string(bot->botInfo->shareGameShortName))), + MTP_string(""), + MTP_long(randomId), + MTPnullMarkup, + MTPnullEntities), + App::main()->rpcDone(&MainWidget::sentUpdatesReceived), + App::main()->rpcFail(&MainWidget::sendMessageFail), + 0, + 0, + history ? history->sendRequestId : 0); + if (history) { + history->sendRequestId = requestId; + } + Ui::hideLayer(); + Ui::showPeerHistory(chat, ShowAtUnreadMsgId); +} + +void AddBotToGroup(not_null bot, not_null chat) { + if (auto &info = bot->botInfo) { + if (!info->startGroupToken.isEmpty()) { + MTP::send( + MTPmessages_StartBot( + bot->inputUser, + chat->input, + MTP_long(rand_value()), + MTP_string(info->startGroupToken)), + App::main()->rpcDone(&MainWidget::sentUpdatesReceived), + App::main()->rpcFail( + &MainWidget::addParticipantFail, + { bot, chat })); + } else { + App::main()->addParticipants( + chat, + { 1, bot }); + } + } else { + App::main()->addParticipants( + chat, + { 1, bot }); + } + Ui::hideLayer(); + Ui::showPeerHistory(chat, ShowAtUnreadMsgId); +} + } // namespace // Not used for now. @@ -751,36 +806,9 @@ void AddBotToGroupBoxController::rowClicked(not_null row) { } void AddBotToGroupBoxController::shareBotGame(not_null chat) { - auto send = [weak = base::make_weak(this), bot = _bot, chat] { - if (!weak) { - return; - } - const auto history = App::historyLoaded(chat); - const auto randomId = rand_value(); - const auto requestId = MTP::send( - MTPmessages_SendMedia( - MTP_flags(0), - chat->input, - MTP_int(0), - MTP_inputMediaGame( - MTP_inputGameShortName( - bot->inputUser, - MTP_string(bot->botInfo->shareGameShortName))), - MTP_string(""), - MTP_long(randomId), - MTPnullMarkup, - MTPnullEntities), - App::main()->rpcDone(&MainWidget::sentUpdatesReceived), - App::main()->rpcFail(&MainWidget::sendMessageFail), - 0, - 0, - history ? history->sendRequestId : 0); - if (history) { - history->sendRequestId = requestId; - } - Ui::hideLayer(); - Ui::showPeerHistory(chat, ShowAtUnreadMsgId); - }; + auto send = crl::guard(this, [bot = _bot, chat] { + ShareBotGame(bot, chat); + }); auto confirmText = [chat] { if (chat->isUser()) { return lng_bot_sure_share_game(lt_user, App::peerName(chat)); @@ -801,35 +829,9 @@ void AddBotToGroupBoxController::addBotToGroup(not_null chat) { return; } } - auto send = [weak = base::make_weak(this), bot = _bot, chat] { - if (!weak) { - return; - } - if (auto &info = bot->botInfo) { - if (!info->startGroupToken.isEmpty()) { - MTP::send( - MTPmessages_StartBot( - bot->inputUser, - chat->input, - MTP_long(rand_value()), - MTP_string(info->startGroupToken)), - App::main()->rpcDone(&MainWidget::sentUpdatesReceived), - App::main()->rpcFail( - &MainWidget::addParticipantFail, - { bot, chat })); - } else { - App::main()->addParticipants( - chat, - { 1, bot }); - } - } else { - App::main()->addParticipants( - chat, - { 1, bot }); - } - Ui::hideLayer(); - Ui::showPeerHistory(chat, ShowAtUnreadMsgId); - }; + auto send = crl::guard(this, [bot = _bot, chat] { + AddBotToGroup(bot, chat); + }); auto confirmText = lng_bot_sure_invite(lt_group, chat->name); Ui::show( Box(confirmText, send), diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index accf844fc..b2a853bf7 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -124,6 +124,7 @@ private: void submitTitle(); void submitDescription(); void deleteWithConfirmation(); + void deleteChannel(); void privacyChanged(Privacy value); void checkUsernameAvailability(); @@ -1404,23 +1405,15 @@ void Controller::savePhoto() { } void Controller::deleteWithConfirmation() { - auto channel = _peer->asChannel(); + const auto channel = _peer->asChannel(); Assert(channel != nullptr); auto text = lang(_isGroup ? lng_sure_delete_group : lng_sure_delete_channel); - auto deleteCallback = [=] { - Ui::hideLayer(); - Ui::showChatsList(); - if (auto chat = channel->migrateFrom()) { - App::main()->deleteAndExit(chat); - } - MTP::send( - MTPchannels_DeleteChannel(channel->inputChannel), - App::main()->rpcDone(&MainWidget::sentUpdatesReceived), - App::main()->rpcFail(&MainWidget::deleteChannelFailed)); - }; + auto deleteCallback = crl::guard(this, [=] { + deleteChannel(); + }); Ui::show(Box( text, lang(lng_box_delete), @@ -1428,6 +1421,21 @@ void Controller::deleteWithConfirmation() { std::move(deleteCallback)), LayerOption::KeepOther); } +void Controller::deleteChannel() { + const auto channel = _peer->asChannel(); + const auto chat = channel->migrateFrom(); + + Ui::hideLayer(); + Ui::showChatsList(); + if (chat) { + App::main()->deleteAndExit(chat); + } + MTP::send( + MTPchannels_DeleteChannel(channel->inputChannel), + App::main()->rpcDone(&MainWidget::sentUpdatesReceived), + App::main()->rpcFail(&MainWidget::deleteChannelFailed)); +} + } // namespace EditPeerInfoBox::EditPeerInfoBox( diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 890d7aba4..fc0f1c8ad 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -2361,6 +2361,7 @@ void StickersListWidget::removeMegagroupSet(bool locally) { _removingSetId = Stickers::MegagroupSetId; Ui::show(Box(lang(lng_stickers_remove_group_set), crl::guard(this, [this, group = _megagroupSet] { Expects(group->mgInfo != nullptr); + if (group->mgInfo->stickerSet.type() != mtpc_inputStickerSetEmpty) { Auth().api().setGroupStickerSet(group, MTP_inputStickerSetEmpty()); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp b/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp index fca5ef235..3ea660de9 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp @@ -76,7 +76,9 @@ void ChatSearchFromController::prepare() { void ChatSearchFromController::rowClicked(not_null row) { Expects(row->peer()->isUser()); - _callback(row->peer()->asUser()); + + const auto onstack = _callback; + onstack(row->peer()->asUser()); } void ChatSearchFromController::rebuildRows() { @@ -143,7 +145,9 @@ void ChannelSearchFromController::prepare() { void ChannelSearchFromController::rowClicked(not_null row) { Expects(row->peer()->isUser()); - _callback(row->peer()->asUser()); + + const auto onstack = _callback; + onstack(row->peer()->asUser()); } std::unique_ptr ChannelSearchFromController::createRow(not_null user) const { diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 562c2d5c9..9c9aa0bc7 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -1199,13 +1199,12 @@ void DialogsWidget::showSearchFrom() { Dialogs::ShowSearchFromBox( controller(), peer, - crl::guard(this, [=]( - not_null user) { + crl::guard(this, [=](not_null user) { Ui::hideLayer(); setSearchInChat(chat, user); onFilterUpdate(true); }), - crl::guard(this, [this] { _filter->setFocus(); })); + crl::guard(this, [=] { _filter->setFocus(); })); } } diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index b3fc92c81..ee2ba88bf 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -217,12 +217,6 @@ void showMediaPreview(Data::FileOrigin origin, not_null photo) { } } -void hideMediaPreview() { - if (auto w = App::wnd()) { - w->ui_hideMediaPreview(); - } -} - void hideLayer(anim::type animated) { if (auto w = App::wnd()) { w->ui_showBox( diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index e1100fbcc..2396a4df8 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -102,7 +102,6 @@ void showMediaPreview( Data::FileOrigin origin, not_null document); void showMediaPreview(Data::FileOrigin origin, not_null photo); -void hideMediaPreview(); template QPointer show( diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index a87215a01..8c2ff17ec 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -403,9 +403,8 @@ void WrapWidget::createTopBar() { void WrapWidget::checkBeforeClose(Fn close) { const auto confirmed = [=] { - const auto copy = close; Ui::hideLayer(); - copy(); + close(); }; if (_controller->canSaveChangesNow()) { Ui::show(Box( diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 332d3da0d..3d241eab5 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -385,8 +385,10 @@ void MainWindow::ui_showMediaPreview( _mediaPreview->showPreview(origin, photo); } -void MainWindow::ui_hideMediaPreview() { - if (!_mediaPreview) return; +void MainWindow::hideMediaPreview() { + if (!_mediaPreview) { + return; + } _mediaPreview->hidePreview(); } @@ -484,12 +486,12 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) { } break; case QEvent::MouseButtonRelease: { - Ui::hideMediaPreview(); + hideMediaPreview(); } break; case QEvent::ApplicationActivate: { if (object == QCoreApplication::instance()) { - InvokeQueued(this, [this] { + InvokeQueued(this, [=] { handleActiveChanged(); }); } diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 9494d745e..6a53d208a 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -116,7 +116,6 @@ public: void ui_showMediaPreview( Data::FileOrigin origin, not_null photo); - void ui_hideMediaPreview(); protected: bool eventFilter(QObject *o, QEvent *e) override; @@ -152,6 +151,7 @@ signals: private: [[nodiscard]] bool skipTrayClick() const; + void hideMediaPreview(); void ensureLayerCreated(); void destroyLayer(); diff --git a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp index 26ffcb7fb..6aabb4c59 100644 --- a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp @@ -49,7 +49,8 @@ QByteArray EscapeShell(const QByteArray &content) { } // namespace internal void UnsafeShowInFolder(const QString &filepath) { - Ui::hideLayer(anim::type::instant); // Hide mediaview to make other apps visible. + // Hide mediaview to make other apps visible. + Ui::hideLayer(anim::type::instant); auto absolutePath = QFileInfo(filepath).absoluteFilePath(); QProcess process; diff --git a/Telegram/SourceFiles/window/layer_widget.cpp b/Telegram/SourceFiles/window/layer_widget.cpp index 06481ae98..43a5add9a 100644 --- a/Telegram/SourceFiles/window/layer_widget.cpp +++ b/Telegram/SourceFiles/window/layer_widget.cpp @@ -457,21 +457,28 @@ void LayerStackWidget::setCacheImages() { _background->setCacheImages(std::move(bodyCache), std::move(mainMenuCache), std::move(specialLayerCache), std::move(layerCache)); } -void LayerStackWidget::onLayerClosed(LayerWidget *layer) { - if (!layer->setClosing()) { +void LayerStackWidget::closeLayer(not_null layer) { + const auto weak = make_weak(layer.get()); + if (weak->inFocusChain()) { + setFocus(); + } + if (!weak || !weak->setClosing()) { // This layer is already closing. return; + } else if (!weak) { + // setClosing() could've killed the layer. + return; } - layer->deleteLater(); + if (layer == _specialLayer) { hideAll(anim::type::normal); } else if (layer == currentLayer()) { if (_layers.size() == 1) { hideCurrent(anim::type::normal); } else { - if (layer->inFocusChain()) setFocus(); - layer->hide(); + auto taken = std::move(_layers.back()); _layers.pop_back(); + layer = currentLayer(); layer->parentResized(); if (!_background->animating()) { @@ -481,7 +488,7 @@ void LayerStackWidget::onLayerClosed(LayerWidget *layer) { } } else { for (auto i = _layers.begin(), e = _layers.end(); i != e; ++i) { - if (layer == *i) { + if (layer == i->get()) { _layers.erase(i); break; } @@ -489,10 +496,6 @@ void LayerStackWidget::onLayerClosed(LayerWidget *layer) { } } -void LayerStackWidget::onLayerResized() { - updateLayerBoxes(); -} - void LayerStackWidget::updateLayerBoxes() { auto getLayerBox = [this]() { if (auto layer = currentLayer()) { @@ -594,15 +597,15 @@ void LayerStackWidget::showBox( void LayerStackWidget::replaceBox( object_ptr box, anim::type animated) { - auto pointer = pushBox(std::move(box), animated); - while (!_layers.isEmpty() && _layers.front() != pointer) { - auto removingLayer = _layers.front(); - _layers.pop_front(); + const auto pointer = pushBox(std::move(box), animated); + while (!_layers.empty() && _layers.front().get() != pointer) { + auto removingLayer = std::move(_layers.front()); + _layers.erase(begin(_layers)); + if (removingLayer->inFocusChain()) { + setFocus(); + } removingLayer->setClosing(); - if (removingLayer->inFocusChain()) setFocus(); - removingLayer->hide(); - removingLayer->deleteLater(); } } @@ -616,7 +619,7 @@ void LayerStackWidget::prepareForAnimation() { if (_specialLayer) { _specialLayer->hide(); } - if (auto layer = currentLayer()) { + if (const auto layer = currentLayer()) { layer->hide(); } } @@ -717,15 +720,13 @@ LayerWidget *LayerStackWidget::pushBox( if (oldLayer->inFocusChain()) setFocus(); oldLayer->hide(); } - auto layer = object_ptr( - this, - std::move(box)); - _layers.push_back(layer); - initChildLayer(layer); + _layers.push_back(std::make_unique(this, std::move(box))); + const auto raw = _layers.back().get(); + initChildLayer(raw); if (_layers.size() > 1) { if (!_background->animating()) { - layer->setVisible(true); + raw->setVisible(true); showFinished(); } } else { @@ -734,7 +735,7 @@ LayerWidget *LayerStackWidget::pushBox( }, Action::ShowLayer, animated); } - return layer.data(); + return raw; } void LayerStackWidget::prependBox( @@ -744,10 +745,12 @@ void LayerStackWidget::prependBox( replaceBox(std::move(box), animated); return; } - auto layer = object_ptr(this, std::move(box)); - layer->hide(); - _layers.push_front(layer); - initChildLayer(layer); + _layers.insert( + begin(_layers), + std::make_unique(this, std::move(box))); + const auto raw = _layers.front().get(); + raw->hide(); + initChildLayer(raw); } bool LayerStackWidget::takeToThirdSection() { @@ -757,11 +760,11 @@ bool LayerStackWidget::takeToThirdSection() { } void LayerStackWidget::clearLayers() { - for (auto layer : base::take(_layers)) { + for (auto &layer : base::take(_layers)) { + if (layer->inFocusChain()) { + setFocus(); + } layer->setClosing(); - if (layer->inFocusChain()) setFocus(); - layer->hide(); - layer->deleteLater(); } } @@ -774,9 +777,8 @@ void LayerStackWidget::clearSpecialLayer() { void LayerStackWidget::initChildLayer(LayerWidget *layer) { layer->setParent(this); - layer->setClosedCallback([this, layer] { onLayerClosed(layer); }); - layer->setResizedCallback([this] { onLayerResized(); }); - connect(layer, SIGNAL(destroyed(QObject*)), this, SLOT(onLayerDestroyed(QObject*))); + layer->setClosedCallback([=] { closeLayer(layer); }); + layer->setResizedCallback([=] { updateLayerBoxes(); }); Ui::SendPendingMoveResizeEvents(layer); layer->parentResized(); } @@ -797,41 +799,7 @@ void LayerStackWidget::sendFakeMouseEvent() { sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton); } -void LayerStackWidget::onLayerDestroyed(QObject *obj) { - if (obj == _specialLayer) { - _specialLayer = nullptr; - hideAll(anim::type::normal); - } else if (obj == currentLayer()) { - _layers.pop_back(); - if (auto newLayer = currentLayer()) { - newLayer->parentResized(); - if (!_background->animating()) { - newLayer->show(); - showFinished(); - } - } else if (!_specialLayer) { - hideAll(anim::type::normal); - } - } else { - for (auto i = _layers.begin(), e = _layers.end(); i != e; ++i) { - if (obj == *i) { - _layers.erase(i); - break; - } - } - } -} - -LayerStackWidget::~LayerStackWidget() { - // We must destroy all layers before we destroy LayerStackWidget. - // Some layers in destructor call layer-related methods, like hiding - // other layers, that call methods of LayerStackWidget and access - // its fields, so if it is destroyed already everything crashes. - for (auto layer : base::take(_layers)) { - layer->hide(); - delete layer; - } -} +LayerStackWidget::~LayerStackWidget() = default; } // namespace Window diff --git a/Telegram/SourceFiles/window/layer_widget.h b/Telegram/SourceFiles/window/layer_widget.h index 8a6cd7769..d75c68661 100644 --- a/Telegram/SourceFiles/window/layer_widget.h +++ b/Telegram/SourceFiles/window/layer_widget.h @@ -55,8 +55,8 @@ public: protected: void closeLayer() { - if (_closedCallback) { - _closedCallback(); + if (const auto callback = base::take(_closedCallback)) { + callback(); } } void mousePressEvent(QMouseEvent *e) override { @@ -81,8 +81,6 @@ private: }; class LayerStackWidget : public Ui::RpWidget { - Q_OBJECT - public: LayerStackWidget(QWidget *parent); @@ -126,11 +124,6 @@ protected: void mousePressEvent(QMouseEvent *e) override; void resizeEvent(QResizeEvent *e) override; -private slots: - void onLayerDestroyed(QObject *obj); - void onLayerClosed(LayerWidget *layer); - void onLayerResized(); - private: void appendBox( object_ptr box, @@ -147,6 +140,7 @@ private: anim::type animated); void showFinished(); void hideCurrent(anim::type animated); + void closeLayer(not_null layer); enum class Action { ShowMainMenu, @@ -175,13 +169,13 @@ private: void sendFakeMouseEvent(); LayerWidget *currentLayer() { - return _layers.empty() ? nullptr : _layers.back(); + return _layers.empty() ? nullptr : _layers.back().get(); } const LayerWidget *currentLayer() const { return const_cast(this)->currentLayer(); } - QList _layers; + std::vector> _layers; object_ptr _specialLayer = { nullptr }; object_ptr _mainMenu = { nullptr };