Fixed possible crash in OverlayWidget when video continues from PiP.

This commit is contained in:
23rd 2021-06-24 12:04:21 +03:00 committed by John Preston
parent 6b62ec97c6
commit 7decf68122
5 changed files with 47 additions and 21 deletions

View file

@ -209,7 +209,7 @@ base::binary_guard ReadImageAsync(
} }
void ResolveDocument( void ResolveDocument(
not_null<Window::SessionController*> controller, Window::SessionController *controller,
not_null<DocumentData*> document, not_null<DocumentData*> document,
HistoryItem *item) { HistoryItem *item) {
if (!document->date) { if (!document->date) {
@ -222,7 +222,7 @@ void ResolveDocument(
&& document->isVideoFile() && document->isVideoFile()
&& !document->filepath().isEmpty()) { && !document->filepath().isEmpty()) {
File::Launch(document->location(false).fname); File::Launch(document->location(false).fname);
} else { } else if (controller) {
controller->openDocument(document, msgId, true); controller->openDocument(document, msgId, true);
} }
}; };

View file

@ -30,7 +30,7 @@ base::binary_guard ReadImageAsync(
FnMut<void(QImage&&)> done); FnMut<void(QImage&&)> done);
void ResolveDocument( void ResolveDocument(
not_null<Window::SessionController*> controller, Window::SessionController *controller,
not_null<DocumentData*> document, not_null<DocumentData*> document,
HistoryItem *item); HistoryItem *item);

View file

@ -1427,12 +1427,15 @@ void OverlayWidget::subscribeToScreenGeometry() {
} }
void OverlayWidget::toMessage() { void OverlayWidget::toMessage() {
if (!_session || !_controller) { if (!_session) {
return; return;
} }
if (const auto item = _session->data().message(_msgid)) { if (const auto item = _session->data().message(_msgid)) {
close(); close();
_controller->showPeerHistoryAtItem(item); if (const auto window = findWindow()) {
window->showPeerHistoryAtItem(item);
}
} }
} }
@ -1556,11 +1559,8 @@ void OverlayWidget::handleDocumentClick() {
if (_document->loading()) { if (_document->loading()) {
saveCancel(); saveCancel();
} else { } else {
if (!_controller) {
return;
}
Data::ResolveDocument( Data::ResolveDocument(
_controller, findWindow(),
_document, _document,
_document->owner().message(_msgid)); _document->owner().message(_msgid));
if (_document->loading() && !_radial.animating()) { if (_document->loading() && !_radial.animating()) {
@ -2251,10 +2251,6 @@ void OverlayWidget::activate() {
} }
void OverlayWidget::show(OpenRequest request) { void OverlayWidget::show(OpenRequest request) {
if (!request.controller()) {
return;
}
const auto document = request.document(); const auto document = request.document();
const auto photo = request.photo(); const auto photo = request.photo();
const auto contextItem = request.item(); const auto contextItem = request.item();
@ -2264,8 +2260,6 @@ void OverlayWidget::show(OpenRequest request) {
return; return;
} }
setSession(&photo->session()); setSession(&photo->session());
_controller = request.controller();
Assert(_session == (&_controller->session()));
if (contextPeer) { if (contextPeer) {
setContext(contextPeer); setContext(contextPeer);
@ -2284,8 +2278,6 @@ void OverlayWidget::show(OpenRequest request) {
activateControls(); activateControls();
} else if (document) { } else if (document) {
setSession(&document->session()); setSession(&document->session());
_controller = request.controller();
Assert(_session == (&_controller->session()));
if (contextItem) { if (contextItem) {
setContext(contextItem); setContext(contextItem);
@ -2308,6 +2300,9 @@ void OverlayWidget::show(OpenRequest request) {
activateControls(); activateControls();
} }
} }
if (const auto controller = request.controller()) {
_window = base::make_weak(&controller->window());
}
} }
void OverlayWidget::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item) { void OverlayWidget::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item) {
@ -3097,14 +3092,13 @@ float64 OverlayWidget::playbackControlsCurrentSpeed() {
void OverlayWidget::switchToPip() { void OverlayWidget::switchToPip() {
Expects(_streamed != nullptr); Expects(_streamed != nullptr);
Expects(_document != nullptr); Expects(_document != nullptr);
Expects(_controller != nullptr);
const auto document = _document; const auto document = _document;
const auto msgId = _msgid; const auto msgId = _msgid;
const auto closeAndContinue = [=] { const auto closeAndContinue = [=] {
_showAsPip = false; _showAsPip = false;
show(OpenRequest( show(OpenRequest(
_controller, findWindow(),
document, document,
document->owner().message(msgId), document->owner().message(msgId),
true)); true));
@ -4538,6 +4532,36 @@ void OverlayWidget::applyHideWindowWorkaround() {
} }
} }
Window::SessionController *OverlayWidget::findWindow() const {
if (!_session) {
return nullptr;
}
const auto window = _window.get();
if (window) {
if (const auto controller = window->sessionController()) {
if (&controller->session() == _session) {
return controller;
}
}
}
const auto &active = _session->windows();
if (!active.empty()) {
return active.front();
} else if (window) {
Window::SessionController *controllerPtr = nullptr;
window->invokeForSessionController(
&_session->account(),
[&](not_null<Window::SessionController*> newController) {
controllerPtr = newController;
});
return controllerPtr;
}
return nullptr;
}
// #TODO unite and check // #TODO unite and check
void OverlayWidget::clearBeforeHide() { void OverlayWidget::clearBeforeHide() {
_sharedMedia = nullptr; _sharedMedia = nullptr;

View file

@ -411,11 +411,13 @@ private:
void applyHideWindowWorkaround(); void applyHideWindowWorkaround();
Window::SessionController *findWindow() const;
bool _opengl = false; bool _opengl = false;
const std::unique_ptr<Ui::RpWidgetWrap> _surface; const std::unique_ptr<Ui::RpWidgetWrap> _surface;
const not_null<QWidget*> _widget; const not_null<QWidget*> _widget;
Window::SessionController *_controller = nullptr; base::weak_ptr<Window::Controller> _window;
Main::Session *_session = nullptr; Main::Session *_session = nullptr;
rpl::lifetime _sessionLifetime; rpl::lifetime _sessionLifetime;
PhotoData *_photo = nullptr; PhotoData *_photo = nullptr;

View file

@ -21,7 +21,7 @@ struct OpenRequest;
namespace Window { namespace Window {
class Controller final { class Controller final : public base::has_weak_ptr {
public: public:
Controller(); Controller();
~Controller(); ~Controller();