Fix render glitches in passcodebox.

This commit is contained in:
John Preston 2019-04-26 13:43:57 +04:00
parent d74992b85b
commit 0b26475300
7 changed files with 56 additions and 21 deletions

View File

@ -304,11 +304,14 @@ QImage TabbedPanel::grabForAnimation() {
showChildren(); showChildren();
Ui::SendPendingMoveResizeEvents(this); Ui::SendPendingMoveResizeEvents(this);
auto result = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(
size() * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
result.fill(Qt::transparent); result.fill(Qt::transparent);
if (_selector) { if (_selector) {
_selector->render(&result, _selector->geometry().topLeft()); QPainter p(&result);
Ui::RenderWidget(p, _selector, _selector->pos());
} }
_a_show = base::take(showAnimation); _a_show = base::take(showAnimation);

View File

@ -563,7 +563,10 @@ void Widget::startWidthAnimation() {
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor()); image.setDevicePixelRatio(cRetinaFactor());
image.fill(Qt::transparent); image.fill(Qt::transparent);
_scroll->render(&image, QPoint(0, 0), QRect(QPoint(0, 0), grabGeometry.size()), QWidget::DrawChildren | QWidget::IgnoreMask); {
QPainter p(&image);
Ui::RenderWidget(p, _scroll);
}
_widthAnimationCache = App::pixmapFromImageInPlace(std::move(image)); _widthAnimationCache = App::pixmapFromImageInPlace(std::move(image));
_scroll->setGeometry(scrollGeometry); _scroll->setGeometry(scrollGeometry);
_scroll->hide(); _scroll->hide();

View File

@ -187,6 +187,15 @@ void SendPendingMoveResizeEvents(not_null<QWidget*> target) {
SendPendingEventsRecursive(target, !target->isVisible()); SendPendingEventsRecursive(target, !target->isVisible());
} }
void MarkDirtyOpaqueChildrenRecursive(not_null<QWidget*> target) {
target->resize(target->size()); // Calls setDirtyOpaqueRegion().
for (const auto child : target->children()) {
if (const auto widget = qobject_cast<QWidget*>(child)) {
MarkDirtyOpaqueChildrenRecursive(widget);
}
}
}
QPixmap GrabWidget(not_null<QWidget*> target, QRect rect, QColor bg) { QPixmap GrabWidget(not_null<QWidget*> target, QRect rect, QColor bg) {
SendPendingMoveResizeEvents(target); SendPendingMoveResizeEvents(target);
if (rect.isNull()) { if (rect.isNull()) {
@ -198,16 +207,15 @@ QPixmap GrabWidget(not_null<QWidget*> target, QRect rect, QColor bg) {
if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) { if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) {
result.fill(bg); result.fill(bg);
} }
target->render( {
&result, QPainter p(&result);
QPoint(0, 0), RenderWidget(p, target, QPoint(), rect);
rect, }
QWidget::DrawChildren | QWidget::IgnoreMask);
return result; return result;
} }
QImage GrabWidgetToImage(not_null<QWidget*> target, QRect rect, QColor bg) { QImage GrabWidgetToImage(not_null<QWidget*> target, QRect rect, QColor bg) {
Ui::SendPendingMoveResizeEvents(target); SendPendingMoveResizeEvents(target);
if (rect.isNull()) { if (rect.isNull()) {
rect = target->rect(); rect = target->rect();
} }
@ -219,14 +227,26 @@ QImage GrabWidgetToImage(not_null<QWidget*> target, QRect rect, QColor bg) {
if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) { if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) {
result.fill(bg); result.fill(bg);
} }
target->render( {
&result, QPainter p(&result);
QPoint(0, 0), RenderWidget(p, target, QPoint(), rect);
rect, }
QWidget::DrawChildren | QWidget::IgnoreMask);
return result; return result;
} }
void RenderWidget(
QPainter &painter,
not_null<QWidget*> source,
const QPoint &targetOffset,
const QRegion &sourceRegion,
QWidget::RenderFlags renderFlags) {
const auto visible = source->isVisible();
source->render(&painter, targetOffset, sourceRegion, renderFlags);
if (!visible) {
MarkDirtyOpaqueChildrenRecursive(source);
}
}
void ForceFullRepaint(not_null<QWidget*> widget) { void ForceFullRepaint(not_null<QWidget*> widget) {
const auto refresher = std::make_unique<QWidget>(widget); const auto refresher = std::make_unique<QWidget>(widget);
refresher->setGeometry(widget->rect()); refresher->setGeometry(widget->rect());

View File

@ -57,6 +57,15 @@ QImage GrabWidgetToImage(
QRect rect = QRect(), QRect rect = QRect(),
QColor bg = QColor(255, 255, 255, 0)); QColor bg = QColor(255, 255, 255, 0));
void RenderWidget(
QPainter &painter,
not_null<QWidget*> source,
const QPoint &targetOffset = QPoint(),
const QRegion &sourceRegion = QRegion(),
QWidget::RenderFlags renderFlags
= QWidget::DrawChildren | QWidget::IgnoreMask);
void ForceFullRepaint(not_null<QWidget*> widget); void ForceFullRepaint(not_null<QWidget*> widget);
void PostponeCall(FnMut<void()> &&callable); void PostponeCall(FnMut<void()> &&callable);

View File

@ -304,9 +304,9 @@ QImage InnerDropdown::grabForPanelAnimation() {
{ {
Painter p(&result); Painter p(&result);
App::roundRect(p, rect().marginsRemoved(_st.padding), _st.bg, ImageRoundRadius::Small); App::roundRect(p, rect().marginsRemoved(_st.padding), _st.bg, ImageRoundRadius::Small);
for (auto child : children()) { for (const auto child : children()) {
if (auto widget = qobject_cast<QWidget*>(child)) { if (const auto widget = qobject_cast<QWidget*>(child)) {
widget->render(&p, widget->pos(), widget->rect(), QWidget::DrawChildren | QWidget::IgnoreMask); RenderWidget(p, widget, widget->pos());
} }
} }
} }

View File

@ -412,9 +412,9 @@ QImage PopupMenu::grabForPanelAnimation() {
} else { } else {
p.fillRect(_inner, _st.menu.itemBg); p.fillRect(_inner, _st.menu.itemBg);
} }
for (auto child : children()) { for (const auto child : children()) {
if (auto widget = qobject_cast<QWidget*>(child)) { if (const auto widget = qobject_cast<QWidget*>(child)) {
widget->render(&p, widget->pos(), widget->rect(), QWidget::DrawChildren | QWidget::IgnoreMask); RenderWidget(p, widget, widget->pos());
} }
} }
} }

View File

@ -95,7 +95,7 @@ QPixmap Shadow::grab(
{ {
Painter p(&result); Painter p(&result);
Ui::Shadow::paint(p, full.marginsRemoved(extend), full.width(), shadow); Ui::Shadow::paint(p, full.marginsRemoved(extend), full.width(), shadow);
target->render(&p, QPoint(extend.left(), extend.top()), rect, QWidget::DrawChildren | QWidget::IgnoreMask); RenderWidget(p, target, QPoint(extend.left(), extend.top()));
} }
return result; return result;
} }