routine code quality improvement

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-09-15 18:24:34 +08:00
parent 31eed109a0
commit 91bb8273b8
13 changed files with 133 additions and 55 deletions

View File

@ -9,6 +9,7 @@
#include <QtWidgets/qpushbutton.h> #include <QtWidgets/qpushbutton.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h> #include <QtWidgets/qfileiconprovider.h>
#include <QtWidgets/qmessagebox.h>
#include <StandardTitleBar> #include <StandardTitleBar>
#include <FramelessWidgetsHelper> #include <FramelessWidgetsHelper>
#include <StandardSystemButton> #include <StandardSystemButton>
@ -44,6 +45,14 @@ void Dialog::setupUi()
findButton = new QPushButton(tr("&Find")); findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true); findButton->setDefault(true);
connect(findButton, &QPushButton::clicked, this, [this](){
const QString text = lineEdit->text();
if (text.isEmpty()) {
QMessageBox::warning(this, tr("Warning"), tr("You didn't enter anything in the search box."));
} else {
QMessageBox::information(this, tr("Result"), tr("You wanted to find: \"%1\".").arg(text));
}
});
moreButton = new QPushButton(tr("&More")); moreButton = new QPushButton(tr("&More"));
moreButton->setCheckable(true); moreButton->setCheckable(true);

View File

@ -113,7 +113,7 @@ Q_SIGNALS:
private: private:
void initialize(); void initialize();
void updateAll(); void updateAll();
void mouseEventHandler(const QMouseEvent *event); Q_NODISCARD bool mouseEventHandler(QMouseEvent *event);
Q_NODISCARD QRect windowIconRect() const; Q_NODISCARD QRect windowIconRect() const;
Q_NODISCARD bool isInTitleBarIconArea(const QPoint &pos) const; Q_NODISCARD bool isInTitleBarIconArea(const QPoint &pos) const;
Q_NODISCARD bool windowIconVisible_real() const; Q_NODISCARD bool windowIconVisible_real() const;

View File

@ -77,7 +77,7 @@ public:
Q_NODISCARD QFont titleFont() const; Q_NODISCARD QFont titleFont() const;
void setTitleFont(const QFont &value); void setTitleFont(const QFont &value);
void mouseEventHandler(const QMouseEvent *event); Q_NODISCARD bool mouseEventHandler(QMouseEvent *event);
Q_NODISCARD QRect windowIconRect() const; Q_NODISCARD QRect windowIconRect() const;
Q_NODISCARD bool windowIconVisible_real() const; Q_NODISCARD bool windowIconVisible_real() const;

View File

