adapt to latest qtbase

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-09-24 17:57:38 +08:00
parent 95449f140f
commit c914992aa4
7 changed files with 81 additions and 8 deletions

View File

@ -2,6 +2,10 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "dialog.h"
#include <QtCore/qsettings.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qlineedit.h>
#include <QtWidgets/qcheckbox.h>
@ -19,6 +23,17 @@ FRAMELESSHELPER_USE_NAMESPACE
using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT2(IniKeyPath, "Window/Geometry")
[[nodiscard]] static inline QSettings *appConfigFile()
{
const QFileInfo fileInfo(QCoreApplication::applicationFilePath());
const QString iniFileName = fileInfo.completeBaseName() + FRAMELESSHELPER_STRING_LITERAL(".ini");
const QString iniFilePath = fileInfo.canonicalPath() + QDir::separator() + iniFileName;
const auto settings = new QSettings(iniFilePath, QSettings::IniFormat);
return settings;
}
Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
{
setupUi();
@ -26,6 +41,13 @@ Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
Dialog::~Dialog() = default;
void Dialog::closeEvent(QCloseEvent *event)
{
const QScopedPointer<QSettings> settings(appConfigFile());
settings->setValue(kIniKeyPath, saveGeometry());
FramelessDialog::closeEvent(event);
}
void Dialog::setupUi()
{
setWindowTitle(tr("Qt Dialog demo"));
@ -109,6 +131,17 @@ void Dialog::setupUi()
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
// Special hack to disable the overriding of the mouse cursor, it's totally different
// with making the window un-resizable, so we don't use setFixedSize() here.
// with making the window un-resizable: we still want the window be able to resize
// programatically, but we also want the user not able to resize the window manually.
// So apparently we can't use QWidget::setFixedWidth/Height/Size() here.
FramelessWidgetsHelperPrivate::get(helper)->setProperty(FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_OVERRIDE_CURSOR"), true);
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QScopedPointer<QSettings> settings(appConfigFile());
const QByteArray data = settings->value(kIniKeyPath).toByteArray();
if (data.isEmpty()) {
helper->moveWindowToDesktopCenter();
} else {
restoreGeometry(data);
}
});
}

View File

@ -27,6 +27,9 @@ public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog() override;
protected:
void closeEvent(QCloseEvent *event) override;
private:
void setupUi();

View File

