fix: avoid resizing login transition

This commit is contained in:
dela
2026-06-10 17:15:34 +08:00
parent 4c783ab9ea
commit fa31f4f821
2 changed files with 52 additions and 256 deletions

View File

@@ -30,12 +30,10 @@
#include <QStringListModel> #include <QStringListModel>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QScreen> #include <QScreen>
#include <QParallelAnimationGroup>
#include <QGraphicsOpacityEffect> #include <QGraphicsOpacityEffect>
#include <services/auth/authservice.h> #include <services/auth/authservice.h>
#include "components/themetransitionwidget.h" #include "components/themetransitionwidget.h"
#include "components/moderntoast.h" #include "components/moderntoast.h"
#include <QPropertyAnimation>
#include <QEasingCurve> #include <QEasingCurve>
#include <QFocusEvent> #include <QFocusEvent>
#include <QLineF> #include <QLineF>
@@ -48,36 +46,6 @@
#include <widgetframe/windowbar.h> #include <widgetframe/windowbar.h>
#include <widgetframe/windowbutton.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) { static inline void emulateLeaveEvent(QWidget *widget) {
Q_ASSERT(widget); Q_ASSERT(widget);
if (!widget) return; if (!widget) return;
@@ -742,7 +710,15 @@ MainWindow::MainWindow(QWidget *parent)
macTitlebarNavSpacer->hide(); macTitlebarNavSpacer->hide();
} }
#endif #endif
resize(m_defaultWidth, m_defaultHeight); setMinimumSize(900, 600);
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
const QString startupWindowState = ConfigStore::instance()->get<QString>(
ConfigKeys::StartupWindowState, "normal");
if (startupWindowState == "maximized") {
setWindowState(windowState() | Qt::WindowMaximized);
} else {
resize(m_defaultWidth, m_defaultHeight);
}
@@ -969,162 +945,43 @@ void MainWindow::navigateToHome()
bool reduceAnimations = ConfigStore::instance()->get<bool>(ConfigKeys::UiAnimations, false); bool reduceAnimations = ConfigStore::instance()->get<bool>(ConfigKeys::UiAnimations, false);
if (reduceAnimations) { if (reduceAnimations) {
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
QString windowState = ConfigStore::instance()->get<QString>(
ConfigKeys::StartupWindowState, "normal");
bool shouldMaximize = (windowState == "maximized");
setMinimumSize(900, 600); setMinimumSize(900, 600);
#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) #if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC)
if (auto* minBtn = findChild<QWidget*>("min-button")) minBtn->show(); if (auto* minBtn = findChild<QWidget*>("min-button")) minBtn->show();
if (auto* maxBtn = findChild<QWidget*>("max-button")) maxBtn->show(); if (auto* maxBtn = findChild<QWidget*>("max-button")) maxBtn->show();
#endif #endif
m_viewStack->setCurrentWidget(m_homeView);
if (shouldMaximize) {
showMaximized();
} else {
QRect screenGeo = screen()->availableGeometry();
int w = 1280, h = 800;
setGeometry(
screenGeo.x() + (screenGeo.width() - w) / 2,
screenGeo.y() + (screenGeo.height() - h) / 2,
w, h);
}
m_viewTransitionInProgress = false;
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_loginView->setGraphicsEffect(nullptr);
m_homeView->setGraphicsEffect(nullptr); m_homeView->setGraphicsEffect(nullptr);
m_viewStack->setCurrentWidget(m_homeView); m_viewStack->setCurrentWidget(m_homeView);
m_viewTransitionInProgress = false;
#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; return;
} }
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
auto *loginOpacity = new QGraphicsOpacityEffect(m_loginView); setMinimumSize(900, 600);
loginOpacity->setOpacity(1.0);
m_loginView->setGraphicsEffect(loginOpacity);
auto *fadeOut = new QPropertyAnimation(loginOpacity, "opacity", this);
fadeOut->setDuration(120);
fadeOut->setStartValue(1.0);
fadeOut->setEndValue(0.0);
connect(fadeOut, &QPropertyAnimation::finished, this, [this]() {
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
setMinimumSize(0, 0);
QString windowState = ConfigStore::instance()->get<QString>(
ConfigKeys::StartupWindowState, "normal");
bool shouldMaximize = (windowState == "maximized");
QRect startGeo = this->geometry();
QRect targetGeo;
if (shouldMaximize) {
targetGeo = screen()->availableGeometry();
} else {
int targetWidth = 1280;
int targetHeight = 800;
QRect screenGeo = screen()->availableGeometry();
targetGeo = centeredRectWithin(startGeo,
QSize(targetWidth, targetHeight),
screenGeo);
}
auto finishWindowTransition = [this, shouldMaximize]() {
setMinimumSize(900, 600);
#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) #if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC)
if (auto* minBtn = findChild<QWidget*>("min-button")) minBtn->show(); if (auto* minBtn = findChild<QWidget*>("min-button")) minBtn->show();
if (auto* maxBtn = findChild<QWidget*>("max-button")) maxBtn->show(); if (auto* maxBtn = findChild<QWidget*>("max-button")) maxBtn->show();
#endif #endif
m_loginView->setGraphicsEffect(nullptr);
m_loginView->setGraphicsEffect(nullptr); auto *homeOpacity = new QGraphicsOpacityEffect(m_homeView);
homeOpacity->setOpacity(0.0);
m_homeView->setGraphicsEffect(homeOpacity);
m_viewStack->setCurrentWidget(m_homeView);
auto *fadeIn = new QPropertyAnimation(homeOpacity, "opacity", this);
if (shouldMaximize) { fadeIn->setDuration(250);
showMaximized(); fadeIn->setStartValue(0.0);
} fadeIn->setEndValue(1.0);
fadeIn->setEasingCurve(QEasingCurve::OutQuad);
connect(fadeIn, &QPropertyAnimation::finished, this, [this]() {
auto *homeOpacity = new QGraphicsOpacityEffect(m_homeView); m_homeView->setGraphicsEffect(nullptr);
homeOpacity->setOpacity(0.0); m_viewTransitionInProgress = false;
m_homeView->setGraphicsEffect(homeOpacity);
m_viewStack->setCurrentWidget(m_homeView);
auto *fadeIn = new QPropertyAnimation(homeOpacity, "opacity", this);
fadeIn->setDuration(250);
fadeIn->setStartValue(0.0);
fadeIn->setEndValue(1.0);
fadeIn->setEasingCurve(QEasingCurve::OutQuad);
connect(fadeIn, &QPropertyAnimation::finished, this, [this]() {
m_homeView->setGraphicsEffect(nullptr);
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); fadeIn->start(QAbstractAnimation::DeleteWhenStopped);
} }
void MainWindow::navigateToLogin() { void MainWindow::navigateToLogin() {
@@ -1149,104 +1006,43 @@ void MainWindow::navigateToLogin() {
if (auto* x = findChild<QWidget*>("max-button")) x->hide(); if (auto* x = findChild<QWidget*>("max-button")) x->hide();
#endif #endif
if (isMaximized()) showNormal(); setMinimumSize(900, 600);
setMinimumSize(0, 0);
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
m_homeView->setGraphicsEffect(nullptr);
m_loginView->setGraphicsEffect(nullptr);
m_viewStack->setCurrentWidget(m_loginView); m_viewStack->setCurrentWidget(m_loginView);
resize(m_defaultWidth, m_defaultHeight);
QRect screenGeo = screen()->availableGeometry();
move(screenGeo.x() + (screenGeo.width() - m_defaultWidth) / 2,
screenGeo.y() + (screenGeo.height() - m_defaultHeight) / 2);
m_core->authService()->logout(); m_core->authService()->logout();
m_viewTransitionInProgress = false; m_viewTransitionInProgress = false;
return; return;
} }
setMinimumSize(900, 600);
auto *homeOpacity = new QGraphicsOpacityEffect(m_homeView); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
homeOpacity->setOpacity(1.0);
m_homeView->setGraphicsEffect(homeOpacity);
auto *fadeOut = new QPropertyAnimation(homeOpacity, "opacity", this);
fadeOut->setDuration(120);
fadeOut->setStartValue(1.0);
fadeOut->setEndValue(0.0);
connect(fadeOut, &QPropertyAnimation::finished, this, [this]() {
#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) #if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC)
if (auto* m = findChild<QWidget*>("min-button")) m->hide(); if (auto* m = findChild<QWidget*>("min-button")) m->hide();
if (auto* x = findChild<QWidget*>("max-button")) x->hide(); if (auto* x = findChild<QWidget*>("max-button")) x->hide();
#endif #endif
m_homeView->setGraphicsEffect(nullptr);
if (isMaximized()) { auto *loginOpacity = new QGraphicsOpacityEffect(m_loginView);
QRect maxGeo = geometry(); loginOpacity->setOpacity(0.0);
showNormal(); m_loginView->setGraphicsEffect(loginOpacity);
setGeometry(maxGeo); m_viewStack->setCurrentWidget(m_loginView);
}
auto *fadeIn = new QPropertyAnimation(loginOpacity, "opacity", this);
setMinimumSize(0, 0); fadeIn->setDuration(250);
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); fadeIn->setStartValue(0.0);
fadeIn->setEndValue(1.0);
QRect startGeo = geometry(); fadeIn->setEasingCurve(QEasingCurve::OutQuad);
int targetWidth = m_defaultWidth;
int targetHeight = m_defaultHeight;
QRect targetGeo = centeredRectWithin(
startGeo, QSize(targetWidth, targetHeight),
screen()->availableGeometry());
auto finishWindowTransition = [this]() { connect(fadeIn, &QPropertyAnimation::finished, this, [this]() {
m_loginView->setGraphicsEffect(nullptr);
m_core->authService()->logout();
m_viewTransitionInProgress = false;
m_homeView->setGraphicsEffect(nullptr);
auto *loginOpacity = new QGraphicsOpacityEffect(m_loginView);
loginOpacity->setOpacity(0.0);
m_loginView->setGraphicsEffect(loginOpacity);
m_viewStack->setCurrentWidget(m_loginView);
auto *fadeIn = new QPropertyAnimation(loginOpacity, "opacity", this);
fadeIn->setDuration(250);
fadeIn->setStartValue(0.0);
fadeIn->setEndValue(1.0);
fadeIn->setEasingCurve(QEasingCurve::OutQuad);
connect(fadeIn, &QPropertyAnimation::finished, this, [this]() {
m_loginView->setGraphicsEffect(nullptr);
m_core->authService()->logout();
m_viewTransitionInProgress = false;
});
fadeIn->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); fadeIn->start(QAbstractAnimation::DeleteWhenStopped);
} }
bool MainWindow::eventFilter(QObject *watched, QEvent *event) bool MainWindow::eventFilter(QObject *watched, QEvent *event)

View File

@@ -53,8 +53,8 @@ private:
QElapsedTimer m_backClickTimer; QElapsedTimer m_backClickTimer;
quint32 m_defaultWidth{450}; quint32 m_defaultWidth{1280};
quint32 m_defaultHeight{320}; quint32 m_defaultHeight{800};
bool m_realQuit{false}; bool m_realQuit{false};
bool m_themeAnimating{false}; bool m_themeAnimating{false};
bool m_wasPausedByTray{false}; bool m_wasPausedByTray{false};