diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b93f43b9d0..8115f271a5 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -220,6 +220,11 @@ StackItemSection::StackItemSection( , _memento(std::move(memento)) { } +struct MainWidget::SettingBackground { + Data::WallPaper data; + base::binary_guard generating; +}; + MainWidget::MainWidget( QWidget *parent, not_null controller) @@ -1414,11 +1419,12 @@ void MainWidget::updateScrollColors() { } void MainWidget::setChatBackground(const Data::WallPaper &background) { - _background = std::make_unique(background); - if (_background->document) { - _background->document->save(Data::FileOrigin(), QString()); - } else if (_background->thumb) { - _background->thumb->loadEvenCancelled(Data::FileOrigin()); + _background = std::make_unique(); + _background->data = background; + if (_background->data.document) { + _background->data.document->save(Data::FileOrigin(), QString()); + } else if (_background->data.thumb) { + _background->data.thumb->loadEvenCancelled(Data::FileOrigin()); } checkChatBackground(); @@ -1433,71 +1439,91 @@ bool MainWidget::chatBackgroundLoading() { float64 MainWidget::chatBackgroundProgress() const { if (_background) { - if (_background->document) { - return _background->document->progress(); - } else if (_background->thumb) { - return _background->thumb->progress(); + if (_background->generating.alive()) { + return 1.; + } else if (_background->data.document) { + return _background->data.document->progress(); + } else if (_background->data.thumb) { + return _background->data.thumb->progress(); } } return 1.; } void MainWidget::checkChatBackground() { - using namespace Window::Theme; - - if (!_background) { + if (!_background || _background->generating.alive()) { return; } - const auto document = _background->document; + const auto document = _background->data.document; if (document && !document->loaded()) { return; - } else if (!document && !_background->thumb->loaded()) { + } else if (!document && !_background->data.thumb->loaded()) { return; } - auto image = [&] { - if (!document) { - const auto &thumb = _background->thumb; - return thumb - ? thumb->pixNoCache(Data::FileOrigin()).toImage() - : QImage(); - } - auto bytes = document->data(); + if (!document) { + const auto &thumb = _background->data.thumb; + setGeneratedBackground(thumb + ? thumb->pixNoCache(Data::FileOrigin()).toImage() + : QImage()); + return; + } + auto [left, right] = base::make_binary_guard(); + _background->generating = std::move(left); + crl::async([ + this, + bytes = document->data(), + path = document->filepath(), + guard = std::move(right) + ]() mutable { auto format = QByteArray(); - const auto path = document->filepath(); if (bytes.isEmpty()) { - QFile f(document->filepath()); + QFile f(path); if (f.size() <= App::kImageSizeLimit && f.open(QIODevice::ReadOnly)) { bytes = f.readAll(); } } - return bytes.isEmpty() + auto image = bytes.isEmpty() ? QImage() : App::readImage(bytes, &format, false, nullptr); - }(); + crl::on_main([ + this, + guard = std::move(guard), + image = std::move(image) + ]() mutable { + if (!guard.alive()) { + return; + } + setGeneratedBackground(std::move(image)); + }); + }); +} + +ImagePtr MainWidget::newBackgroundThumb() { + return _background ? _background->data.thumb : ImagePtr(); +} + +void MainWidget::setGeneratedBackground(QImage &&image) { + using namespace Window::Theme; if (image.isNull()) { Background()->setImage(kDefaultBackground); } else if (false - || _background->id == kInitialBackground - || _background->id == kDefaultBackground) { - Background()->setImage(_background->id); + || _background->data.id == kInitialBackground + || _background->data.id == kDefaultBackground) { + Background()->setImage(_background->data.id); } else { Background()->setImage( - _background->id, + _background->data.id, std::move(image)); } - const auto tile = (_background->id == kInitialBackground); + const auto tile = (_background->data.id == kInitialBackground); Background()->setTile(tile); _background = nullptr; crl::on_main(this, [=] { update(); }); } -ImagePtr MainWidget::newBackgroundThumb() { - return _background ? _background->thumb : ImagePtr(); -} - void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) { _history->messageDataReceived(channel, msgId); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index a256046319..374b6c14da 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -454,6 +454,8 @@ private: void ensureFirstColumnResizeAreaCreated(); void ensureThirdColumnResizeAreaCreated(); + void setGeneratedBackground(QImage &&image); + not_null _controller; bool _started = false; @@ -543,7 +545,8 @@ private: QMap _viewsIncrementByRequest; SingleTimer _viewsIncrementTimer; - std::unique_ptr _background; + struct SettingBackground; + std::unique_ptr _background; bool _firstColumnResizing = false; int _firstColumnResizingShift = 0;