@ -38,35 +38,39 @@ function(setup_compile_params arg_target)
QT_DISABLE_DEPRECATED_BEFORE=0x070000 QT_DISABLE_DEPRECATED_BEFORE=0x070000
QT_DISABLE_DEPRECATED_UP_TO=0x070000 # Since 6.5 QT_DISABLE_DEPRECATED_UP_TO=0x070000 # Since 6.5
) )
if(MSVC) if(WIN32) # Needed by both MSVC and MinGW
set(_WIN32_WINNT_WIN10 0x0A00) set(_WIN32_WINNT_WIN10 0x0A00)
set(NTDDI_WIN10_CO 0x0A00000B) set(NTDDI_WIN10_CO 0x0A00000B)
target_compile_definitions(${arg_target} PRIVATE
WINVER=${_WIN32_WINNT_WIN10} _WIN32_WINNT=${_WIN32_WINNT_WIN10}
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
)
endif()
if(MSVC)
target_compile_definitions(${arg_target} PRIVATE target_compile_definitions(${arg_target} PRIVATE
_CRT_NON_CONFORMING_SWPRINTFS _CRT_SECURE_NO_WARNINGS _CRT_NON_CONFORMING_SWPRINTFS _CRT_SECURE_NO_WARNINGS
_CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE _ENABLE_EXTENDED_ALIGNED_STORAGE _CRT_NONSTDC_NO_DEPRECATE _ENABLE_EXTENDED_ALIGNED_STORAGE
NOMINMAX UNICODE _UNICODE WIN32_LEAN_AND_MEAN WINRT_LEAN_AND_MEAN NOMINMAX UNICODE _UNICODE WIN32_LEAN_AND_MEAN WINRT_LEAN_AND_MEAN
WINVER=${_WIN32_WINNT_WIN10} _WIN32_WINNT=${_WIN32_WINNT_WIN10}
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
) )
target_compile_options(${arg_target} PRIVATE target_compile_options(${arg_target} PRIVATE
/utf-8 /W3 /WX # Cannot use /W4 here, Qt's own headers are not warning-clean. /utf-8 /W3 /WX # Can't use /W4 here, Qt's own headers are not warning-clean, especially QtQuick headers.
$<$<CONFIG:Debug>:/JMC> $<$<CONFIG:Debug>:/JMC>
$<$<NOT:$<CONFIG:Debug>>:/guard:cf /Gw /Gy /QIntel-jcc-erratum /Zc:inline> # /guard:ehcont ? /Qspectre-load ? $<$<NOT:$<CONFIG:Debug>>:/guard:cf /Gw /Gy /QIntel-jcc-erratum /Zc:inline> # /guard:ehcont? /Qspectre-load?
) )
target_link_options(${arg_target} PRIVATE target_link_options(${arg_target} PRIVATE
/WX # Make sure we don't use wrong parameters. /WX # Make sure we don't use wrong parameters.
$<$<NOT:$<CONFIG:Debug>>:/CETCOMPAT /GUARD:CF /OPT:REF /OPT:ICF> # /GUARD:EHCONT ? $<$<NOT:$<CONFIG:Debug>>:/CETCOMPAT /GUARD:CF /OPT:REF /OPT:ICF> # /GUARD:EHCONT?
) )
else() else()
target_compile_options(${arg_target} PRIVATE target_compile_options(${arg_target} PRIVATE
-Wall -Wextra -Werror -Wall -Wextra -Werror
#$<$<NOT:$<CONFIG:Debug>>:-ffunction-sections -fdata-sections -fcf-protection=full -Wa,-mno-branches-within-32B-boundaries> $<$<NOT:$<CONFIG:Debug>>:-ffunction-sections -fdata-sections -fcf-protection=full> # -Wa,-mno-branches-within-32B-boundaries?
) )
#[[target_link_options(${arg_target} PRIVATE target_link_options(${arg_target} PRIVATE
$<$<NOT:$<CONFIG:Debug>>:-Wl,--gc-sections> $<$<NOT:$<CONFIG:Debug>>:-Wl,--gc-sections>
) )
if(CLANG) #[[if(CLANG)
target_compile_options(${arg_target} PRIVATE target_compile_options(${arg_target} PRIVATE
$<$<NOT:$<CONFIG:Debug>>:-Xclang -cfguard -mretpoline> $<$<NOT:$<CONFIG:Debug>>:-Xclang -cfguard -mretpoline>
) )

View File

