Example improvements

Try to fix the frame border issue on high dpi monitors.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-01-10 10:07:26 +08:00
parent 485d9665ea
commit e0c00bce35
5 changed files with 50 additions and 22 deletions

View File

@ -92,7 +92,8 @@ void MainWindow::showEvent(QShowEvent *event)
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->maximizeButton, true); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->maximizeButton, true);
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->closeButton, true); FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->closeButton, true);
FramelessWindowsManager::setHitTestVisible(win, appMainWindow->menubar, true); FramelessWindowsManager::setHitTestVisible(win, appMainWindow->menubar, true);
setContentsMargins(1, 1, 1, 1); const auto margin = static_cast<int>(qRound(frameBorderThickness()));
setContentsMargins(margin, margin, margin, margin);
inited = true; inited = true;
} }
} }
@ -106,7 +107,8 @@ void MainWindow::changeEvent(QEvent *event)
if (isMaximized() || isFullScreen()) { if (isMaximized() || isFullScreen()) {
setContentsMargins(0, 0, 0, 0); setContentsMargins(0, 0, 0, 0);
} else if (!isMinimized()) { } else if (!isMinimized()) {
setContentsMargins(1, 1, 1, 1); const auto margin = static_cast<int>(qRound(frameBorderThickness()));
setContentsMargins(margin, margin, margin, margin);
} }
shouldUpdate = true; shouldUpdate = true;
Q_EMIT windowStateChanged(); Q_EMIT windowStateChanged();
@ -118,21 +120,31 @@ void MainWindow::changeEvent(QEvent *event)
} }
} }
qreal MainWindow::frameBorderThickness() const
{
return (static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId())) / devicePixelRatioF());
}
void MainWindow::paintEvent(QPaintEvent *event) void MainWindow::paintEvent(QPaintEvent *event)
{ {
QMainWindow::paintEvent(event); QMainWindow::paintEvent(event);
if ((windowState() == Qt::WindowNoState) && !Utilities::isWin11OrGreater()) { if ((windowState() == Qt::WindowNoState)
const int w = width(); #ifdef Q_OS_WINDOWS
const int h = height(); && !Utilities::isWin11OrGreater()
#endif
) {
const qreal borderThickness = frameBorderThickness();
const auto w = static_cast<qreal>(width());
const auto h = static_cast<qreal>(height());
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using BorderLines = QList<QLine>; using BorderLines = QList<QLineF>;
#else #else
using BorderLines = QVector<QLine>; using BorderLines = QVector<QLineF>;
#endif #endif
const BorderLines lines = { const BorderLines lines = {
{0, 0, w, 0}, {0, 0, w, 0},
{w - 1, 0, w - 1, h}, {w - borderThickness, 0, w - borderThickness, h},
{w, h - 1, 0, h - 1}, {w, h - borderThickness, 0, h - borderThickness},
{0, h, 0, 0} {0, h, 0, 0}
}; };
QPainter painter(this); QPainter painter(this);
@ -142,7 +154,6 @@ void MainWindow::paintEvent(QPaintEvent *event)
const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder) const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder)
|| (area == ColorizationArea::All)); || (area == ColorizationArea::All));
const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray); const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray);
const auto borderThickness = static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId()));
painter.setPen({borderColor, borderThickness}); painter.setPen({borderColor, borderThickness});
painter.drawLines(lines); painter.drawLines(lines);
painter.restore(); painter.restore();

View File

@ -41,6 +41,9 @@ protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void changeEvent(QEvent *event) override; void changeEvent(QEvent *event) override;
private:
qreal frameBorderThickness() const;
Q_SIGNALS: Q_SIGNALS:
void windowStateChanged(); void windowStateChanged();

View File

