Emulate leave event for max button (#278)

This commit is contained in:
SineStriker 2023-08-31 15:55:25 +08:00 committed by GitHub
parent 9279500c18
commit 040027a6e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 36 additions and 1 deletions

View File

@ -38,6 +38,7 @@
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <QtGui/qevent.h> #include <QtGui/qevent.h>
#include <QtGui/qfontmetrics.h> #include <QtGui/qfontmetrics.h>
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -57,6 +58,33 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global; using namespace Global;
static void emulateLeaveEvent(QAbstractButton *button) {
QTimer::singleShot(0, button, [button](){
if (!QRect(button->mapToGlobal({}), button->size()).contains(QCursor::pos())) {
QApplication::postEvent(button, new QEvent(QEvent::Leave));
if (button->testAttribute(Qt::WA_Hover)) {
QPoint localPos = button->mapFromGlobal(QCursor::pos());
QPoint scenePos = button->window()->mapFromGlobal(QCursor::pos());
QPoint globalPos = QCursor::pos();
QPoint oldPos = {};
Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
auto e = new QHoverEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers);
Q_UNUSED(localPos);
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
auto e = new QHoverEvent(QEvent::HoverLeave, localPos, globalPos, oldPos, modifiers);
Q_UNUSED(scenePos);
#else
auto e = new QHoverEvent(QEvent::HoverLeave, localPos, oldPos, modifiers);
Q_UNUSED(scenePos);
Q_UNUSED(globalPos);
#endif
QApplication::postEvent(button, e);
}
}
});
}
StandardTitleBarPrivate::StandardTitleBarPrivate(StandardTitleBar *q) : QObject(q) StandardTitleBarPrivate::StandardTitleBarPrivate(StandardTitleBar *q) : QObject(q)
{ {
Q_ASSERT(q); Q_ASSERT(q);
@ -341,7 +369,9 @@ void StandardTitleBarPrivate::initialize()
titleBarLayout->setContentsMargins(0, 0, 0, 0); titleBarLayout->setContentsMargins(0, 0, 0, 0);
#elif FRAMELESSHELPER_CONFIG(system_button) #elif FRAMELESSHELPER_CONFIG(system_button)
minimizeButton = new StandardSystemButton(SystemButtonType::Minimize, q); minimizeButton = new StandardSystemButton(SystemButtonType::Minimize, q);
connect(minimizeButton, &StandardSystemButton::clicked, window, &QWidget::showMinimized); connect(minimizeButton, &StandardSystemButton::clicked, this, [this](){
window->showMinimized();
});
maximizeButton = new StandardSystemButton(SystemButtonType::Maximize, q); maximizeButton = new StandardSystemButton(SystemButtonType::Maximize, q);
updateMaximizeButton(); updateMaximizeButton();
connect(maximizeButton, &StandardSystemButton::clicked, this, [this](){ connect(maximizeButton, &StandardSystemButton::clicked, this, [this](){
@ -350,6 +380,11 @@ void StandardTitleBarPrivate::initialize()
} else { } else {
window->showMaximized(); window->showMaximized();
} }
// It's a Qt issue that if a QAbstractButton::clicked triggers a window's maximization,
// the button remains to be hovered until the mouse move. As a result, we need to
// manully send leave events to the button.
emulateLeaveEvent(maximizeButton);
}); });
closeButton = new StandardSystemButton(SystemButtonType::Close, q); closeButton = new StandardSystemButton(SystemButtonType::Close, q);
connect(closeButton, &StandardSystemButton::clicked, this, [this](){ connect(closeButton, &StandardSystemButton::clicked, this, [this](){