@ -122,24 +122,24 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
managerPriv->notifySystemThemeHasChangedOrNot(); managerPriv->notifySystemThemeHasChangedOrNot();
} }
} }
return false; return QObject::eventFilter(object, event);
} }
// We are only interested in events that are dispatched to top level windows. // We are only interested in events that are dispatched to top level windows.
if (!object->isWindowType()) { if (!object->isWindowType()) {
return false; return QObject::eventFilter(object, event);
} }
const QEvent::Type type = event->type(); const QEvent::Type type = event->type();
// We are only interested in some specific mouse events. // We are only interested in some specific mouse events.
if ((type != QEvent::MouseButtonPress) && (type != QEvent::MouseButtonRelease) if ((type != QEvent::MouseButtonPress) && (type != QEvent::MouseButtonRelease)
&& (type != QEvent::MouseButtonDblClick) && (type != QEvent::MouseMove)) { && (type != QEvent::MouseButtonDblClick) && (type != QEvent::MouseMove)) {
return false; return QObject::eventFilter(object, event);
} }
const auto window = qobject_cast<QWindow *>(object); const auto window = qobject_cast<QWindow *>(object);
const WId windowId = window->winId(); const WId windowId = window->winId();
g_qtHelper()->mutex.lock(); g_qtHelper()->mutex.lock();
if (!g_qtHelper()->data.contains(windowId)) { if (!g_qtHelper()->data.contains(windowId)) {
g_qtHelper()->mutex.unlock(); g_qtHelper()->mutex.unlock();
return false; return QObject::eventFilter(object, event);
} }
const QtHelperData data = g_qtHelper()->data.value(windowId); const QtHelperData data = g_qtHelper()->data.value(windowId);
g_qtHelper()->mutex.unlock(); g_qtHelper()->mutex.unlock();
@ -166,6 +166,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos); const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos);
if (edges != Qt::Edges{}) { if (edges != Qt::Edges{}) {
Utils::startSystemResize(window, edges, globalPos); Utils::startSystemResize(window, edges, globalPos);
event->accept();
return true; return true;
} }
} }
@ -179,6 +180,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
if (button == Qt::RightButton) { if (button == Qt::RightButton) {
if (!ignoreThisEvent && insideTitleBar) { if (!ignoreThisEvent && insideTitleBar) {
data.params.showSystemMenu(scenePos); data.params.showSystemMenu(scenePos);
event->accept();
return true; return true;
} }
} }
@ -190,6 +192,8 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
newWindowState = Qt::WindowMaximized; newWindowState = Qt::WindowMaximized;
} }
data.params.setWindowState(newWindowState); data.params.setWindowState(newWindowState);
event->accept();
return true;
} }
} break; } break;
case QEvent::MouseMove: { case QEvent::MouseMove: {
@ -210,6 +214,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
if (data.leftButtonPressed) { if (data.leftButtonPressed) {
if (!ignoreThisEvent && insideTitleBar) { if (!ignoreThisEvent && insideTitleBar) {
Utils::startSystemMove(window, globalPos); Utils::startSystemMove(window, globalPos);
event->accept();
return true; return true;
} }
} }
@ -217,7 +222,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
default: default:
break; break;
} }
return false; return QObject::eventFilter(object, event);
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -764,6 +764,11 @@ void Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
// Popup the system menu at the required position. // Popup the system menu at the required position.
const int result = TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() const int result = TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft()
? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr); ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr);
// Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
// highlighting until we unhighlight it manually.
HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
if (result == 0) { if (result == 0) {
// The user canceled the menu, no need to continue. // The user canceled the menu, no need to continue.
return; return;

View File

@ -801,19 +801,35 @@ FramelessQuickHelper *FramelessQuickHelper::get(QObject *object)
if (!object) { if (!object) {
return nullptr; return nullptr;
} }
FramelessQuickHelper *instance = nullptr;
QObject *parent = nullptr; QObject *parent = nullptr;
if (const auto item = qobject_cast<QQuickItem *>(object)) { QQuickItem *parentItem = nullptr;
parent = ((item->window() && item->window()->contentItem()) ? item->window()->contentItem() : item); if (const auto window = qobject_cast<QQuickWindow *>(object)) {
if (QQuickItem * const item = window->contentItem()) {
parent = item;
parentItem = item;
} else {
parent = window;
}
} else if (const auto item = qobject_cast<QQuickItem *>(object)) {
if (QQuickWindow * const window = item->window()) {
if (QQuickItem * const contentItem = window->contentItem()) {
parent = contentItem;
parentItem = contentItem;
} else {
parent = window;
parentItem = item;
}
} else {
parent = item;
parentItem = item;
}
} else { } else {
parent = object; parent = object;
} }
instance = parent->findChild<FramelessQuickHelper *>(); FramelessQuickHelper *instance = parent->findChild<FramelessQuickHelper *>();
if (!instance) { if (!instance) {
instance = new FramelessQuickHelper; instance = new FramelessQuickHelper;
if (const auto item = qobject_cast<QQuickItem *>(parent)) { instance->setParentItem(parentItem);
instance->setParentItem(item);
}
instance->setParent(parent); instance->setParent(parent);
// No need to do this here, we'll do it once the item has been assigned to a specific window. // No need to do this here, we'll do it once the item has been assigned to a specific window.
//instance->d_func()->attachToWindow(); //instance->d_func()->attachToWindow();
@ -943,14 +959,19 @@ void FramelessQuickHelper::itemChange(const ItemChange change, const ItemChangeD
{ {
QQuickItem::itemChange(change, value); QQuickItem::itemChange(change, value);
if ((change == ItemSceneChange) && value.window) { if ((change == ItemSceneChange) && value.window) {
const QObject * const p = parent();
const QQuickItem * const pItem = parentItem();
QQuickItem * const rootItem = value.window->contentItem(); QQuickItem * const rootItem = value.window->contentItem();
if (rootItem) { if (rootItem) {
if ((parentItem() != rootItem) || (parent() != rootItem)) { if ((pItem != rootItem) || (p != rootItem)) {
setParentItem(rootItem); setParentItem(rootItem);
setParent(rootItem); setParent(rootItem);
} }
} else { } else {
if (parent() != value.window) { if (pItem != nullptr) {
setParentItem(nullptr);
}
if (p != value.window) {
setParent(value.window); setParent(value.window);
} }
} }

View File

@ -357,11 +357,11 @@ void QuickStandardTitleBar::updateWindowIcon()
m_windowIcon->setSource(icon); m_windowIcon->setSource(icon);
} }
void QuickStandardTitleBar::mouseEventHandler(const QMouseEvent *event) bool QuickStandardTitleBar::mouseEventHandler(QMouseEvent *event)
{ {
Q_ASSERT(event); Q_ASSERT(event);
if (!event) { if (!event) {
return; return false;
} }
const Qt::MouseButton button = event->button(); const Qt::MouseButton button = event->button();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
@ -402,6 +402,7 @@ void QuickStandardTitleBar::mouseEventHandler(const QMouseEvent *event)
return scenePos; return scenePos;
}()); }());
}); });
// Don't eat this event, we have not handled it yet.
} }
break; break;
case QEvent::MouseButtonDblClick: case QEvent::MouseButtonDblClick:
@ -409,12 +410,16 @@ void QuickStandardTitleBar::mouseEventHandler(const QMouseEvent *event)
if ((button == Qt::LeftButton) && interestArea) { if ((button == Qt::LeftButton) && interestArea) {
m_closeTriggered = true; m_closeTriggered = true;
w->close(); w->close();
// Eat this event, we have handled it here.
event->accept();
return true;
} }
} }
break; break;
default: default:
break; break;
} }
return false;
} }
QRect QuickStandardTitleBar::windowIconRect() const QRect QuickStandardTitleBar::windowIconRect() const
@ -521,6 +526,8 @@ void QuickStandardTitleBar::itemChange(const ItemChange change, const ItemChange
m_windowTitleChangeConnection = connect(value.window, &QQuickWindow::windowTitleChanged, this, &QuickStandardTitleBar::updateTitleLabelText); m_windowTitleChangeConnection = connect(value.window, &QQuickWindow::windowTitleChanged, this, &QuickStandardTitleBar::updateTitleLabelText);
updateAll(); updateAll();
value.window->installEventFilter(this); value.window->installEventFilter(this);
// The window has changed, we need to re-add or re-remove the window icon rect to
// the hit test visible whitelist. This is different with Qt Widgets.
FramelessQuickHelper::get(this)->setHitTestVisible(windowIconRect(), windowIconVisible_real()); FramelessQuickHelper::get(this)->setHitTestVisible(windowIconRect(), windowIconVisible_real());
} }
} }
@ -542,9 +549,14 @@ bool QuickStandardTitleBar::eventFilter(QObject *object, QEvent *event)
const QEvent::Type type = event->type(); const QEvent::Type type = event->type();
if (type == QEvent::LanguageChange) { if (type == QEvent::LanguageChange) {
retranslateUi(); retranslateUi();
// Don't eat the event here, we need it to keep dispatching to other
// objects that may be interested in this event.
} else if ((type >= QEvent::MouseButtonPress) && (type <= QEvent::MouseMove)) { } else if ((type >= QEvent::MouseButtonPress) && (type <= QEvent::MouseMove)) {
const auto mouseEvent = static_cast<QMouseEvent *>(event); const auto mouseEvent = static_cast<QMouseEvent *>(event);
mouseEventHandler(mouseEvent); if (mouseEventHandler(mouseEvent)) {
// We have handled the event already, stop dispatching.
return true;
}
} }
return QQuickRectangle::eventFilter(object, event); return QQuickRectangle::eventFilter(object, event);
} }

