Example: special case for Win11
1. On Win11 we don't need to paint the frame border, the OS will always draw one for us. 2. Fix the wrong coordinate of the right and bottom frame border of the widget example. 3. Improve the Qt Quick example. 4. Correctly detect the OS version when building against Qt below 5.9. 5. Other minor tweaks. Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
7ddde978e8
commit
e85e3f891e
|
@ -121,7 +121,7 @@ void MainWindow::changeEvent(QEvent *event)
|
|||
void MainWindow::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QMainWindow::paintEvent(event);
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
if ((windowState() == Qt::WindowNoState) && !Utilities::isWin11OrGreater()) {
|
||||
const int w = width();
|
||||
const int h = height();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
|
|
|
@ -22,11 +22,71 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../../utilities.h"
|
||||
#include "../../framelessquickhelper.h"
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtQml/qqmlapplicationengine.h>
|
||||
#include <QtQuickControls2/qquickstyle.h>
|
||||
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
|
||||
static constexpr const char qtquicknamespace[] = "wangwenx190.Utils";
|
||||
|
||||
class UtilFunctions : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(UtilFunctions)
|
||||
Q_PROPERTY(bool isWindowsHost READ isWindowsHost CONSTANT)
|
||||
Q_PROPERTY(bool isWindows10OrGreater READ isWindows10OrGreater CONSTANT)
|
||||
Q_PROPERTY(bool isWindows11OrGreater READ isWindows11OrGreater CONSTANT)
|
||||
Q_PROPERTY(QColor activeFrameBorderColor READ activeFrameBorderColor CONSTANT)
|
||||
Q_PROPERTY(QColor inactiveFrameBorderColor READ inactiveFrameBorderColor CONSTANT)
|
||||
Q_PROPERTY(qreal frameBorderThickness READ frameBorderThickness CONSTANT)
|
||||
|
||||
public:
|
||||
explicit UtilFunctions(QObject *parent = nullptr) : QObject(parent) {}
|
||||
~UtilFunctions() override = default;
|
||||
|
||||
inline bool isWindowsHost() const {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool isWindows10OrGreater() const {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return Utilities::isWin10OrGreater();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool isWindows11OrGreater() const {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return Utilities::isWin11OrGreater();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline QColor activeFrameBorderColor() const {
|
||||
const ColorizationArea area = Utilities::getColorizationArea();
|
||||
const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder)
|
||||
|| (area == ColorizationArea::All));
|
||||
return (colorizedBorder ? Utilities::getColorizationColor() : Qt::black);
|
||||
}
|
||||
|
||||
inline QColor inactiveFrameBorderColor() const {
|
||||
return Qt::darkGray;
|
||||
}
|
||||
|
||||
inline qreal frameBorderThickness() const {
|
||||
return 1.0;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
|
@ -48,7 +108,12 @@ int main(int argc, char *argv[])
|
|||
QQuickStyle::setStyle(QStringLiteral("Default"));
|
||||
#endif
|
||||
|
||||
qmlRegisterType<FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper)>("wangwenx190.Utils", 1, 0, "FramelessHelper");
|
||||
qmlRegisterSingletonType<UtilFunctions>(qtquicknamespace, 1, 0, "Utils", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
|
||||
Q_UNUSED(engine);
|
||||
Q_UNUSED(scriptEngine);
|
||||
return new UtilFunctions();
|
||||
});
|
||||
qmlRegisterType<FramelessQuickHelper>(qtquicknamespace, 1, 0, "FramelessHelper");
|
||||
|
||||
const QUrl mainQmlUrl(QStringLiteral("qrc:///qml/main.qml"));
|
||||
const QMetaObject::Connection connection = QObject::connect(
|
||||
|
@ -71,3 +136,5 @@ int main(int argc, char *argv[])
|
|||
|
||||
return QGuiApplication::exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
|
|
|
@ -35,7 +35,7 @@ Window {
|
|||
title: qsTr("Hello, World!")
|
||||
color: "#f0f0f0"
|
||||
|
||||
property real _flh_margin: ((window.visibility === Window.Maximized) | (window.visibility === Window.FullScreen)) ? 0.0 : 1.0
|
||||
property real _flh_margin: ((window.visibility === Window.Maximized) || (window.visibility === Window.FullScreen)) ? 0 : Utils.frameBorderThickness
|
||||
property var _win_prev_state: null
|
||||
|
||||
FramelessHelper {
|
||||
|
@ -140,8 +140,9 @@ Window {
|
|||
id: windowFrame
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
visible: !Utils.isWindows11OrGreater
|
||||
border {
|
||||
color: window.active ? "black" : "darkGray"
|
||||
color: window.active ? Utils.activeFrameBorderColor : Utils.inactiveFrameBorderColor
|
||||
width: window._flh_margin
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,18 +136,18 @@ void Widget::changeEvent(QEvent *event)
|
|||
void Widget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
if (!isMaximized() && !isFullScreen()) {
|
||||
const auto w = static_cast<qreal>(width());
|
||||
const auto h = static_cast<qreal>(height());
|
||||
if ((windowState() == Qt::WindowNoState) && !Utilities::isWin11OrGreater()) {
|
||||
const int w = width();
|
||||
const int h = height();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using BorderLines = QList<QLineF>;
|
||||
using BorderLines = QList<QLine>;
|
||||
#else
|
||||
using BorderLines = QVector<QLineF>;
|
||||
using BorderLines = QVector<QLine>;
|
||||
#endif
|
||||
const BorderLines lines = {
|
||||
{0, 0, w, 0},
|
||||
{w, 0, w , h},
|
||||
{w, h, 0, h},
|
||||
{w - 1, 0, w - 1, h},
|
||||
{w, h - 1, 0, h - 1},
|
||||
{0, h, 0, 0}
|
||||
};
|
||||
const ColorizationArea area = Utilities::getColorizationArea();
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace Utilities
|
|||
[[nodiscard]] FRAMELESSHELPER_API bool isWin8OrGreater();
|
||||
[[nodiscard]] FRAMELESSHELPER_API bool isWin8Point1OrGreater();
|
||||
[[nodiscard]] FRAMELESSHELPER_API bool isWin10OrGreater();
|
||||
[[nodiscard]] FRAMELESSHELPER_API bool isWin11OrGreater();
|
||||
[[nodiscard]] FRAMELESSHELPER_API bool isDwmCompositionAvailable();
|
||||
FRAMELESSHELPER_API void triggerFrameChange(const WId winId);
|
||||
FRAMELESSHELPER_API void updateFrameMargins(const WId winId, const bool reset);
|
||||
|
|
|
@ -44,11 +44,23 @@ Q_DECLARE_METATYPE(QMargins)
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
[[nodiscard]] static inline QPointF extractMousePositionFromLParam(const LPARAM lParam)
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
|
||||
[[nodiscard]] static inline bool isWindowsVersionOrGreater(const DWORD dwMajor, const DWORD dwMinor, const DWORD dwBuild)
|
||||
{
|
||||
const POINT nativePos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
return QPointF(static_cast<qreal>(nativePos.x), static_cast<qreal>(nativePos.y));
|
||||
OSVERSIONINFOEXW osvi;
|
||||
SecureZeroMemory(&osvi, sizeof(osvi));
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
osvi.dwMajorVersion = dwMajor;
|
||||
osvi.dwMinorVersion = dwMinor;
|
||||
osvi.dwBuildNumber = dwBuild;
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
const auto op = VER_GREATER_EQUAL;
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, op);
|
||||
return (VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, dwlConditionMask) != FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
[[nodiscard]] static inline bool isWin10RS5OrGreater()
|
||||
{
|
||||
|
@ -57,7 +69,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 17763));
|
||||
#else
|
||||
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
|
||||
static const bool result = isWindowsVersionOrGreater(10, 0, 17763);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -69,7 +81,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 18362));
|
||||
#else
|
||||
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
|
||||
static const bool result = isWindowsVersionOrGreater(10, 0, 18362);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -137,6 +149,18 @@ bool Utilities::isWin10OrGreater()
|
|||
return result;
|
||||
}
|
||||
|
||||
bool Utilities::isWin11OrGreater()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
||||
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11);
|
||||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 22000));
|
||||
#else
|
||||
static const bool result = isWindowsVersionOrGreater(10, 0, 22000);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Utilities::isDwmCompositionAvailable()
|
||||
{
|
||||
// DWM composition is always enabled and can't be disabled since Windows 8.
|
||||
|
@ -454,7 +478,10 @@ bool Utilities::isSystemMenuRequested(const void *data, QPointF *pos)
|
|||
}
|
||||
if (result) {
|
||||
if (pos) {
|
||||
*pos = extractMousePositionFromLParam(msg->lParam);
|
||||
*pos = [msg](){
|
||||
const POINT nativePos = {GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)};
|
||||
return QPointF(static_cast<qreal>(nativePos.x), static_cast<qreal>(nativePos.y));
|
||||
}();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue