Fix PiP window first show.

This commit is contained in:
John Preston 2021-05-20 09:53:09 +04:00
parent a45064257a
commit ccc599c83e
4 changed files with 114 additions and 126 deletions

View file

@ -53,6 +53,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/base_platform_info.h"
#include "base/openssl_help.h"
#include "base/unixtime.h"
#include "base/qt_signal_producer.h"
#include "main/main_account.h"
#include "main/main_domain.h" // Domain::activeSessionValue.
#include "main/main_session.h"
@ -352,8 +353,6 @@ OverlayWidget::OverlayWidget()
_saveMsgText.setMarkedText(st::mediaviewSaveMsgStyle, text, Ui::DialogTextOptions());
_saveMsg = QRect(0, 0, _saveMsgText.maxWidth() + st::mediaviewSaveMsgPadding.left() + st::mediaviewSaveMsgPadding.right(), st::mediaviewSaveMsgStyle.font->height + st::mediaviewSaveMsgPadding.top() + st::mediaviewSaveMsgPadding.bottom());
connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int)));
if (Platform::IsLinux()) {
setWindowFlags(Qt::FramelessWindowHint
| Qt::MaximizeUsingFullscreenGeometryHint);
@ -392,6 +391,7 @@ OverlayWidget::OverlayWidget()
&QWindow::screenChanged,
this,
[=](QScreen *screen) { handleScreenChanged(screen); });
subscribeToScreenGeometry();
#if defined Q_OS_MAC && !defined OS_OSX
TouchBar::SetupMediaViewTouchBar(
@ -420,16 +420,16 @@ OverlayWidget::OverlayWidget()
_saveMsgUpdater.setCallback([=] { updateImage(); });
setAttribute(Qt::WA_AcceptTouchEvents);
_touchTimer.setCallback([=] { onTouchTimer(); });
_touchTimer.setCallback([=] { handleTouchTimer(); });
_controlsHideTimer.setCallback([=] { onHideControls(); });
_controlsHideTimer.setCallback([=] { hideControls(); });
_docDownload->addClickHandler([=] { onDownload(); });
_docSaveAs->addClickHandler([=] { onSaveAs(); });
_docCancel->addClickHandler([=] { onSaveCancel(); });
_docDownload->addClickHandler([=] { downloadMedia(); });
_docSaveAs->addClickHandler([=] { saveAs(); });
_docCancel->addClickHandler([=] { saveCancel(); });
_dropdown->setHiddenCallback([this] { dropdownHidden(); });
_dropdownShowTimer.setCallback([=] { onDropdown(); });
_dropdownShowTimer.setCallback([=] { showDropdown(); });
}
void OverlayWidget::refreshLang() {
@ -698,10 +698,10 @@ void OverlayWidget::checkForSaveLoaded() {
return;
} else if (_savePhotoVideoWhenLoaded == SavePhotoVideo::QuickSave) {
_savePhotoVideoWhenLoaded = SavePhotoVideo::None;
onDownload();
downloadMedia();
} else if (_savePhotoVideoWhenLoaded == SavePhotoVideo::SaveAs) {
_savePhotoVideoWhenLoaded = SavePhotoVideo::None;
onSaveAs();
saveAs();
} else {
Unexpected("SavePhotoVideo in OverlayWidget::checkForSaveLoaded.");
}
@ -838,35 +838,28 @@ void OverlayWidget::refreshCaptionGeometry() {
void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) {
if (_document && _document->loading()) {
addAction(tr::lng_cancel(tr::now), [=] { onSaveCancel(); });
addAction(tr::lng_cancel(tr::now), [=] { saveCancel(); });
}
if (IsServerMsgId(_msgid.msg)) {
addAction(tr::lng_context_to_msg(tr::now), [=] { onToMessage(); });
addAction(tr::lng_context_to_msg(tr::now), [=] { toMessage(); });
}
if (_document && !_document->filepath(true).isEmpty()) {
const auto text = Platform::IsMac()
? tr::lng_context_show_in_finder(tr::now)
: tr::lng_context_show_in_folder(tr::now);
addAction(text, [=] { onShowInFolder(); });
addAction(text, [=] { showInFolder(); });
}
if ((_document && documentContentShown()) || (_photo && _photoMedia->loaded())) {
addAction(tr::lng_mediaview_copy(tr::now), [=] { onCopy(); });
addAction(tr::lng_mediaview_copy(tr::now), [=] { copyMedia(); });
}
if ((_photo && _photo->hasAttachedStickers())
|| (_document && _document->hasAttachedStickers())) {
auto callback = [=] {
if (_photo) {
onPhotoAttachedStickers();
} else if (_document) {
onDocumentAttachedStickers();
}
};
addAction(
tr::lng_context_attached_stickers(tr::now),
std::move(callback));
[=] { showAttachedStickers(); });
}
if (_canForwardItem) {
addAction(tr::lng_mediaview_forward(tr::now), [=] { onForward(); });
addAction(tr::lng_mediaview_forward(tr::now), [=] { forwardMedia(); });
}
const auto canDelete = [&] {
if (_canDeleteItem) {
@ -886,15 +879,15 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) {
return false;
}();
if (canDelete) {
addAction(tr::lng_mediaview_delete(tr::now), [=] { onDelete(); });
addAction(tr::lng_mediaview_delete(tr::now), [=] { deleteMedia(); });
}
addAction(tr::lng_mediaview_save_as(tr::now), [=] { onSaveAs(); });
addAction(tr::lng_mediaview_save_as(tr::now), [=] { saveAs(); });
if (const auto overviewType = computeOverviewType()) {
const auto text = _document
? tr::lng_mediaview_files_all(tr::now)
: tr::lng_mediaview_photos_all(tr::now);
addAction(text, [=] { onOverview(); });
addAction(text, [=] { showMediaOverview(); });
}
}
@ -1300,7 +1293,7 @@ void OverlayWidget::activateControls() {
}
}
void OverlayWidget::onHideControls(bool force) {
void OverlayWidget::hideControls(bool force) {
if (!force) {
if (!_dropdown->isHidden()
|| (_streamed && _streamed->controls.hasMenu())
@ -1333,24 +1326,7 @@ void OverlayWidget::dropdownHidden() {
updateOver(_lastMouseMovePos);
_ignoringDropdown = false;
if (!_controlsHideTimer.isActive()) {
onHideControls(true);
}
}
void OverlayWidget::onScreenResized(int screen) {
if (isHidden()) {
return;
}
const auto screens = QApplication::screens();
const auto changed = (screen >= 0 && screen < screens.size())
? screens[screen]
: nullptr;
if (windowHandle()
&& windowHandle()->screen()
&& changed
&& windowHandle()->screen() == changed) {
updateGeometry();
hideControls(true);
}
}
@ -1365,6 +1341,7 @@ void OverlayWidget::handleVisibleChanged(bool visible) {
}
void OverlayWidget::handleScreenChanged(QScreen *screen) {
subscribeToScreenGeometry();
if (!isVisible()) {
return;
}
@ -1376,7 +1353,21 @@ void OverlayWidget::handleScreenChanged(QScreen *screen) {
moveToScreen();
}
void OverlayWidget::onToMessage() {
void OverlayWidget::subscribeToScreenGeometry() {
_screenGeometryLifetime.destroy();
const auto screen = windowHandle()->screen();
if (!screen) {
return;
}
base::qt_signal_producer(
screen,
&QScreen::geometryChanged
) | rpl::start_with_next([=] {
updateGeometry();
}, _screenGeometryLifetime);
}
void OverlayWidget::toMessage() {
if (!_session) {
return;
}
@ -1397,7 +1388,7 @@ void OverlayWidget::notifyFileDialogShown(bool shown) {
}
}
void OverlayWidget::onSaveAs() {
void OverlayWidget::saveAs() {
QString file;
if (_document) {
const auto &location = _document->location(true);
@ -1502,9 +1493,9 @@ void OverlayWidget::onSaveAs() {
setFocus();
}
void OverlayWidget::onDocClick() {
void OverlayWidget::handleDocumentClick() {
if (_document->loading()) {
onSaveCancel();
saveCancel();
} else {
DocumentOpenClickHandler::Open(
fileOrigin(),
@ -1520,12 +1511,12 @@ PeerData *OverlayWidget::ui_getPeerForMouseAction() {
return _history ? _history->peer.get() : nullptr;
}
void OverlayWidget::onDownload() {
void OverlayWidget::downloadMedia() {
if (!_photo && !_document) {
return;
}
if (Core::App().settings().askDownloadPath()) {
return onSaveAs();
return saveAs();
}
QString path;
@ -1607,7 +1598,7 @@ void OverlayWidget::onDownload() {
}
}
void OverlayWidget::onSaveCancel() {
void OverlayWidget::saveCancel() {
if (_document && _document->loading()) {
_document->cancel();
if (_documentMedia->canBePlayed()) {
@ -1616,7 +1607,7 @@ void OverlayWidget::onSaveCancel() {
}
}
void OverlayWidget::onShowInFolder() {
void OverlayWidget::showInFolder() {
if (!_document) return;
auto filepath = _document->filepath(true);
@ -1626,7 +1617,7 @@ void OverlayWidget::onShowInFolder() {
}
}
void OverlayWidget::onForward() {
void OverlayWidget::forwardMedia() {
if (!_session) {
return;
}
@ -1645,7 +1636,7 @@ void OverlayWidget::onForward() {
{ 1, item->fullId() });
}
void OverlayWidget::onDelete() {
void OverlayWidget::deleteMedia() {
if (!_session) {
return;
}
@ -1678,7 +1669,7 @@ void OverlayWidget::onDelete() {
}
}
void OverlayWidget::onOverview() {
void OverlayWidget::showMediaOverview() {
if (_menu) {
_menu->hideMenu(true);
}
@ -1689,7 +1680,7 @@ void OverlayWidget::onOverview() {
}
}
void OverlayWidget::onCopy() {
void OverlayWidget::copyMedia() {
_dropdown->hideAnimated(Ui::DropdownMenu::HideOption::IgnoreShow);
if (_document) {
QGuiApplication::clipboard()->setImage(videoShown()
@ -1702,31 +1693,23 @@ void OverlayWidget::onCopy() {
}
}
void OverlayWidget::onPhotoAttachedStickers() {
if (!_session || !_photo) {
void OverlayWidget::showAttachedStickers() {
if (!_session) {
return;
}
const auto &active = _session->windows();
if (active.empty()) {
return;
}
_session->api().attachedStickers().requestAttachedStickerSets(
active.front(),
_photo);
close();
}
void OverlayWidget::onDocumentAttachedStickers() {
if (!_session || !_document) {
const auto window = active.front();
auto &attachedStickers = _session->api().attachedStickers();
if (_photo) {
attachedStickers.requestAttachedStickerSets(window, _photo);
} else if (_document) {
attachedStickers.requestAttachedStickerSets(window, _document);
} else {
return;
}
const auto &active = _session->windows();
if (active.empty()) {
return;
}
_session->api().attachedStickers().requestAttachedStickerSets(
active.front(),
_document);
close();
}
@ -2455,8 +2438,12 @@ void OverlayWidget::updateThemePreviewGeometry() {
void OverlayWidget::displayFinished() {
updateControls();
if (isHidden()) {
Ui::Platform::UpdateOverlayed(this);
moveToScreen();
//setAttribute(Qt::WA_DontShowOnScreen);
//OverlayParent::setVisibleHook(true);
//OverlayParent::setVisibleHook(false);
//setAttribute(Qt::WA_DontShowOnScreen, false);
Ui::Platform::UpdateOverlayed(this);
if (Platform::IsLinux()) {
showFullScreen();
} else {
@ -3616,19 +3603,19 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) {
}
if (!_menu && e->key() == Qt::Key_Escape) {
if (_document && _document->loading() && !_streamed) {
onDocClick();
handleDocumentClick();
} else {
close();
}
} else if (e == QKeySequence::Save || e == QKeySequence::SaveAs) {
onSaveAs();
saveAs();
} else if (e->key() == Qt::Key_Copy || (e->key() == Qt::Key_C && ctrl)) {
onCopy();
copyMedia();
} else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) {
if (_streamed) {
playbackPauseResume();
} else if (_document && !_document->loading() && (documentBubbleShown() || !_documentMedia->loaded())) {
onDocClick();
handleDocumentClick();
}
} else if (e->key() == Qt::Key_Left) {
if (_controlsHideTimer.isActive()) {
@ -4173,17 +4160,17 @@ void OverlayWidget::mouseReleaseEvent(QMouseEvent *e) {
Ui::showPeerProfile(_from);
}
} else if (_over == OverDate && _down == OverDate) {
onToMessage();
toMessage();
} else if (_over == OverHeader && _down == OverHeader) {
onOverview();
showMediaOverview();
} else if (_over == OverSave && _down == OverSave) {
onDownload();
downloadMedia();
} else if (_over == OverRotate && _down == OverRotate) {
playbackControlsRotate();
} else if (_over == OverIcon && _down == OverIcon) {
onDocClick();
handleDocumentClick();
} else if (_over == OverMore && _down == OverMore) {
InvokeQueued(this, [=] { onDropdown(); });
InvokeQueued(this, [=] { showDropdown(); });
} else if (_over == OverClose && _down == OverClose) {
close();
} else if (_over == OverVideo && _down == OverVideo) {
@ -4432,7 +4419,7 @@ void OverlayWidget::receiveMouse() {
_receiveMouse = true;
}
void OverlayWidget::onDropdown() {
void OverlayWidget::showDropdown() {
_dropdown->clearActions();
fillContextMenuActions([&] (const QString &text, Fn<void()> handler) {
_dropdown->addAction(text, std::move(handler));
@ -4442,7 +4429,7 @@ void OverlayWidget::onDropdown() {
_dropdown->setFocus();
}
void OverlayWidget::onTouchTimer() {
void OverlayWidget::handleTouchTimer() {
_touchRightButton = true;
}

View file

@ -72,10 +72,9 @@ class OverlayWidget final
: public OverlayParent
, public ClickHandlerHost
, private PlaybackControls::Delegate {
Q_OBJECT
public:
OverlayWidget();
~OverlayWidget();
enum class TouchBarItemType {
Photo,
@ -99,10 +98,8 @@ public:
updateOver(mapFromGlobal(QCursor::pos()));
}
void close();
void activateControls();
void onDocClick();
void close();
PeerData *ui_getPeerForMouseAction();
@ -110,36 +107,10 @@ public:
void clearSession();
~OverlayWidget();
// ClickHandlerHost interface
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
private Q_SLOTS:
void onHideControls(bool force = false);
void onScreenResized(int screen);
void onToMessage();
void onSaveAs();
void onDownload();
void onSaveCancel();
void onShowInFolder();
void onForward();
void onDelete();
void onOverview();
void onCopy();
void receiveMouse();
void onPhotoAttachedStickers();
void onDocumentAttachedStickers();
void onDropdown();
void onTouchTimer();
void updateImage();
private:
struct Streamed;
struct PipWrap;
@ -212,6 +183,25 @@ private:
void playbackPauseMusic();
void switchToPip();
void hideControls(bool force = false);
void subscribeToScreenGeometry();
void toMessage();
void saveAs();
void downloadMedia();
void saveCancel();
void showInFolder();
void forwardMedia();
void deleteMedia();
void showMediaOverview();
void copyMedia();
void receiveMouse();
void showAttachedStickers();
void showDropdown();
void handleTouchTimer();
void handleDocumentClick();
void updateImage();
void clearBeforeHide();
void clearAfterHide();
@ -445,6 +435,7 @@ private:
int32 _dragging = 0;
QPixmap _staticContent;
bool _blurred = true;
rpl::lifetime _screenGeometryLifetime;
std::unique_ptr<Streamed> _streamed;
std::unique_ptr<PipWrap> _pip;

View file

@ -375,7 +375,7 @@ PipPanel::PipPanel(
QWidget *parent,
Fn<void(QPainter&, FrameRequest, bool)> paint)
: _content(Ui::GL::CreateSurface(
parent,
nullptr, // No parent for the window in Qt parent-child sense.
[=](Ui::GL::Capabilities capabilities) {
return chooseRenderer(capabilities);
}))
@ -629,15 +629,22 @@ void PipPanel::setPositionOnScreen(Position position, QRect available) {
geometry += _padding;
widget()->setGeometry(geometry);
setGeometry(geometry);
widget()->setMinimumSize(minimalSize);
widget()->setMaximumSize(
std::max(minimalSize.width(), maximalSize.width()),
std::max(minimalSize.height(), maximalSize.height()));
updateDecorations();
}
void PipPanel::update() {
widget()->update();
}
void PipPanel::setGeometry(QRect geometry) {
widget()->setGeometry(geometry);
}
void PipPanel::paint(QPainter &p, const QRegion &clip, bool opengl) {
if (_useTransparency && opengl) {
p.setCompositionMode(QPainter::CompositionMode_Source);
@ -826,7 +833,7 @@ void PipPanel::processDrag(QPoint point) {
} else {
const auto newGeometry = valid.marginsAdded(_padding);
_positionAnimation.stop();
widget()->setGeometry(newGeometry);
setGeometry(newGeometry);
}
}
@ -917,8 +924,8 @@ void PipPanel::updateDecorations() {
_padding = padding;
_useTransparency = use;
widget()->setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
widget()->setGeometry(newGeometry);
widget()->update();
setGeometry(newGeometry);
update();
}
Pip::Pip(
@ -1029,7 +1036,7 @@ void Pip::setOverState(OverState state) {
const auto nowShown = (_over != OverState::None);
if ((was != OverState::None) != nowShown) {
_controlsShown.start(
[=] { _panel.widget()->update(); },
[=] { _panel.update(); },
nowShown ? 0. : 1.,
nowShown ? 1. : 0.,
st::fadeWrapDuration,
@ -1038,7 +1045,7 @@ void Pip::setOverState(OverState state) {
if (!_pressed) {
updateActiveState(was);
}
_panel.widget()->update();
_panel.update();
}
void Pip::setPressedState(std::optional<OverState> state) {
@ -1232,7 +1239,7 @@ void Pip::updatePlayPauseResumeState(const Player::TrackState &state) {
auto showPause = Player::ShowPauseIcon(state.state);
if (showPause != _showPause) {
_showPause = showPause;
_panel.widget()->update();
_panel.update();
}
}
@ -1397,7 +1404,7 @@ void Pip::handleStreamingUpdate(Streaming::Update &&update) {
}, [&](const PreloadedVideo &update) {
updatePlaybackState();
}, [&](const UpdateVideo &update) {
_panel.widget()->update();
_panel.update();
Core::App().updateNonIdle();
updatePlaybackState();
}, [&](const PreloadedAudio &update) {

View file

@ -60,6 +60,9 @@ public:
[[nodiscard]] not_null<QWidget*> widget() const;
[[nodiscard]] not_null<Ui::RpWidgetWrap*> rp() const;
void update();
void setGeometry(QRect geometry);
void setAspectRatio(QSize ratio);
[[nodiscard]] Position countPosition() const;
void setPosition(Position position);