add synchronize api to wait for the ready signal

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2023-02-24 13:13:01 +08:00
parent e2652fc2a9
commit 598de50290
20 changed files with 183 additions and 55 deletions

View File

@ -136,7 +136,12 @@ void Dialog::setupUi()
// programatically, but we also want the user not able to resize the window manually.
// So apparently we can't use QWidget::setFixedWidth/Height/Size() here.
FramelessWidgetsHelperPrivate::get(helper)->setProperty(kDontOverrideCursorVar, true);
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
}
void Dialog::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
@ -147,5 +152,4 @@ void Dialog::setupUi()
} else {
helper->moveWindowToDesktopCenter();
}
});
}

View File

@ -27,6 +27,8 @@ public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;

View File

@ -54,6 +54,7 @@ int main(int argc, char *argv[])
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const auto dialog = std::make_unique<Dialog>();
dialog->waitReady();
dialog->show();
return QCoreApplication::exec();

View File

@ -54,6 +54,7 @@ int main(int argc, char *argv[])
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const auto mainWindow = std::make_unique<MainWindow>();
mainWindow->waitReady();
mainWindow->show();
return QCoreApplication::exec();

View File

@ -107,7 +107,27 @@ QMenuBar::item:pressed {
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
#endif // Q_OS_MACOS
helper->setHitTestVisible(mb); // IMPORTANT!
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(m_mainWindow->pushButton, &QPushButton::clicked, this, [this]{
const auto dialog = new Dialog(this);
dialog->waitReady();
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->exec();
});
connect(m_mainWindow->pushButton_2, &QPushButton::clicked, this, [this]{
const auto widget = new Widget(this);
widget->waitReady();
widget->setAttribute(Qt::WA_DeleteOnClose);
widget->show();
});
}
void MainWindow::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
@ -122,18 +142,4 @@ QMenuBar::item:pressed {
if (!savedState.isEmpty() && !parent()) {
restoreState(savedState);
}
});
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(m_mainWindow->pushButton, &QPushButton::clicked, this, [this]{
const auto dialog = new Dialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->exec();
});
connect(m_mainWindow->pushButton_2, &QPushButton::clicked, this, [this]{
const auto widget = new Widget(this);
widget->setAttribute(Qt::WA_DeleteOnClose);
widget->show();
});
}

View File

@ -44,6 +44,8 @@ public:
explicit MainWindow(QWidget *parent = nullptr, const Qt::WindowFlags flags = {});
~MainWindow() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;

View File

@ -103,6 +103,7 @@ int main(int argc, char *argv[])
QSurfaceFormat::setDefaultFormat(fmt);
const auto mainWindow = std::make_unique<MainWindow>();
mainWindow->waitReady();
mainWindow->show();
return QCoreApplication::exec();

View File

@ -82,7 +82,12 @@ void MainWindow::initialize()
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
#endif // Q_OS_MACOS
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
}
void MainWindow::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
@ -93,5 +98,4 @@ void MainWindow::initialize()
} else {
helper->moveWindowToDesktopCenter();
}
});
}

View File

@ -41,6 +41,8 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;

View File

@ -33,7 +33,7 @@ FramelessApplicationWindow {
visible: false // Hide the window before we sets up it's correct size and position.
width: 800
height: 600
title: qsTr("FramelessHelper demo application - Qt Quick")
title: qsTr("FramelessHelper demo application - Qt Quick [") + objectName + ']'
color: {
if (FramelessHelper.blurBehindWindowEnabled) {
return "transparent";

View File

@ -33,7 +33,7 @@ FramelessWindow {
visible: false // Hide the window before we sets up it's correct size and position.
width: 800
height: 600
title: qsTr("FramelessHelper demo application - Qt Quick")
title: qsTr("FramelessHelper demo application - Qt Quick [") + objectName +']'
color: {
if (FramelessHelper.blurBehindWindowEnabled) {
return "transparent";

View File

@ -55,10 +55,12 @@ int main(int argc, char *argv[])
const auto window1 = std::make_unique<Widget>();
window1->setObjectName(FRAMELESSHELPER_STRING_LITERAL("window1"));
window1->waitReady();
window1->show();
const auto window2 = std::make_unique<Widget>();
window2->setObjectName(FRAMELESSHELPER_STRING_LITERAL("window2"));
window2->waitReady();
window2->show();
return QCoreApplication::exec();

View File

@ -126,6 +126,13 @@ void Widget::initialize()
}
});
connect(this, &Widget::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(m_titleBar);
#ifndef Q_OS_MACOS
@ -133,19 +140,6 @@ void Widget::initialize()
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
#endif // Q_OS_MACOS
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QString objName = objectName();
const auto savedGeometry = Settings::get<QRect>(objName, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>(objName, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
});
}
void Widget::updateStyleSheet()
@ -162,3 +156,20 @@ void Widget::updateStyleSheet()
}
update();
}
void Widget::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const QString objName = objectName();
const auto savedGeometry = Settings::get<QRect>(objName, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>(objName, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
}

View File

@ -44,6 +44,8 @@ public:
explicit Widget(QWidget *parent = nullptr);
~Widget() override;
void waitReady();
protected:
void timerEvent(QTimerEvent *event) override;
void closeEvent(QCloseEvent *event) override;

View File

@ -66,6 +66,9 @@ public:
Q_NODISCARD QuickMicaMaterial *micaMaterial() const;
Q_NODISCARD QuickWindowBorder *windowBorder() const;
Q_NODISCARD bool isReady() const;
void waitForReady();
public Q_SLOTS:
void extendsContentIntoTitleBar(const bool value = true);

View File

@ -85,6 +85,9 @@ public:
Q_NODISCARD static FramelessQuickHelper *findOrCreateFramelessHelper(QObject *object);
Q_NODISCARD bool isReady() const;
void waitForReady();
private:
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
@ -101,6 +104,7 @@ private:
bool m_blurBehindWindowEnabled = false;
std::optional<bool> m_extendIntoTitleBar = std::nullopt;
bool m_destroying = false;
bool m_qpaReady = false;
};
FRAMELESSHELPER_END_NAMESPACE

View File

@ -59,6 +59,9 @@ public:
Q_NODISCARD MicaMaterial *micaMaterial() const;
Q_NODISCARD WindowBorderPainter *windowBorder() const;
Q_NODISCARD bool isReady() const;
void waitForReady();
public Q_SLOTS:
void extendsContentIntoTitleBar(const bool value = true);

View File

@ -86,6 +86,9 @@ public:
Q_NODISCARD static WidgetsSharedHelper *findOrCreateSharedHelper(QWidget *window);
Q_NODISCARD static FramelessWidgetsHelper *findOrCreateFramelessHelper(QObject *object);
Q_NODISCARD bool isReady() const;
void waitForReady();
private:
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
@ -102,6 +105,7 @@ private:
bool m_blurBehindWindowEnabled = false;
QPointer<QWidget> m_window = nullptr;
bool m_destroying = false;
bool m_qpaReady = false;
};
FRAMELESSHELPER_END_NAMESPACE