@ -135,6 +135,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
if (!object || !event) {
return false;
}
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
// First detect whether we got a theme change event or not, if so,
// inform the user the system theme has changed.
if (Utils::isThemeChangeEvent(event)) {
@ -146,6 +147,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
}
return QObject::eventFilter(object, event);
}
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
// We are only interested in events that are dispatched to top level windows.
if (!object->isWindowType()) {
return QObject::eventFilter(object, event);

View File

@ -1208,9 +1208,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// Sometimes the FramelessManager instance may be destroyed already.
if (FramelessManager * const manager = FramelessManager::instance()) {
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
if (systemThemeChanged) {
managerPriv->notifySystemThemeHasChangedOrNot();
}
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
if (wallpaperChanged) {
managerPriv->notifyWallpaperHasChangedOrNot();
}

View File

@ -28,6 +28,10 @@
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
#include <QtGui/qfontdatabase.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
# include <QtGui/qguiapplication.h>
# include <QtGui/qstylehints.h>
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
#include "framelesshelper_qt.h"
#include "framelessconfig_p.h"
#include "utils.h"
@ -346,6 +350,13 @@ void FramelessManagerPrivate::initialize()
#endif
m_wallpaper = Utils::getWallpaperFilePath();
m_wallpaperAspectStyle = Utils::getWallpaperAspectStyle();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
QStyleHints * const styleHints = QGuiApplication::styleHints();
connect(styleHints, &QStyleHints::appearanceChanged, this, [this](const Qt::Appearance appearance){
Q_UNUSED(appearance);
notifySystemThemeHasChangedOrNot();
});
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
}
FramelessManager::FramelessManager(QObject *parent) :

View File

@ -27,7 +27,9 @@
#include <QtGui/qwindow.h>
#include <QtGui/qscreen.h>
#include <QtGui/qguiapplication.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
# include <QtGui/qstylehints.h>
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
# include <QtGui/qpa/qplatformtheme.h>
# include <QtGui/private/qguiapplication_p.h>
#endif
@ -263,7 +265,9 @@ QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button
bool Utils::shouldAppsUseDarkMode()
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
return (QGuiApplication::styleHints()->appearance() == Qt::Appearance::Dark);
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
if (const QPlatformTheme * const theme = QGuiApplicationPrivate::platformTheme()) {
return (theme->appearance() == QPlatformTheme::Appearance::Dark);
}

View File

@ -43,6 +43,7 @@
#include "sysapiloader_p.h"
#include "registrykey_p.h"
#include <uxtheme.h>
#include <d2d1.h>
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
@ -165,6 +166,9 @@ FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
FRAMELESSHELPER_STRING_CONSTANT(CreateDCW)
FRAMELESSHELPER_STRING_CONSTANT(DeleteDC)
FRAMELESSHELPER_STRING_CONSTANT(d2d1)
FRAMELESSHELPER_STRING_CONSTANT(D2D1CreateFactory)
FRAMELESSHELPER_STRING_CONSTANT(ReloadSystemMetrics)
struct Win32UtilsHelperData
{
@ -843,7 +847,9 @@ bool Utils::isHighContrastModeEnabled()
quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
{
// GetDesktopWindow(): The desktop window will always be in the primary monitor.
if (const HMONITOR hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY)) {
// GetDpiForMonitor() is only available on Windows 8 and onwards.
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
UINT dpiX = 0, dpiY = 0;
const HRESULT hr = API_CALL_FUNCTION(GetDpiForMonitor, hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
@ -853,6 +859,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
WARNING << __getSystemErrorMessage(kGetDpiForMonitor, hr);
}
}
// GetScaleFactorForMonitor() is only available on Windows 8 and onwards.
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
DEVICE_SCALE_FACTOR factor = DEVICE_SCALE_FACTOR_INVALID;
const HRESULT hr = API_CALL_FUNCTION(GetScaleFactorForMonitor, hMonitor, &factor);
@ -862,6 +869,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr);
}
}
// This solution is supported on Windows 2000 and onwards.
MONITORINFOEXW monitorInfo;
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
@ -891,13 +899,14 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
WARNING << getSystemErrorMessage(kMonitorFromWindow);
}
#if 0 // The above solutions should be sufficient enough, no need to pull in a new dependency.
// Using Direct2D to get the primary monitor's DPI is only available on Windows 7
// and onwards, but it has been marked as deprecated by Microsoft.
if (API_D2D_AVAILABLE(D2D1CreateFactory)) {
using D2D1CreateFactoryPtr =
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
const auto pD2D1CreateFactory =
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kD2D1CreateFactory));
auto d2dFactory = CComPtr<ID2D1Factory>(nullptr);
ID2D1Factory *d2dFactory = nullptr;
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
nullptr, reinterpret_cast<void **>(&d2dFactory));
if (SUCCEEDED(hr)) {
@ -919,9 +928,14 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
} else {
WARNING << __getSystemErrorMessage(kD2D1CreateFactory, hr);
}
if (d2dFactory) {
d2dFactory->Release();
d2dFactory = nullptr;
}
}
#endif
// Our last hope to get the DPI of the primary monitor, if all the above
// solutions failed, however, it won't happen in most cases.
if (const HDC hdc = GetDC(nullptr)) {
bool valid = false;
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
@ -940,6 +954,9 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
} else {
WARNING << getSystemErrorMessage(kGetDC);
}
// We should never go here, but let's make it extra safe. Just assume we
// are not scaled (96 DPI) if we really can't get the real DPI.
return USER_DEFAULT_SCREEN_DPI;
}
@ -1124,11 +1141,12 @@ void Utils::maybeFixupQtInternals(const WId windowId)
// necessary window styles in some cases (caused by misconfigured setWindowFlag(s) calls)
// and this will also break the normal functionalities for our windows, so we do the
// correction here unconditionally.
static constexpr const DWORD badWindowStyle = WS_POPUP;
static constexpr const DWORD goodWindowStyle =
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME);
if (!(windowStyle & goodWindowStyle)) {
if ((windowStyle & badWindowStyle) || !(windowStyle & goodWindowStyle)) {
SetLastError(ERROR_SUCCESS);
if (SetWindowLongPtrW(hwnd, GWL_STYLE, ((windowStyle & ~WS_POPUP) | goodWindowStyle)) == 0) {
if (SetWindowLongPtrW(hwnd, GWL_STYLE, ((windowStyle & ~badWindowStyle) | goodWindowStyle)) == 0) {
WARNING << getSystemErrorMessage(kSetWindowLongPtrW);
} else {
shouldUpdateFrame = true;