perf: improve animation smoothness on Wayland
This commit is contained in:
+110
-39
@@ -48,6 +48,36 @@
|
||||
#include <widgetframe/windowbar.h>
|
||||
#include <widgetframe/windowbutton.h>
|
||||
|
||||
namespace {
|
||||
bool canAnimateTopLevelWindowPosition()
|
||||
{
|
||||
#if defined(Q_OS_LINUX)
|
||||
return !QGuiApplication::platformName().contains(QStringLiteral("wayland"),
|
||||
Qt::CaseInsensitive);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
QRect centeredRectWithin(const QRect &sourceGeometry, const QSize &targetSize,
|
||||
const QRect &bounds)
|
||||
{
|
||||
QRect target(QPoint(0, 0), targetSize);
|
||||
target.moveCenter(sourceGeometry.center());
|
||||
|
||||
if (target.left() < bounds.left())
|
||||
target.moveLeft(bounds.left());
|
||||
if (target.top() < bounds.top())
|
||||
target.moveTop(bounds.top());
|
||||
if (target.right() > bounds.right())
|
||||
target.moveRight(bounds.right());
|
||||
if (target.bottom() > bounds.bottom())
|
||||
target.moveBottom(bounds.bottom());
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void emulateLeaveEvent(QWidget *widget) {
|
||||
Q_ASSERT(widget);
|
||||
if (!widget) return;
|
||||
@@ -966,6 +996,51 @@ void MainWindow::navigateToHome()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canAnimateTopLevelWindowPosition()) {
|
||||
hide();
|
||||
setWindowOpacity(0.0);
|
||||
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
setMinimumSize(0, 0);
|
||||
|
||||
const QString windowState = ConfigStore::instance()->get<QString>(
|
||||
ConfigKeys::StartupWindowState, "normal");
|
||||
const bool shouldMaximize = (windowState == "maximized");
|
||||
|
||||
m_loginView->setGraphicsEffect(nullptr);
|
||||
m_homeView->setGraphicsEffect(nullptr);
|
||||
m_viewStack->setCurrentWidget(m_homeView);
|
||||
|
||||
#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC)
|
||||
if (auto* minBtn = findChild<QWidget*>("min-button")) minBtn->show();
|
||||
if (auto* maxBtn = findChild<QWidget*>("max-button")) maxBtn->show();
|
||||
#endif
|
||||
|
||||
if (shouldMaximize) {
|
||||
showMaximized();
|
||||
} else {
|
||||
resize(1280, 800);
|
||||
}
|
||||
setMinimumSize(900, 600);
|
||||
show();
|
||||
raise();
|
||||
activateWindow();
|
||||
|
||||
auto *fadeIn = new QPropertyAnimation(this, "windowOpacity", this);
|
||||
fadeIn->setDuration(180);
|
||||
fadeIn->setStartValue(0.0);
|
||||
fadeIn->setEndValue(1.0);
|
||||
fadeIn->setEasingCurve(QEasingCurve::OutCubic);
|
||||
|
||||
connect(fadeIn, &QPropertyAnimation::finished, this, [this]() {
|
||||
setWindowOpacity(1.0);
|
||||
m_viewTransitionInProgress = false;
|
||||
});
|
||||
QTimer::singleShot(0, fadeIn, [fadeIn]() {
|
||||
fadeIn->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto *loginOpacity = new QGraphicsOpacityEffect(m_loginView);
|
||||
loginOpacity->setOpacity(1.0);
|
||||
@@ -979,6 +1054,7 @@ void MainWindow::navigateToHome()
|
||||
connect(fadeOut, &QPropertyAnimation::finished, this, [this]() {
|
||||
|
||||
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
setMinimumSize(0, 0);
|
||||
|
||||
|
||||
QString windowState = ConfigStore::instance()->get<QString>(
|
||||
@@ -994,32 +1070,13 @@ void MainWindow::navigateToHome()
|
||||
|
||||
int targetWidth = 1280;
|
||||
int targetHeight = 800;
|
||||
targetGeo = QRect(
|
||||
startGeo.x() - (targetWidth - startGeo.width()) / 2,
|
||||
startGeo.y() - (targetHeight - startGeo.height()) / 2,
|
||||
targetWidth, targetHeight);
|
||||
|
||||
|
||||
|
||||
QRect screenGeo = screen()->availableGeometry();
|
||||
if (targetGeo.left() < screenGeo.left())
|
||||
targetGeo.moveLeft(screenGeo.left());
|
||||
if (targetGeo.top() < screenGeo.top())
|
||||
targetGeo.moveTop(screenGeo.top());
|
||||
if (targetGeo.right() > screenGeo.right())
|
||||
targetGeo.moveRight(screenGeo.right());
|
||||
if (targetGeo.bottom() > screenGeo.bottom())
|
||||
targetGeo.moveBottom(screenGeo.bottom());
|
||||
targetGeo = centeredRectWithin(startGeo,
|
||||
QSize(targetWidth, targetHeight),
|
||||
screenGeo);
|
||||
}
|
||||
|
||||
auto *geoAnim = new QPropertyAnimation(this, "geometry", this);
|
||||
|
||||
geoAnim->setDuration(shouldMaximize ? 500 : 350);
|
||||
geoAnim->setStartValue(startGeo);
|
||||
geoAnim->setEndValue(targetGeo);
|
||||
geoAnim->setEasingCurve(QEasingCurve::InOutCubic);
|
||||
|
||||
connect(geoAnim, &QPropertyAnimation::finished, this, [this, shouldMaximize]() {
|
||||
auto finishWindowTransition = [this, shouldMaximize]() {
|
||||
|
||||
setMinimumSize(900, 600);
|
||||
|
||||
@@ -1055,7 +1112,16 @@ void MainWindow::navigateToHome()
|
||||
m_viewTransitionInProgress = false;
|
||||
});
|
||||
fadeIn->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
});
|
||||
};
|
||||
|
||||
auto *geoAnim = new QPropertyAnimation(this, "geometry", this);
|
||||
|
||||
geoAnim->setDuration(shouldMaximize ? 500 : 350);
|
||||
geoAnim->setStartValue(startGeo);
|
||||
geoAnim->setEndValue(targetGeo);
|
||||
geoAnim->setEasingCurve(QEasingCurve::InOutCubic);
|
||||
connect(geoAnim, &QPropertyAnimation::finished, this,
|
||||
finishWindowTransition);
|
||||
geoAnim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
});
|
||||
fadeOut->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
@@ -1132,20 +1198,11 @@ void MainWindow::navigateToLogin() {
|
||||
QRect startGeo = geometry();
|
||||
int targetWidth = m_defaultWidth;
|
||||
int targetHeight = m_defaultHeight;
|
||||
|
||||
|
||||
QRect targetGeo(startGeo.x() + (startGeo.width() - targetWidth) / 2,
|
||||
startGeo.y() + (startGeo.height() - targetHeight) / 2,
|
||||
targetWidth, targetHeight);
|
||||
QRect targetGeo = centeredRectWithin(
|
||||
startGeo, QSize(targetWidth, targetHeight),
|
||||
screen()->availableGeometry());
|
||||
|
||||
auto *geoAnim = new QPropertyAnimation(this, "geometry", this);
|
||||
|
||||
geoAnim->setDuration(startGeo.width() > 1300 ? 500 : 350);
|
||||
geoAnim->setStartValue(startGeo);
|
||||
geoAnim->setEndValue(targetGeo);
|
||||
geoAnim->setEasingCurve(QEasingCurve::InOutCubic);
|
||||
|
||||
connect(geoAnim, &QPropertyAnimation::finished, this, [this]() {
|
||||
auto finishWindowTransition = [this]() {
|
||||
|
||||
|
||||
|
||||
@@ -1172,8 +1229,22 @@ void MainWindow::navigateToLogin() {
|
||||
m_viewTransitionInProgress = false;
|
||||
});
|
||||
fadeIn->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
});
|
||||
geoAnim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
};
|
||||
|
||||
if (canAnimateTopLevelWindowPosition()) {
|
||||
auto *geoAnim = new QPropertyAnimation(this, "geometry", this);
|
||||
|
||||
geoAnim->setDuration(startGeo.width() > 1300 ? 500 : 350);
|
||||
geoAnim->setStartValue(startGeo);
|
||||
geoAnim->setEndValue(targetGeo);
|
||||
geoAnim->setEasingCurve(QEasingCurve::InOutCubic);
|
||||
connect(geoAnim, &QPropertyAnimation::finished, this,
|
||||
finishWindowTransition);
|
||||
geoAnim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
} else {
|
||||
resize(targetGeo.size());
|
||||
finishWindowTransition();
|
||||
}
|
||||
});
|
||||
fadeOut->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user