@ -35,7 +35,7 @@ Window {
title: qsTr("Hello, World!") title: qsTr("Hello, World!")
color: "#f0f0f0" color: "#f0f0f0"
property real _flh_margin: ((window.visibility === Window.Maximized) || (window.visibility === Window.FullScreen)) ? 0 : Utils.frameBorderThickness property real _flh_margin: ((window.visibility === Window.Maximized) || (window.visibility === Window.FullScreen)) ? 0 : (Utils.frameBorderThickness / Screen.devicePixelRatio)
property var _win_prev_state: null property var _win_prev_state: null
FramelessHelper { FramelessHelper {

View File

@ -102,7 +102,7 @@ void Widget::showEvent(QShowEvent *event)
FramelessWindowsManager::setHitTestVisible(win, m_minimizeButton, true); FramelessWindowsManager::setHitTestVisible(win, m_minimizeButton, true);
FramelessWindowsManager::setHitTestVisible(win, m_maximizeButton, true); FramelessWindowsManager::setHitTestVisible(win, m_maximizeButton, true);
FramelessWindowsManager::setHitTestVisible(win, m_closeButton, true); FramelessWindowsManager::setHitTestVisible(win, m_closeButton, true);
const int margin = Utilities::getWindowVisibleFrameBorderThickness(winId()); const auto margin = static_cast<int>(qRound(frameBorderThickness()));
setContentsMargins(margin, margin, margin, margin); setContentsMargins(margin, margin, margin, margin);
} }
} }
@ -120,8 +120,12 @@ void Widget::changeEvent(QEvent *event)
QWidget::changeEvent(event); QWidget::changeEvent(event);
bool shouldUpdate = false; bool shouldUpdate = false;
if (event->type() == QEvent::WindowStateChange) { if (event->type() == QEvent::WindowStateChange) {
const int margin = ((isMaximized() || isFullScreen()) ? 0 : Utilities::getWindowVisibleFrameBorderThickness(winId())); if (isMaximized() || isFullScreen()) {
setContentsMargins(margin, margin, margin, margin); setContentsMargins(0, 0, 0, 0);
} else if (!isMinimized()) {
const auto margin = static_cast<int>(qRound(frameBorderThickness()));
setContentsMargins(margin, margin, margin, margin);
}
updateSystemButtonIcons(); updateSystemButtonIcons();
updateTitleBarSize(); updateTitleBarSize();
shouldUpdate = true; shouldUpdate = true;
@ -136,25 +140,29 @@ void Widget::changeEvent(QEvent *event)
void Widget::paintEvent(QPaintEvent *event) void Widget::paintEvent(QPaintEvent *event)
{ {
QWidget::paintEvent(event); QWidget::paintEvent(event);
if ((windowState() == Qt::WindowNoState) && !Utilities::isWin11OrGreater()) { if ((windowState() == Qt::WindowNoState)
const int w = width(); #ifdef Q_OS_WINDOWS
const int h = height(); && !Utilities::isWin11OrGreater()
#endif
) {
const qreal borderThickness = frameBorderThickness();
const auto w = static_cast<qreal>(width());
const auto h = static_cast<qreal>(height());
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using BorderLines = QList<QLine>; using BorderLines = QList<QLineF>;
#else #else
using BorderLines = QVector<QLine>; using BorderLines = QVector<QLineF>;
#endif #endif
const BorderLines lines = { const BorderLines lines = {
{0, 0, w, 0}, {0, 0, w, 0},
{w - 1, 0, w - 1, h}, {w - borderThickness, 0, w - borderThickness, h},
{w, h - 1, 0, h - 1}, {w, h - borderThickness, 0, h - borderThickness},
{0, h, 0, 0} {0, h, 0, 0}
}; };
const ColorizationArea area = Utilities::getColorizationArea(); const ColorizationArea area = Utilities::getColorizationArea();
const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder) const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder)
|| (area == ColorizationArea::All)); || (area == ColorizationArea::All));
const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray); const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray);
const auto borderThickness = static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId()));
QPainter painter(this); QPainter painter(this);
painter.save(); painter.save();
painter.setRenderHint(QPainter::Antialiasing, false); painter.setRenderHint(QPainter::Antialiasing, false);
@ -306,6 +314,11 @@ void Widget::updateSystemButtonIcons()
m_closeButton->setIcon(QIcon(QStringLiteral(":/images/button_close_%1.svg").arg(suffix))); m_closeButton->setIcon(QIcon(QStringLiteral(":/images/button_close_%1.svg").arg(suffix)));
} }
qreal Widget::frameBorderThickness() const
{
return (static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId())) / devicePixelRatioF());
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool Widget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) bool Widget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else #else

View File

@ -55,6 +55,7 @@ private:
void updateStyleSheet(); void updateStyleSheet();
void updateTitleBarSize(); void updateTitleBarSize();
void updateSystemButtonIcons(); void updateSystemButtonIcons();
qreal frameBorderThickness() const;
private: private:
QWidget *m_titleBarWidget = nullptr; QWidget *m_titleBarWidget = nullptr;