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_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<qreal>(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<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)));

View File

@ -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; }

View File

@ -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<qreal>(resizeBorderThickness) * scaleFactor);
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultResizeBorderThickness) * devicePixelRatio);
} else {
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(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<qreal>(captionHeight) * scaleFactor);
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(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<qreal>(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;

View File

@ -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<NSWindow*> gFlsWindows;
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);
switch (metric) {
case SystemMetric::ResizeBorderThickness: {
const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt();
if ((resizeBorderThickness > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(resizeBorderThickness) * scaleFactor);
} else {
const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
if (result > 0) {
if (dpiScale) {
return result;
} else {
return qRound(static_cast<qreal>(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<qreal>(defaultResizeBorderThickness) * devicePixelRatio);
} else {
return defaultResizeBorderThickness;
}
return qRound(static_cast<qreal>(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<qreal>(defaultResizeBorderThickness) * devicePixelRatio);
} else {
return defaultResizeBorderThickness;
}
}
}
case SystemMetric::CaptionHeight: {
const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt();
if ((captionHeight > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(captionHeight) * scaleFactor);
} else {
const int result = GetSystemMetrics(SM_CYCAPTION);
if (result > 0) {
if (dpiScale) {
return result;
} else {
return qRound(static_cast<qreal>(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<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
return kDefaultCaptionHeight;
}
return qRound(static_cast<qreal>(result) / devicePixelRatio);
}
} else {
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"));
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
return kDefaultCaptionHeight;
}
}
}
case SystemMetric::TitleBarHeight: {
const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt();
if ((titleBarHeight > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(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;