default titlebar height and resize border

This commit is contained in:
Altair Wei 2021-10-06 15:40:23 +08:00
parent 183aa9a730
commit cefae7950d
5 changed files with 135 additions and 85 deletions

View File

@ -48,6 +48,8 @@ FramelessHelper::FramelessHelper(QWindow *window)
, m_window(window) , m_window(window)
, m_hoveredFrameSection(Qt::NoSection) , m_hoveredFrameSection(Qt::NoSection)
, m_clickedFrameSection(Qt::NoSection) , m_clickedFrameSection(Qt::NoSection)
, m_titleBarHeight(-1)
, m_resizeBorderThickness(-1)
{ {
Q_ASSERT(window != nullptr && window->isTopLevel()); Q_ASSERT(window != nullptr && window->isTopLevel());
@ -138,6 +140,25 @@ void FramelessHelper::resizeWindow(const QSize& windowSize)
setWindowSize(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() QRect FramelessHelper::titleBarRect()
{ {
return QRect(0, 0, windowSize().width(), titleBarHeight()); return QRect(0, 0, windowSize().width(), titleBarHeight());
@ -163,6 +184,25 @@ QRegion FramelessHelper::titleBarRegion()
return region; 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 FramelessHelper::clientRect()
{ {
QRect rect(0, 0, windowSize().width(), windowSize().height()); 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 // 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 // do not appear because you don't need them (because you can't resize
// a window when it's maximized unless you restore it). // a window when it's maximized unless you restore it).
const int resizeBorderThickness = qRound(this->resizeBorderThickness() * scaleFactor); const int resizeBorderThickness = qRound(
static_cast<qreal>(this->resizeBorderThickness()) * scaleFactor);
clientRect->top += resizeBorderThickness; clientRect->top += resizeBorderThickness;
if (!shouldHaveWindowFrame()) { if (!shouldHaveWindowFrame()) {
clientRect->bottom -= resizeBorderThickness; clientRect->bottom -= resizeBorderThickness;
@ -1037,8 +1078,10 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event
break; break;
} }
const LONG windowWidth = clientRect.right; const LONG windowWidth = clientRect.right;
const int resizeBorderThickness = qRound(this->resizeBorderThickness() * scaleFactor); const int resizeBorderThickness = qRound(
const int titleBarHeight = qRound(this->titleBarHeight() * scaleFactor); static_cast<qreal>(this->resizeBorderThickness()) * scaleFactor);
const int titleBarHeight = qRound(
static_cast<qreal>(this->titleBarHeight()) * scaleFactor);
bool isTitleBar = isInTitlebarArea(QPoint(qRound(localMouse.x() / scaleFactor), qRound(localMouse.y() / scaleFactor))); bool isTitleBar = isInTitlebarArea(QPoint(qRound(localMouse.x() / scaleFactor), qRound(localMouse.y() / scaleFactor)));

View File

@ -54,13 +54,13 @@ public:
void setWindowSize(const QSize& size) { m_windowSize = size; } void setWindowSize(const QSize& size) { m_windowSize = size; }
void resizeWindow(const QSize& windowSize); void resizeWindow(const QSize& windowSize);
int titleBarHeight() { return m_titleBarHeight; } int titleBarHeight();
void setTitleBarHeight(int height) { m_titleBarHeight = height; } void setTitleBarHeight(int height);
QRect titleBarRect(); QRect titleBarRect();
QRegion titleBarRegion(); QRegion titleBarRegion();
int resizeBorderThickness() { return m_resizeBorderThickness; } int resizeBorderThickness();
void setResizeBorderThickness(int thickness) { m_resizeBorderThickness = thickness; } void setResizeBorderThickness(int thickness);
bool resizable() { return m_resizable; } bool resizable() { return m_resizable; }
void setResizable(bool resizable) { m_resizable = resizable; } void setResizable(bool resizable) { m_resizable = resizable; }

View File

@ -58,44 +58,30 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0); const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0);
switch (metric) { switch (metric) {
case SystemMetric::ResizeBorderThickness: { case SystemMetric::ResizeBorderThickness: {
const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt(); // ### TO BE IMPLEMENTED: Retrieve system value through official API
if ((resizeBorderThickness > 0) && !forceSystemValue) { if (dpiScale) {
return qRound(static_cast<qreal>(resizeBorderThickness) * scaleFactor); return qRound(static_cast<qreal>(kDefaultResizeBorderThickness) * devicePixelRatio);
} else { } else {
// ### TO BE IMPLEMENTED: Retrieve system value through official API return kDefaultResizeBorderThickness;
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultResizeBorderThickness) * devicePixelRatio);
} else {
return kDefaultResizeBorderThickness;
}
} }
} }
case SystemMetric::CaptionHeight: { case SystemMetric::CaptionHeight: {
const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt(); // ### TO BE IMPLEMENTED: Retrieve system value through official API
if ((captionHeight > 0) && !forceSystemValue) { if (dpiScale) {
return qRound(static_cast<qreal>(captionHeight) * scaleFactor); return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else { } else {
// ### TO BE IMPLEMENTED: Retrieve system value through official API return kDefaultCaptionHeight;
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
return kDefaultCaptionHeight;
}
} }
} }
case SystemMetric::TitleBarHeight: { case SystemMetric::TitleBarHeight: {
const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt(); const int captionHeight = getSystemMetric(window, SystemMetric::CaptionHeight,
if ((titleBarHeight > 0) && !forceSystemValue) { dpiScale, forceSystemValue);
return qRound(static_cast<qreal>(titleBarHeight) * scaleFactor); const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness,
} else { dpiScale, forceSystemValue);
const int captionHeight = getSystemMetric(window,SystemMetric::CaptionHeight, return (((window->windowState() == Qt::WindowMaximized)
dpiScale, forceSystemValue); || (window->windowState() == Qt::WindowFullScreen))
const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, ? captionHeight : (captionHeight + resizeBorderThickness));
dpiScale, forceSystemValue);
return (((window->windowState() == Qt::WindowMaximized)
|| (window->windowState() == Qt::WindowFullScreen))
? captionHeight : (captionHeight + resizeBorderThickness));
}
} }
} }
return 0; return 0;