View File

@ -35,6 +35,7 @@
#endif // Q_OS_WINDOWS
#include <QtCore/qmutex.h>
#include <QtCore/qtimer.h>
#include <QtCore/qeventloop.h>
#include <QtCore/qloggingcategory.h>
#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
@ -237,6 +238,7 @@ void FramelessQuickHelperPrivate::attach()
// due to QPA will reset the position and size of the window during it's
// initialization process.
QTimer::singleShot(0, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
}
@ -660,6 +662,30 @@ FramelessQuickHelper *FramelessQuickHelperPrivate::findOrCreateFramelessHelper(Q
return instance;
}
bool FramelessQuickHelperPrivate::isReady() const
{
return m_qpaReady;
}
void FramelessQuickHelperPrivate::waitForReady()
{
if (m_qpaReady) {
return;
}
#if 1
QEventLoop loop;
Q_Q(FramelessQuickHelper);
const QMetaObject::Connection connection = connect(
q, &FramelessQuickHelper::ready, &loop, &QEventLoop::quit);
loop.exec();
disconnect(connection);
#else
while (!m_qpaReady) {
QCoreApplication::processEvents();
}
#endif
}
QRect FramelessQuickHelperPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
{
Q_ASSERT(item);
@ -993,6 +1019,18 @@ QuickWindowBorder *FramelessQuickHelper::windowBorder() const
return d->findOrCreateWindowBorder();
}
bool FramelessQuickHelper::isReady() const
{
Q_D(const FramelessQuickHelper);
return d->isReady();
}
void FramelessQuickHelper::waitForReady()
{
Q_D(FramelessQuickHelper);
d->waitForReady();
}
void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
{
Q_D(FramelessQuickHelper);

View File

@ -38,6 +38,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/qhash.h>
#include <QtCore/qtimer.h>
#include <QtCore/qeventloop.h>
#include <QtCore/qloggingcategory.h>
#include <QtGui/qwindow.h>
#include <QtGui/qpalette.h>
@ -320,6 +321,30 @@ FramelessWidgetsHelper *FramelessWidgetsHelperPrivate::findOrCreateFramelessHelp
return instance;
}
bool FramelessWidgetsHelperPrivate::isReady() const
{
return m_qpaReady;
}
void FramelessWidgetsHelperPrivate::waitForReady()
{
if (m_qpaReady) {
return;
}
#if 1
QEventLoop loop;
Q_Q(FramelessWidgetsHelper);
const QMetaObject::Connection connection = connect(
q, &FramelessWidgetsHelper::ready, &loop, &QEventLoop::quit);
loop.exec();
disconnect(connection);
#else
while (!m_qpaReady) {
QCoreApplication::processEvents();
}
#endif
}
bool FramelessWidgetsHelperPrivate::isContentExtendedIntoTitleBar() const
{
return getWindowData().ready;
@ -476,6 +501,7 @@ void FramelessWidgetsHelperPrivate::attach()
// due to QPA will reset the position and size of the window during it's
// initialization process.
QTimer::singleShot(0, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
}
@ -916,6 +942,18 @@ WindowBorderPainter *FramelessWidgetsHelper::windowBorder() const
return d->getWindowBorderIfAny();
}
bool FramelessWidgetsHelper::isReady() const
{
Q_D(const FramelessWidgetsHelper);
return d->isReady();
}
void FramelessWidgetsHelper::waitForReady()
{
Q_D(FramelessWidgetsHelper);
d->waitForReady();
}
void FramelessWidgetsHelper::extendsContentIntoTitleBar(const bool value)
{
Q_D(FramelessWidgetsHelper);