diff --git a/Telegram/SourceFiles/ui/twidget.cpp b/Telegram/SourceFiles/ui/twidget.cpp index e9848ef25..aaef88bb9 100644 --- a/Telegram/SourceFiles/ui/twidget.cpp +++ b/Telegram/SourceFiles/ui/twidget.cpp @@ -120,29 +120,65 @@ QString GetOverride(const QString &familyName) { namespace { -void _sendResizeEvents(QWidget *target) { - QResizeEvent e(target->size(), QSize()); - QApplication::sendEvent(target, &e); +class WidgetCreator : public QWidget { +public: + static void Create(not_null widget) { + volatile auto unknown = widget.get(); + static_cast(unknown)->create(); + } - const QObjectList children = target->children(); - for (int i = 0; i < children.size(); ++i) { - QWidget *child = static_cast(children.at(i)); - if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent)) { - _sendResizeEvents(child); +}; + +void CreateWidgetStateRecursive(not_null target) { + if (!target->testAttribute(Qt::WA_WState_Created)) { + if (!target->isWindow()) { + CreateWidgetStateRecursive(target->parentWidget()); } + WidgetCreator::Create(target); + } +} + +void SendPendingEventsRecursive(QWidget *target) { + auto wasVisible = target->isVisible(); + if (!wasVisible) { + target->setAttribute(Qt::WA_WState_Visible, true); + } + if (target->testAttribute(Qt::WA_PendingMoveEvent)) { + target->setAttribute(Qt::WA_PendingMoveEvent, false); + QMoveEvent e(target->pos(), QPoint()); + QApplication::sendEvent(target, &e); + } + if (target->testAttribute(Qt::WA_PendingResizeEvent)) { + target->setAttribute(Qt::WA_PendingResizeEvent, false); + QResizeEvent e(target->size(), QSize()); + QApplication::sendEvent(target, &e); + } + auto &children = target->children(); + for (auto i = 0; i < children.size(); ++i) { + auto child = children[i]; + if (child->isWidgetType()) { + auto widget = static_cast(child); + if (!widget->isWindow()) { + if (!widget->testAttribute(Qt::WA_WState_Created)) { + WidgetCreator::Create(widget); + } + SendPendingEventsRecursive(widget); + } + } + } + if (!wasVisible) { + target->setAttribute(Qt::WA_WState_Visible, false); } } } // namespace -bool TWidget::inFocusChain() const { - return !isHidden() && App::wnd() && (App::wnd()->focusWidget() == this || isAncestorOf(App::wnd()->focusWidget())); -} - void myEnsureResized(QWidget *target) { - if (target && (target->testAttribute(Qt::WA_PendingResizeEvent) || !target->testAttribute(Qt::WA_WState_Created))) { - _sendResizeEvents(target); + if (!target) { + return; } + CreateWidgetStateRecursive(target); + SendPendingEventsRecursive(target); } QPixmap myGrab(TWidget *target, QRect rect, QColor bg) { diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h index ddbed035c..902f240f4 100644 --- a/Telegram/SourceFiles/ui/twidget.h +++ b/Telegram/SourceFiles/ui/twidget.h @@ -29,6 +29,48 @@ QString GetOverride(const QString &familyName); } // namespace +template +class object_ptr; + +namespace Ui { + +inline bool InFocusChain(not_null widget) { + if (auto top = widget->window()) { + if (auto focused = top->focusWidget()) { + return !widget->isHidden() + && (focused == widget + || widget->isAncestorOf(focused)); + } + } + return false; +} + +template +inline ChildWidget *AttachParentChild( + not_null parent, + const object_ptr &child) { + if (auto raw = child.data()) { + raw->setParent(parent); + raw->show(); + return raw; + } + return nullptr; +} + +template +inline ChildWidget *AttachParentChildToBottom( + not_null parent, + const object_ptr &child) { + if (auto raw = AttachParentChild(parent, child)) { + raw->resizeToWidth(parent->width()); + raw->move(0, parent->height()); + return raw; + } + return nullptr; +} + +} // namespace Ui + enum class RectPart { None = 0, @@ -303,19 +345,21 @@ public: virtual void grabFinish() { } - bool inFocusChain() const; + bool inFocusChain() const { + return Ui::InFocusChain(this); + } void hideChildren() { for (auto child : children()) { - if (auto widget = qobject_cast(child)) { - widget->hide(); + if (child->isWidgetType()) { + static_cast(child)->hide(); } } } void showChildren() { for (auto child : children()) { - if (auto widget = qobject_cast(child)) { - widget->show(); + if (child->isWidgetType()) { + static_cast(child)->show(); } } }