View File

@ -28,12 +28,14 @@
#include "framelesswidgetshelper.h" #include "framelesswidgetshelper.h"
#include "framelesswidget.h" #include "framelesswidget.h"
#include "framelessmainwindow.h" #include "framelessmainwindow.h"
#include "framelessdialog.h"
#include "widgetssharedhelper_p.h" #include "widgetssharedhelper_p.h"
#include "standardtitlebar_p.h" #include "standardtitlebar_p.h"
#include "standardsystembutton_p.h" #include "standardsystembutton_p.h"
#include "framelesswidgetshelper_p.h" #include "framelesswidgetshelper_p.h"
#include "framelesswidget_p.h" #include "framelesswidget_p.h"
#include "framelessmainwindow_p.h" #include "framelessmainwindow_p.h"
#include "framelessdialog_p.h"
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -62,12 +64,14 @@ void initialize()
qRegisterMetaType<FramelessWidgetsHelper>(); qRegisterMetaType<FramelessWidgetsHelper>();
qRegisterMetaType<FramelessWidget>(); qRegisterMetaType<FramelessWidget>();
qRegisterMetaType<FramelessMainWindow>(); qRegisterMetaType<FramelessMainWindow>();
qRegisterMetaType<FramelessDialog>();
qRegisterMetaType<WidgetsSharedHelper>(); qRegisterMetaType<WidgetsSharedHelper>();
qRegisterMetaType<StandardTitleBarPrivate>(); qRegisterMetaType<StandardTitleBarPrivate>();
qRegisterMetaType<StandardSystemButtonPrivate>(); qRegisterMetaType<StandardSystemButtonPrivate>();
qRegisterMetaType<FramelessWidgetsHelperPrivate>(); qRegisterMetaType<FramelessWidgetsHelperPrivate>();
qRegisterMetaType<FramelessWidgetPrivate>(); qRegisterMetaType<FramelessWidgetPrivate>();
qRegisterMetaType<FramelessMainWindowPrivate>(); qRegisterMetaType<FramelessMainWindowPrivate>();
qRegisterMetaType<FramelessDialogPrivate>();
#endif #endif
} }

