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();
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.fill(Qt::transparent);
if (_selector) {
_selector->render(&result, _selector->geometry().topLeft());
QPainter p(&result);
Ui::RenderWidget(p, _selector, _selector->pos());
}
_a_show = base::take(showAnimation);

View File

@ -563,7 +563,10 @@ void Widget::startWidthAnimation() {
QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor());
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));
_scroll->setGeometry(scrollGeometry);
_scroll->hide();

View File

@ -187,6 +187,15 @@ void SendPendingMoveResizeEvents(not_null<QWidget*> target) {
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) {
SendPendingMoveResizeEvents(target);
if (rect.isNull()) {
@ -198,16 +207,15 @@ QPixmap GrabWidget(not_null<QWidget*> target, QRect rect, QColor bg) {
if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) {
result.fill(bg);
}
target->render(
&result,
QPoint(0, 0),
rect,
QWidget::DrawChildren | QWidget::IgnoreMask);
{
QPainter p(&result);
RenderWidget(p, target, QPoint(), rect);
}
return result;
}
QImage GrabWidgetToImage(not_null<QWidget*> target, QRect rect, QColor bg) {
Ui::SendPendingMoveResizeEvents(target);
SendPendingMoveResizeEvents(target);
if (rect.isNull()) {
rect = target->rect();
}
@ -219,14 +227,26 @@ QImage GrabWidgetToImage(not_null<QWidget*> target, QRect rect, QColor bg) {
if (!target->testAttribute(Qt::WA_OpaquePaintEvent)) {
result.fill(bg);
}
target->render(
&result,
QPoint(0, 0),
rect,
QWidget::DrawChildren | QWidget::IgnoreMask);
{
QPainter p(&result);
RenderWidget(p, target, QPoint(), rect);
}
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) {
const auto refresher = std::make_unique<QWidget>(widget);
refresher->setGeometry(widget->rect());

View File

@ -57,6 +57,15 @@ QImage GrabWidgetToImage(
QRect rect = QRect(),
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 PostponeCall(FnMut<void()> &&callable);

View File

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

View File

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

View File

@ -95,7 +95,7 @@ QPixmap Shadow::grab(
{
Painter p(&result);
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;
}