Fix media viewer on macOS multi-monitor setup.

This commit is contained in:
John Preston 2023-03-13 15:58:10 +04:00
parent cc6dfd08fc
commit 42d999922f
11 changed files with 66 additions and 8 deletions

View File

@ -234,7 +234,12 @@ void OverlayWidget::RendererGL::paint(
if (_factor != factor) {
_factor = factor;
_controlsImage.invalidate();
_controlsFadeImage.invalidate();
// We use the fact that fade texture atlas
// takes exactly full texture size. In case we
// just invalidate it we may get larger image
// in case of moving from greater _factor to lesser.
_controlsFadeImage.destroy(&f);
}
_blendingEnabled = false;
_viewport = widget->size();
@ -468,10 +473,10 @@ void OverlayWidget::RendererGL::paintTransformedContent(
program->setUniformValue("viewport", _uniformViewport);
const auto &top = st::mediaviewShadowTop.size();
const auto point = QPoint(_shadowTopFlip ? 0 : (_viewport.width() - top.width()), 0);
program->setUniformValue(
"shadowTopRect",
Uniform(transformRect(
QRect(QPoint(_viewport.width() - top.width(), 0), top))));
Uniform(transformRect(QRect(point, top))));
const auto &bottom = st::mediaviewShadowBottom;
program->setUniformValue(
"shadowBottomAndOpacity",
@ -687,9 +692,12 @@ void OverlayWidget::RendererGL::invalidateControls() {
}
void OverlayWidget::RendererGL::validateControlsFade() {
if (!_controlsFadeImage.image().isNull()) {
const auto flip = !_owner->topShadowOnTheRight();
if (!_controlsFadeImage.image().isNull()
&& _shadowTopFlip == flip) {
return;
}
_shadowTopFlip = flip;
const auto width = st::mediaviewShadowTop.width();
const auto bottomTop = st::mediaviewShadowTop.height();
const auto height = bottomTop + st::mediaviewShadowBottom.height();
@ -707,6 +715,10 @@ void OverlayWidget::RendererGL::validateControlsFade() {
QRect(0, bottomTop, width, st::mediaviewShadowBottom.height()));
p.end();
if (flip) {
image = std::move(image).mirrored(true, false);
}
_controlsFadeImage.setImage(std::move(image));
_shadowTopTexture = QRect(
QPoint(),

View File

@ -142,6 +142,7 @@ private:
QRect _shadowTopTexture;
QRect _shadowBottomTexture;
bool _shadowTopFlip;
bool _blendingEnabled = false;
rpl::lifetime _lifetime;

View File

@ -105,11 +105,22 @@ void OverlayWidget::RendererSW::paintControlsFade(
_p->setClipRect(geometry);
const auto width = _owner->width();
const auto &top = st::mediaviewShadowTop;
const auto flip = !_owner->topShadowOnTheRight();
const auto topShadow = QRect(
QPoint(width - top.width(), 0),
QPoint(flip ? 0 : (width - top.width()), 0),
top.size());
if (topShadow.intersected(geometry).intersects(_clipOuter)) {
top.paint(*_p, topShadow.topLeft(), width);
if (flip) {
if (_topShadowCache.isNull()
|| _topShadowColor != st::windowShadowFg->c) {
_topShadowColor = st::windowShadowFg->c;
_topShadowCache = top.instance(
_topShadowColor).mirrored(true, false);
}
_p->drawImage(0, 0, _topShadowCache);
} else {
top.paint(*_p, topShadow.topLeft(), width);
}
}
const auto &bottom = st::mediaviewShadowBottom;
const auto bottomShadow = QRect(

View File

@ -66,6 +66,9 @@ private:
QImage _overControlImage;
QImage _topShadowCache;
QColor _topShadowColor;
};
} // namespace Media::View

View File

@ -493,6 +493,12 @@ OverlayWidget::OverlayWidget()
}
}
}, lifetime());
_topShadowRight = _helper->controlsSideRightValue();
_topShadowRight.changes(
) | rpl::start_with_next([=] {
updateControlsGeometry();
update();
}, lifetime());
_window->setTitle(u"Media viewer"_q);
_window->setTitleStyle(st::mediaviewTitle);
@ -822,13 +828,19 @@ void OverlayWidget::updateControlsGeometry() {
const auto bottom = st::mediaviewShadowBottom.height();
const auto top = st::mediaviewShadowTop.size();
_bottomShadowRect = QRect(0, height() - bottom, width(), bottom);
_topShadowRect = QRect(QPoint(width() - top.width(), 0), top);
_topShadowRect = QRect(
QPoint(topShadowOnTheRight() ? (width() - top.width()) : 0, 0),
top);
updateControls();
resizeContentByScreenSize();
update();
}
bool OverlayWidget::topShadowOnTheRight() const {
return _topShadowRight.current();
}
QSize OverlayWidget::flipSizeByRotation(QSize size) const {
return FlipSizeByRotation(size, _rotation);
}

View File

@ -458,6 +458,7 @@ private:
void clearStreaming(bool savePosition = true);
bool canInitStreaming() const;
[[nodiscard]] bool topShadowOnTheRight() const;
void applyHideWindowWorkaround();
Window::SessionController *findWindow(bool switchTo = true) const;
@ -561,6 +562,7 @@ private:
QRect _bottomShadowRect;
QRect _topShadowRect;
rpl::variable<bool> _topShadowRight = false;
QRect _photoRadialRect;
Ui::RadialAnimation _radial;

View File

@ -35,6 +35,7 @@ public:
void minimize(not_null<Ui::RpWindow*> window) override;
void clearState() override;
void setControlsOpacity(float64 opacity) override;
rpl::producer<bool> controlsSideRightValue() override;
private:
using Control = Ui::Platform::TitleControl;

View File

@ -148,6 +148,10 @@ void MacOverlayWidgetHelper::setControlsOpacity(float64 opacity) {
_data->masterOpacity = opacity;
}
rpl::producer<bool> MacOverlayWidgetHelper::controlsSideRightValue() {
return rpl::single(false);
}
object_ptr<Ui::AbstractButton> MacOverlayWidgetHelper::create(
not_null<QWidget*> parent,
Control control) {

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/platform/ui_platform_window_title.h"
#include "ui/platform/ui_platform_utility.h"
#include "ui/widgets/rp_window.h"
#include "ui/abstract_button.h"
#include "styles/style_media_view.h"
@ -222,6 +223,13 @@ rpl::producer<> DefaultOverlayWidgetHelper::controlsActivations() {
return _buttons->activations();
}
rpl::producer<bool> DefaultOverlayWidgetHelper::controlsSideRightValue() {
return Ui::Platform::TitleControlsLayoutValue() | rpl::map([=] {
return _controls->controls.geometry().center().x()
> _controls->wrap.geometry().center().x();
}) | rpl::distinct_until_changed();
}
void DefaultOverlayWidgetHelper::beforeShow(bool fullscreen) {
_buttons->clearState();
}

View File

@ -38,6 +38,9 @@ public:
[[nodiscard]] virtual rpl::producer<> controlsActivations() {
return rpl::never<>();
}
[[nodiscard]] virtual rpl::producer<bool> controlsSideRightValue() {
return rpl::single(true);
}
virtual void beforeShow(bool fullscreen) {
}
virtual void afterShow(bool fullscreen) {
@ -72,6 +75,7 @@ public:
void beforeShow(bool fullscreen) override;
void clearState() override;
void setControlsOpacity(float64 opacity) override;
rpl::producer<bool> controlsSideRightValue() override;
rpl::producer<not_null<QMouseEvent*>> mouseEvents() const override;
private:

@ -1 +1 @@
Subproject commit 849a84050356a1321eedc36eb5296374e42fadd6
Subproject commit c80df2cdd2d2838d5e4aab50075e4f6e7c05e380