View File

@ -421,15 +421,10 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
QWidget *FramelessWidgetsHelperPrivate::getWindow() const QWidget *FramelessWidgetsHelperPrivate::getWindow() const
{ {
Q_Q(const FramelessWidgetsHelper); Q_Q(const FramelessWidgetsHelper);
const auto parentWidget = qobject_cast<QWidget *>(q->parent()); if (const auto parentWidget = qobject_cast<QWidget *>(q->parent())) {
if (!parentWidget) { return (parentWidget->nativeParentWidget() ? parentWidget->nativeParentWidget() : parentWidget->window());
return nullptr;
} }
QWidget * const nativeParentWidget = parentWidget->nativeParentWidget(); return nullptr;
if (nativeParentWidget) {
return nativeParentWidget;
}
return parentWidget->window();
} }
WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const
@ -782,15 +777,13 @@ FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *object)
if (!object) { if (!object) {
return nullptr; return nullptr;
} }
FramelessWidgetsHelper *instance = nullptr;
QObject *parent = nullptr; QObject *parent = nullptr;
if (object->isWidgetType()) { if (const auto widget = qobject_cast<QWidget *>(object)) {
const auto widget = qobject_cast<QWidget *>(object);
parent = (widget->nativeParentWidget() ? widget->nativeParentWidget() : widget->window()); parent = (widget->nativeParentWidget() ? widget->nativeParentWidget() : widget->window());
} else { } else {
parent = object; parent = object;
} }
instance = parent->findChild<FramelessWidgetsHelper *>(); FramelessWidgetsHelper *instance = parent->findChild<FramelessWidgetsHelper *>();
if (!instance) { if (!instance) {
instance = new FramelessWidgetsHelper(parent); instance = new FramelessWidgetsHelper(parent);
instance->d_func()->attachToWindow(); instance->d_func()->attachToWindow();

View File

@ -25,6 +25,7 @@
#include "standardsystembutton.h" #include "standardsystembutton.h"
#include "standardsystembutton_p.h" #include "standardsystembutton_p.h"
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <QtGui/qevent.h>
#include <QtWidgets/qtooltip.h> #include <QtWidgets/qtooltip.h>
#include <framelessmanager_p.h> #include <framelessmanager_p.h>
#include <utils.h> #include <utils.h>
@ -314,6 +315,7 @@ void StandardSystemButtonPrivate::enterEventHandler(QT_ENTER_EVENT_TYPE *event)
return; return;
} }
setHovered(true); setHovered(true);
event->accept();
} }
void StandardSystemButtonPrivate::leaveEventHandler(QEvent *event) void StandardSystemButtonPrivate::leaveEventHandler(QEvent *event)
@ -323,6 +325,7 @@ void StandardSystemButtonPrivate::leaveEventHandler(QEvent *event)
return; return;
} }
setHovered(false); setHovered(false);
event->accept();
} }
void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event) void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
@ -373,6 +376,7 @@ void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
painter.drawText(buttonRect, Qt::AlignCenter, m_code); painter.drawText(buttonRect, Qt::AlignCenter, m_code);
} }
painter.restore(); painter.restore();
event->accept();
} }
void StandardSystemButtonPrivate::initialize() void StandardSystemButtonPrivate::initialize()

