diff --git a/framelesshelper.cpp b/framelesshelper.cpp index d76d391..8f8463f 100644 --- a/framelesshelper.cpp +++ b/framelesshelper.cpp @@ -48,6 +48,8 @@ FramelessHelper::FramelessHelper(QWindow *window) , m_window(window) , m_hoveredFrameSection(Qt::NoSection) , m_clickedFrameSection(Qt::NoSection) + , m_titleBarHeight(-1) + , m_resizeBorderThickness(-1) { Q_ASSERT(window != nullptr && window->isTopLevel()); @@ -138,6 +140,25 @@ void FramelessHelper::resizeWindow(const QSize& windowSize) setWindowSize(windowSize); } +int FramelessHelper::titleBarHeight() +{ + if (m_titleBarHeight == -1) { + return Utilities::getSystemMetric(m_window, SystemMetric::TitleBarHeight, true, false); + } + + return m_titleBarHeight; +} + +void FramelessHelper::setTitleBarHeight(int height) +{ + if (height < 0 && height != -1) { + qWarning() << "Negative title bar height was ignored."; + return; + } + + m_titleBarHeight = height; +} + QRect FramelessHelper::titleBarRect() { return QRect(0, 0, windowSize().width(), titleBarHeight()); @@ -163,6 +184,25 @@ QRegion FramelessHelper::titleBarRegion() return region; } +int FramelessHelper::resizeBorderThickness() +{ + if (m_resizeBorderThickness == -1) { + return Utilities::getSystemMetric(m_window, SystemMetric::ResizeBorderThickness, true, false); + } + + return m_resizeBorderThickness; +} + +void FramelessHelper::setResizeBorderThickness(int thickness) +{ + if (thickness < 0 && thickness != -1) { + qWarning() << "Negative resize border thickness was ignored."; + return; + } + + m_resizeBorderThickness = thickness; +} + QRect FramelessHelper::clientRect() { QRect rect(0, 0, windowSize().width(), windowSize().height()); @@ -767,7 +807,8 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event // then the window is clipped to the monitor so that the resize handle // do not appear because you don't need them (because you can't resize // a window when it's maximized unless you restore it). - const int resizeBorderThickness = qRound(this->resizeBorderThickness() * scaleFactor); + const int resizeBorderThickness = qRound( + static_cast(this->resizeBorderThickness()) * scaleFactor); clientRect->top += resizeBorderThickness; if (!shouldHaveWindowFrame()) { clientRect->bottom -= resizeBorderThickness; @@ -1037,8 +1078,10 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event break; } const LONG windowWidth = clientRect.right; - const int resizeBorderThickness = qRound(this->resizeBorderThickness() * scaleFactor); - const int titleBarHeight = qRound(this->titleBarHeight() * scaleFactor); + const int resizeBorderThickness = qRound( + static_cast(this->resizeBorderThickness()) * scaleFactor); + const int titleBarHeight = qRound( + static_cast(this->titleBarHeight()) * scaleFactor); bool isTitleBar = isInTitlebarArea(QPoint(qRound(localMouse.x() / scaleFactor), qRound(localMouse.y() / scaleFactor))); diff --git a/framelesshelper.h b/framelesshelper.h index 3d2638d..8492f2c 100644 --- a/framelesshelper.h +++ b/framelesshelper.h @@ -54,13 +54,13 @@ public: void setWindowSize(const QSize& size) { m_windowSize = size; } void resizeWindow(const QSize& windowSize); - int titleBarHeight() { return m_titleBarHeight; } - void setTitleBarHeight(int height) { m_titleBarHeight = height; } + int titleBarHeight(); + void setTitleBarHeight(int height); QRect titleBarRect(); QRegion titleBarRegion(); - int resizeBorderThickness() { return m_resizeBorderThickness; } - void setResizeBorderThickness(int thickness) { m_resizeBorderThickness = thickness; } + int resizeBorderThickness(); + void setResizeBorderThickness(int thickness); bool resizable() { return m_resizable; } void setResizable(bool resizable) { m_resizable = resizable; } diff --git a/utilities_linux.cpp b/utilities_linux.cpp index 41216c0..2903dc4 100644 --- a/utilities_linux.cpp +++ b/utilities_linux.cpp @@ -58,44 +58,30 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0); switch (metric) { case SystemMetric::ResizeBorderThickness: { - const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt(); - if ((resizeBorderThickness > 0) && !forceSystemValue) { - return qRound(static_cast(resizeBorderThickness) * scaleFactor); + // ### TO BE IMPLEMENTED: Retrieve system value through official API + if (dpiScale) { + return qRound(static_cast(kDefaultResizeBorderThickness) * devicePixelRatio); } else { - // ### TO BE IMPLEMENTED: Retrieve system value through official API - if (dpiScale) { - return qRound(static_cast(kDefaultResizeBorderThickness) * devicePixelRatio); - } else { - return kDefaultResizeBorderThickness; - } + return kDefaultResizeBorderThickness; } + } case SystemMetric::CaptionHeight: { - const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt(); - if ((captionHeight > 0) && !forceSystemValue) { - return qRound(static_cast(captionHeight) * scaleFactor); + // ### TO BE IMPLEMENTED: Retrieve system value through official API + if (dpiScale) { + return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); } else { - // ### TO BE IMPLEMENTED: Retrieve system value through official API - if (dpiScale) { - return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); - } else { - return kDefaultCaptionHeight; - } + return kDefaultCaptionHeight; } } case SystemMetric::TitleBarHeight: { - const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt(); - if ((titleBarHeight > 0) && !forceSystemValue) { - return qRound(static_cast(titleBarHeight) * scaleFactor); - } else { - const int captionHeight = getSystemMetric(window,SystemMetric::CaptionHeight, - dpiScale, forceSystemValue); - const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, - dpiScale, forceSystemValue); - return (((window->windowState() == Qt::WindowMaximized) - || (window->windowState() == Qt::WindowFullScreen)) - ? captionHeight : (captionHeight + resizeBorderThickness)); - } + const int captionHeight = getSystemMetric(window, SystemMetric::CaptionHeight, + dpiScale, forceSystemValue); + const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, + dpiScale, forceSystemValue); + return (((window->windowState() == Qt::WindowMaximized) + || (window->windowState() == Qt::WindowFullScreen)) + ? captionHeight : (captionHeight + resizeBorderThickness)); } } return 0; diff --git a/utilities_macos.mm b/utilities_macos.mm index 816f07a..fcbb7ac 100644 --- a/utilities_macos.mm +++ b/utilities_macos.mm @@ -35,6 +35,42 @@ FRAMELESSHELPER_BEGIN_NAMESPACE namespace Utilities { +static constexpr int kDefaultResizeBorderThickness = 8; +static constexpr int kDefaultCaptionHeight = 23; + +int getSystemMetric(const QWindow *window, const SystemMetric metric, const bool dpiScale, const bool forceSystemValue) +{ + Q_ASSERT(window); + if (!window) { + return 0; + } + + // The Apple platforms implement scaling and coordinate system virtualization, + // so there is no need to scale again. + + switch (metric) { + case SystemMetric::ResizeBorderThickness: { + // ### TO BE IMPLEMENTED: Retrieve system value through official API + return kDefaultResizeBorderThickness; + + } + case SystemMetric::CaptionHeight: { + // ### TO BE IMPLEMENTED: Retrieve system value through official API + return kDefaultCaptionHeight; + } + case SystemMetric::TitleBarHeight: { + const int captionHeight = getSystemMetric(window, SystemMetric::CaptionHeight, + dpiScale, forceSystemValue); + const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, + dpiScale, forceSystemValue); + return (((window->windowState() == Qt::WindowMaximized) + || (window->windowState() == Qt::WindowFullScreen)) + ? captionHeight : (captionHeight + resizeBorderThickness)); + } + } + return 0; +} + static QList gFlsWindows; static bool gNSWindowOverrode = false; diff --git a/utilities_win32.cpp b/utilities_win32.cpp index e79a0cf..01186b1 100644 --- a/utilities_win32.cpp +++ b/utilities_win32.cpp @@ -128,64 +128,49 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0); switch (metric) { case SystemMetric::ResizeBorderThickness: { - const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt(); - if ((resizeBorderThickness > 0) && !forceSystemValue) { - return qRound(static_cast(resizeBorderThickness) * scaleFactor); - } else { - const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER); - if (result > 0) { - if (dpiScale) { - return result; - } else { - return qRound(static_cast(result) / devicePixelRatio); - } + const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER); + if (result > 0) { + if (dpiScale) { + return result; } else { - qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); - // The padded border will disappear if DWM composition is disabled. - const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic); - if (dpiScale) { - return qRound(static_cast(defaultResizeBorderThickness) * devicePixelRatio); - } else { - return defaultResizeBorderThickness; - } + return qRound(static_cast(result) / devicePixelRatio); + } + } else { + qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); + // The padded border will disappear if DWM composition is disabled. + const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic); + if (dpiScale) { + return qRound(static_cast(defaultResizeBorderThickness) * devicePixelRatio); + } else { + return defaultResizeBorderThickness; } } } case SystemMetric::CaptionHeight: { - const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt(); - if ((captionHeight > 0) && !forceSystemValue) { - return qRound(static_cast(captionHeight) * scaleFactor); - } else { - const int result = GetSystemMetrics(SM_CYCAPTION); - if (result > 0) { - if (dpiScale) { - return result; - } else { - return qRound(static_cast(result) / devicePixelRatio); - } + const int result = GetSystemMetrics(SM_CYCAPTION); + if (result > 0) { + if (dpiScale) { + return result; } else { - qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); - if (dpiScale) { - return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); - } else { - return kDefaultCaptionHeight; - } + return qRound(static_cast(result) / devicePixelRatio); + } + } else { + qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); + if (dpiScale) { + return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); + } else { + return kDefaultCaptionHeight; } } } case SystemMetric::TitleBarHeight: { - const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt(); - if ((titleBarHeight > 0) && !forceSystemValue) { - return qRound(static_cast(titleBarHeight) * scaleFactor); - } else { - const int captionHeight = getSystemMetric(window,SystemMetric::CaptionHeight, - dpiScale, forceSystemValue); - const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, - dpiScale, forceSystemValue); - return (((window->windowState() == Qt::WindowMaximized) - || (window->windowState() == Qt::WindowFullScreen)) - ? captionHeight : (captionHeight + resizeBorderThickness)); - } + const int captionHeight = getSystemMetric( + window, SystemMetric::CaptionHeight, dpiScale, forceSystemValue); + const int resizeBorderThickness = getSystemMetric( + window, SystemMetric::ResizeBorderThickness, dpiScale, forceSystemValue); + return (((window->windowState() == Qt::WindowMaximized) + || (window->windowState() == Qt::WindowFullScreen)) + ? captionHeight : (captionHeight + resizeBorderThickness)); } } return 0;