View File

@ -35,6 +35,42 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
namespace Utilities { 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<NSWindow*> gFlsWindows; static QList<NSWindow*> gFlsWindows;
static bool gNSWindowOverrode = false; static bool gNSWindowOverrode = false;

View File

@ -128,64 +128,49 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0); const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0);
switch (metric) { switch (metric) {
case SystemMetric::ResizeBorderThickness: { case SystemMetric::ResizeBorderThickness: {
const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt(); const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
if ((resizeBorderThickness > 0) && !forceSystemValue) { if (result > 0) {
return qRound(static_cast<qreal>(resizeBorderThickness) * scaleFactor); if (dpiScale) {
} else { return result;
const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
if (result > 0) {
if (dpiScale) {
return result;
} else {
return qRound(static_cast<qreal>(result) / devicePixelRatio);
}
} else { } else {
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); return qRound(static_cast<qreal>(result) / devicePixelRatio);
// The padded border will disappear if DWM composition is disabled. }
const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic); } else {
if (dpiScale) { qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"));
return qRound(static_cast<qreal>(defaultResizeBorderThickness) * devicePixelRatio); // The padded border will disappear if DWM composition is disabled.
} else { const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic);
return defaultResizeBorderThickness; if (dpiScale) {
} return qRound(static_cast<qreal>(defaultResizeBorderThickness) * devicePixelRatio);
} else {
return defaultResizeBorderThickness;
} }
} }
} }
case SystemMetric::CaptionHeight: { case SystemMetric::CaptionHeight: {
const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt(); const int result = GetSystemMetrics(SM_CYCAPTION);
if ((captionHeight > 0) && !forceSystemValue) { if (result > 0) {
return qRound(static_cast<qreal>(captionHeight) * scaleFactor); if (dpiScale) {
} else { return result;
const int result = GetSystemMetrics(SM_CYCAPTION);
if (result > 0) {
if (dpiScale) {
return result;
} else {
return qRound(static_cast<qreal>(result) / devicePixelRatio);
}
} else { } else {
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); return qRound(static_cast<qreal>(result) / devicePixelRatio);
if (dpiScale) { }
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio); } else {
} else { qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"));
return kDefaultCaptionHeight; if (dpiScale) {
} return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
return kDefaultCaptionHeight;
} }
} }
} }
case SystemMetric::TitleBarHeight: { case SystemMetric::TitleBarHeight: {
const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt(); const int captionHeight = getSystemMetric(
if ((titleBarHeight > 0) && !forceSystemValue) { window, SystemMetric::CaptionHeight, dpiScale, forceSystemValue);
return qRound(static_cast<qreal>(titleBarHeight) * scaleFactor); const int resizeBorderThickness = getSystemMetric(
} else { window, SystemMetric::ResizeBorderThickness, dpiScale, forceSystemValue);
const int captionHeight = getSystemMetric(window,SystemMetric::CaptionHeight, return (((window->windowState() == Qt::WindowMaximized)
dpiScale, forceSystemValue); || (window->windowState() == Qt::WindowFullScreen))
const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness, ? captionHeight : (captionHeight + resizeBorderThickness));
dpiScale, forceSystemValue);
return (((window->windowState() == Qt::WindowMaximized)
|| (window->windowState() == Qt::WindowFullScreen))
? captionHeight : (captionHeight + resizeBorderThickness));
}
} }
} }
return 0; return 0;