diff --git a/framelesshelper.cpp b/framelesshelper.cpp index 58e8604..28ca2bf 100644 --- a/framelesshelper.cpp +++ b/framelesshelper.cpp @@ -298,6 +298,19 @@ void FramelessHelper::setResizable(QObject *const obj, const bool val) { } } +bool FramelessHelper::getTitleBarEnabled(QObject *const obj) const { + if (!obj) { + return true; + } + return !m_disableTitleBar.value(obj); +} + +void FramelessHelper::setTitleBarEnabled(QObject *const obj, const bool val) { + if (obj) { + m_disableTitleBar[obj] = !val; + } +} + void FramelessHelper::removeWindowFrame(QObject *const obj) { if (obj) { // Don't miss the Qt::Window flag. @@ -512,7 +525,8 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) { return ((point.y() <= m_titleBarHeight) && isInDraggableAreas(point, window) && isInDraggableObjects(globalPoint, window) && - isResizePermitted(globalPoint, point, window)); + isResizePermitted(globalPoint, point, window) && + getTitleBarEnabled(window)); } return false; }; diff --git a/framelesshelper.h b/framelesshelper.h index 5fc6b9b..e8bde31 100644 --- a/framelesshelper.h +++ b/framelesshelper.h @@ -77,6 +77,9 @@ public: bool getResizable(QObject *const obj) const; void setResizable(QObject *const obj, const bool val); + bool getTitleBarEnabled(QObject *const obj) const; + void setTitleBarEnabled(QObject *const obj, const bool val); + void removeWindowFrame(QObject *const obj); protected: @@ -90,5 +93,5 @@ private: QHash> m_ignoreAreas = {}, m_draggableAreas = {}; QHash>> m_ignoreObjects = {}, m_draggableObjects = {}; - QHash m_fixedSize = {}; + QHash m_fixedSize = {}, m_disableTitleBar = {}; }; diff --git a/framelessquickhelper.cpp b/framelessquickhelper.cpp index f7c2a67..4a9ccda 100644 --- a/framelessquickhelper.cpp +++ b/framelessquickhelper.cpp @@ -183,7 +183,43 @@ void FramelessQuickHelper::setResizable(const bool val) { } } -QSizeF FramelessQuickHelper::minimumSize() const { +bool FramelessQuickHelper::titleBarEnabled() const { + const auto win = window(); + if (win) { +#ifdef Q_OS_WINDOWS + const auto hWnd = reinterpret_cast(win->winId()); + if (hWnd) { + const auto data = WinNativeEventFilter::windowData(hWnd); + if (data) { + return !data->disableTitleBar; + } + } +#else + return m_framelessHelper.getTitleBarEnabled(win); +#endif + } + return true; +} + +void FramelessQuickHelper::setTitleBarEnabled(const bool val) { + const auto win = window(); + if (win) { +#ifdef Q_OS_WINDOWS + const auto hWnd = reinterpret_cast(win->winId()); + if (hWnd) { + const auto data = WinNativeEventFilter::windowData(hWnd); + if (data) { + data->disableTitleBar = !val; + Q_EMIT titleBarEnabledChanged(val); + } + } +#else + m_framelessHelper.setTitleBarEnabled(win, val); +#endif + } +} + +QSize FramelessQuickHelper::minimumSize() const { const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS @@ -198,10 +234,10 @@ QSizeF FramelessQuickHelper::minimumSize() const { return win->minimumSize(); #endif } - return {0.0, 0.0}; + return {0, 0}; } -void FramelessQuickHelper::setMinimumSize(const QSizeF &val) { +void FramelessQuickHelper::setMinimumSize(const QSize &val) { const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS @@ -209,18 +245,18 @@ void FramelessQuickHelper::setMinimumSize(const QSizeF &val) { if (hWnd) { const auto data = WinNativeEventFilter::windowData(hWnd); if (data) { - data->minimumSize = {qRound(val.width()), qRound(val.height())}; + data->minimumSize = val; Q_EMIT minimumSizeChanged(val); } } #else - win->setMinimumSize({qRound(val.width()), qRound(val.height())}); + win->setMinimumSize(val); Q_EMIT minimumSizeChanged(val); #endif } } -QSizeF FramelessQuickHelper::maximumSize() const { +QSize FramelessQuickHelper::maximumSize() const { const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS @@ -235,10 +271,10 @@ QSizeF FramelessQuickHelper::maximumSize() const { return win->maximumSize(); #endif } - return {0.0, 0.0}; + return {0, 0}; } -void FramelessQuickHelper::setMaximumSize(const QSizeF &val) { +void FramelessQuickHelper::setMaximumSize(const QSize &val) { const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS @@ -246,12 +282,12 @@ void FramelessQuickHelper::setMaximumSize(const QSizeF &val) { if (hWnd) { const auto data = WinNativeEventFilter::windowData(hWnd); if (data) { - data->maximumSize = {qRound(val.width()), qRound(val.height())}; + data->maximumSize = val; Q_EMIT maximumSizeChanged(val); } } #else - win->setMaximumSize({qRound(val.width()), qRound(val.height())}); + win->setMaximumSize(val); Q_EMIT maximumSizeChanged(val); #endif } diff --git a/framelessquickhelper.h b/framelessquickhelper.h index d1fc072..6440d28 100644 --- a/framelessquickhelper.h +++ b/framelessquickhelper.h @@ -57,10 +57,12 @@ class FramelessQuickHelper : public QQuickItem { NOTIFY titleBarHeightChanged) Q_PROPERTY(bool resizable READ resizable WRITE setResizable NOTIFY resizableChanged) - Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize NOTIFY + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize NOTIFY minimumSizeChanged) - Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize NOTIFY + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize NOTIFY maximumSizeChanged) + Q_PROPERTY(bool titleBarEnabled READ titleBarEnabled WRITE + setTitleBarEnabled NOTIFY titleBarEnabledChanged) public: explicit FramelessQuickHelper(QQuickItem *parent = nullptr); @@ -78,11 +80,14 @@ public: bool resizable() const; void setResizable(const bool val); - QSizeF minimumSize() const; - void setMinimumSize(const QSizeF &val); + QSize minimumSize() const; + void setMinimumSize(const QSize &val); - QSizeF maximumSize() const; - void setMaximumSize(const QSizeF &val); + QSize maximumSize() const; + void setMaximumSize(const QSize &val); + + bool titleBarEnabled() const; + void setTitleBarEnabled(const bool val); public Q_SLOTS: void removeWindowFrame(const bool center = true); @@ -109,8 +114,9 @@ Q_SIGNALS: void borderHeightChanged(int); void titleBarHeightChanged(int); void resizableChanged(bool); - void minimumSizeChanged(const QSizeF &); - void maximumSizeChanged(const QSizeF &); + void minimumSizeChanged(const QSize &); + void maximumSizeChanged(const QSize &); + void titleBarEnabledChanged(bool); private: #ifndef Q_OS_WINDOWS diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 7753000..09f12b9 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -1345,7 +1345,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, return true; } const auto getHTResult = [](const HWND _hWnd, const LPARAM _lParam, - const WINDOW *_data) -> LRESULT { + const WINDOWDATA &_data) -> LRESULT { const auto isInSpecificAreas = [](const int x, const int y, const QVector &areas, const qreal dpr) -> bool { @@ -1424,23 +1424,20 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const LONG tbh = getSystemMetric(_hWnd, SystemMetric::TitleBarHeight); const qreal dpr = GetDevicePixelRatioForWindow(_hWnd); - const bool isInIgnoreAreas = isInSpecificAreas( - mouse.x, mouse.y, _data->windowData.ignoreAreas, dpr); - const bool isInDraggableAreas = - _data->windowData.draggableAreas.isEmpty() + const bool isInIgnoreAreas = + isInSpecificAreas(mouse.x, mouse.y, _data.ignoreAreas, dpr); + const bool isInDraggableAreas = _data.draggableAreas.isEmpty() ? true - : isInSpecificAreas(mouse.x, mouse.y, - _data->windowData.draggableAreas, dpr); + : isInSpecificAreas(mouse.x, mouse.y, _data.draggableAreas, + dpr); #if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB) - const bool isInIgnoreObjects = - isInSpecificObjects(globalMouse.x, globalMouse.y, - _data->windowData.ignoreObjects, dpr); + const bool isInIgnoreObjects = isInSpecificObjects( + globalMouse.x, globalMouse.y, _data.ignoreObjects, dpr); const bool isInDraggableObjects = - _data->windowData.draggableObjects.isEmpty() + _data.draggableObjects.isEmpty() ? true : isInSpecificObjects(globalMouse.x, globalMouse.y, - _data->windowData.draggableObjects, - dpr); + _data.draggableObjects, dpr); #else // Don't block resizing if both of the Qt Widgets module and Qt // Quick module are not compiled in, although there's not much @@ -1450,11 +1447,11 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, #endif const bool isResizePermitted = !isInIgnoreAreas && !isInIgnoreObjects; - const bool isTitlebar = (mouse.y <= tbh) && + const bool isTitleBar = (mouse.y <= tbh) && isInDraggableAreas && isInDraggableObjects && - isResizePermitted; + isResizePermitted && !_data.disableTitleBar; if (IsMaximized(_hWnd)) { - if (isTitlebar) { + if (isTitleBar) { return HTCAPTION; } return HTCLIENT; @@ -1466,7 +1463,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const int factor = (isTop || isBottom) ? 2 : 1; const bool isLeft = (mouse.x <= (bw * factor)); const bool isRight = (mouse.x >= (ww - (bw * factor))); - const bool fixedSize = _data->windowData.fixedSize; + const bool fixedSize = _data.fixedSize; const auto getBorderValue = [fixedSize](int value) -> int { // HTBORDER: non-resizeable window border. return fixedSize ? HTBORDER : value; @@ -1495,12 +1492,12 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, if (isRight) { return getBorderValue(HTRIGHT); } - if (isTitlebar) { + if (isTitleBar) { return HTCAPTION; } return HTCLIENT; }; - *result = getHTResult(msg->hwnd, msg->lParam, data); + *result = getHTResult(msg->hwnd, msg->lParam, data->windowData); return true; } case WM_GETMINMAXINFO: { diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index ec2ea00..c0bc091 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -55,7 +55,7 @@ public: using WINDOWDATA = struct _WINDOWDATA { BOOL fixedSize = FALSE, mouseTransparent = FALSE, restoreDefaultWindowStyles = FALSE, - doNotEnableLayeredWindow = FALSE; + doNotEnableLayeredWindow = FALSE, disableTitleBar = FALSE; int borderWidth = -1, borderHeight = -1, titleBarHeight = -1; QVector ignoreAreas = {}, draggableAreas = {}; QVector> ignoreObjects = {}, draggableObjects = {};