View File

@ -126,7 +126,10 @@ ChromePalette *StandardTitleBarPrivate::chromePalette() const
void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event) void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
{ {
Q_UNUSED(event); Q_ASSERT(event);
if (!event) {
return;
}
Q_Q(StandardTitleBar); Q_Q(StandardTitleBar);
if (!m_window || m_chromePalette.isNull()) { if (!m_window || m_chromePalette.isNull()) {
return; return;
@ -181,6 +184,7 @@ void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
} }
} }
painter.restore(); painter.restore();
event->accept();
} }
bool StandardTitleBarPrivate::titleLabelVisible() const bool StandardTitleBarPrivate::titleLabelVisible() const
@ -230,6 +234,13 @@ void StandardTitleBarPrivate::setWindowIconVisible(const bool value)
return; return;
} }
m_windowIconVisible = value; m_windowIconVisible = value;
// Ideally we should use FramelessWidgetsHelper::get(this) everywhere, but sadly when
// we call it here, it may be too early that FramelessWidgetsHelper has not attached
// to the top level widget yet, and thus it will trigger an assert error (the assert
// should not be suppressed, because it usually indicates there's something really
// wrong). So here we have to use the top level widget directly, as a special case.
// NOTE: In your own code, you should always use FramelessWidgetsHelper::get(this)
// if possible.
FramelessWidgetsHelper::get(m_window)->setHitTestVisible(windowIconRect(), windowIconVisible_real()); FramelessWidgetsHelper::get(m_window)->setHitTestVisible(windowIconRect(), windowIconVisible_real());
Q_Q(StandardTitleBar); Q_Q(StandardTitleBar);
q->update(); q->update();
@ -252,14 +263,11 @@ void StandardTitleBarPrivate::setTitleFont(const QFont &value)
Q_EMIT q->titleFontChanged(); Q_EMIT q->titleFontChanged();
} }
void StandardTitleBarPrivate::mouseEventHandler(const QMouseEvent *event) bool StandardTitleBarPrivate::mouseEventHandler(QMouseEvent *event)
{ {
Q_ASSERT(event); Q_ASSERT(event);
if (!event) { if (!event) {
return; return false;
}
if (!m_window) {
return;
} }
Q_Q(const StandardTitleBar); Q_Q(const StandardTitleBar);
const Qt::MouseButton button = event->button(); const Qt::MouseButton button = event->button();
@ -271,7 +279,8 @@ void StandardTitleBarPrivate::mouseEventHandler(const QMouseEvent *event)
const bool interestArea = isInTitleBarIconArea(scenePos); const bool interestArea = isInTitleBarIconArea(scenePos);
switch (event->type()) { switch (event->type()) {
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease:
if (interestArea) { // We need a valid top level widget here.
if (m_window && interestArea) {
// Sadly the mouse release events are always triggered before the // Sadly the mouse release events are always triggered before the
// mouse double click events, and if we intercept the mouse release // mouse double click events, and if we intercept the mouse release
// events here, we'll never get the double click events afterwards, // events here, we'll never get the double click events afterwards,
@ -294,6 +303,7 @@ void StandardTitleBarPrivate::mouseEventHandler(const QMouseEvent *event)
if (m_closeTriggered) { if (m_closeTriggered) {
return; return;
} }
// Please refer to the comments in StandardTitleBarPrivate::setWindowIconVisible().
FramelessWidgetsHelper::get(m_window)->showSystemMenu([button, q, &scenePos]() -> QPoint { FramelessWidgetsHelper::get(m_window)->showSystemMenu([button, q, &scenePos]() -> QPoint {
if (button == Qt::LeftButton) { if (button == Qt::LeftButton) {
return {0, q->height()}; return {0, q->height()};
@ -301,17 +311,23 @@ void StandardTitleBarPrivate::mouseEventHandler(const QMouseEvent *event)
return scenePos; return scenePos;
}()); }());
}); });
// Don't eat this event, we have not handled it yet.
} }
break; break;
case QEvent::MouseButtonDblClick: case QEvent::MouseButtonDblClick:
if ((button == Qt::LeftButton) && interestArea) { // We need a valid top level widget here.
if (m_window && (button == Qt::LeftButton) && interestArea) {
m_closeTriggered = true; m_closeTriggered = true;
m_window->close(); m_window->close();
// Eat this event, we have handled it here.
event->accept();
return true;
} }
break; break;
default: default:
break; break;
} }
return false;
} }
QRect StandardTitleBarPrivate::windowIconRect() const QRect StandardTitleBarPrivate::windowIconRect() const
@ -604,14 +620,14 @@ void StandardTitleBar::mouseReleaseEvent(QMouseEvent *event)
{ {
QWidget::mouseReleaseEvent(event); QWidget::mouseReleaseEvent(event);
Q_D(StandardTitleBar); Q_D(StandardTitleBar);
d->mouseEventHandler(event); Q_UNUSED(d->mouseEventHandler(event));
} }
void StandardTitleBar::mouseDoubleClickEvent(QMouseEvent *event) void StandardTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{ {
QWidget::mouseDoubleClickEvent(event); QWidget::mouseDoubleClickEvent(event);
Q_D(StandardTitleBar); Q_D(StandardTitleBar);
d->mouseEventHandler(event); Q_UNUSED(d->mouseEventHandler(event));
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -121,15 +121,15 @@ bool WidgetsSharedHelper::eventFilter(QObject *object, QEvent *event)
const auto paintEvent = static_cast<QPaintEvent *>(event); const auto paintEvent = static_cast<QPaintEvent *>(event);
paintEventHandler(paintEvent); paintEventHandler(paintEvent);
} break; } break;
case QEvent::WindowStateChange: { case QEvent::WindowStateChange:
changeEventHandler(event); changeEventHandler(event);
} break; break;
case QEvent::Move: case QEvent::Move:
case QEvent::Resize: { case QEvent::Resize:
if (m_micaEnabled) { if (m_micaEnabled) {
m_targetWidget->update(); m_targetWidget->update();
} }
} break; break;
default: default:
break; break;
} }
@ -179,7 +179,10 @@ void WidgetsSharedHelper::changeEventHandler(QEvent *event)
void WidgetsSharedHelper::paintEventHandler(QPaintEvent *event) void WidgetsSharedHelper::paintEventHandler(QPaintEvent *event)
{ {
Q_UNUSED(event); Q_ASSERT(event);
if (!event) {
return;
}
if (m_micaEnabled && m_micaMaterial) { if (m_micaEnabled && m_micaMaterial) {
QPainter painter(m_targetWidget); QPainter painter(m_targetWidget);
m_micaMaterial->paint(&painter, m_targetWidget->size(), m_micaMaterial->paint(&painter, m_targetWidget->size(),
@ -205,6 +208,8 @@ void WidgetsSharedHelper::paintEventHandler(QPaintEvent *event)
painter.restore(); painter.restore();
} }
#endif #endif
// Don't eat this event here, we need Qt to keep dispatching this paint event
// otherwise the widget won't paint anything else from the user side.
} }
bool WidgetsSharedHelper::shouldDrawFrameBorder() const bool WidgetsSharedHelper::shouldDrawFrameBorder() const