forked from github_mirror/framelesshelper
adapt to latest qtbase
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
95449f140f
commit
c914992aa4
|
@ -2,6 +2,10 @@
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
#include "dialog.h"
|
#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/qlabel.h>
|
||||||
#include <QtWidgets/qlineedit.h>
|
#include <QtWidgets/qlineedit.h>
|
||||||
#include <QtWidgets/qcheckbox.h>
|
#include <QtWidgets/qcheckbox.h>
|
||||||
|
@ -19,6 +23,17 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
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)
|
Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
|
||||||
{
|
{
|
||||||
setupUi();
|
setupUi();
|
||||||
|
@ -26,6 +41,13 @@ Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
|
||||||
|
|
||||||
Dialog::~Dialog() = default;
|
Dialog::~Dialog() = default;
|
||||||
|
|
||||||
|
void Dialog::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
const QScopedPointer<QSettings> settings(appConfigFile());
|
||||||
|
settings->setValue(kIniKeyPath, saveGeometry());
|
||||||
|
FramelessDialog::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void Dialog::setupUi()
|
void Dialog::setupUi()
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Qt Dialog demo"));
|
setWindowTitle(tr("Qt Dialog demo"));
|
||||||
|
@ -109,6 +131,17 @@ void Dialog::setupUi()
|
||||||
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
|
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
|
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
|
||||||
// Special hack to disable the overriding of the mouse cursor, it's totally different
|
// 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);
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ public:
|
||||||
explicit Dialog(QWidget *parent = nullptr);
|
explicit Dialog(QWidget *parent = nullptr);
|
||||||
~Dialog() override;
|
~Dialog() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUi();
|
void setupUi();
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
if (!object || !event) {
|
if (!object || !event) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
||||||
// First detect whether we got a theme change event or not, if so,
|
// First detect whether we got a theme change event or not, if so,
|
||||||
// inform the user the system theme has changed.
|
// inform the user the system theme has changed.
|
||||||
if (Utils::isThemeChangeEvent(event)) {
|
if (Utils::isThemeChangeEvent(event)) {
|
||||||
|
@ -146,6 +147,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
}
|
}
|
||||||
return QObject::eventFilter(object, 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.
|
// We are only interested in events that are dispatched to top level windows.
|
||||||
if (!object->isWindowType()) {
|
if (!object->isWindowType()) {
|
||||||
return QObject::eventFilter(object, event);
|
return QObject::eventFilter(object, event);
|
||||||
|
|
|
@ -1208,9 +1208,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// Sometimes the FramelessManager instance may be destroyed already.
|
// Sometimes the FramelessManager instance may be destroyed already.
|
||||||
if (FramelessManager * const manager = FramelessManager::instance()) {
|
if (FramelessManager * const manager = FramelessManager::instance()) {
|
||||||
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
|
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
||||||
if (systemThemeChanged) {
|
if (systemThemeChanged) {
|
||||||
managerPriv->notifySystemThemeHasChangedOrNot();
|
managerPriv->notifySystemThemeHasChangedOrNot();
|
||||||
}
|
}
|
||||||
|
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
||||||
if (wallpaperChanged) {
|
if (wallpaperChanged) {
|
||||||
managerPriv->notifyWallpaperHasChangedOrNot();
|
managerPriv->notifyWallpaperHasChangedOrNot();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
#include <QtGui/qscreen.h>
|
#include <QtGui/qscreen.h>
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <QtGui/qfontdatabase.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 "framelesshelper_qt.h"
|
||||||
#include "framelessconfig_p.h"
|
#include "framelessconfig_p.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -346,6 +350,13 @@ void FramelessManagerPrivate::initialize()
|
||||||
#endif
|
#endif
|
||||||
m_wallpaper = Utils::getWallpaperFilePath();
|
m_wallpaper = Utils::getWallpaperFilePath();
|
||||||
m_wallpaperAspectStyle = Utils::getWallpaperAspectStyle();
|
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) :
|
FramelessManager::FramelessManager(QObject *parent) :
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <QtGui/qscreen.h>
|
#include <QtGui/qscreen.h>
|
||||||
#include <QtGui/qguiapplication.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/qpa/qplatformtheme.h>
|
||||||
# include <QtGui/private/qguiapplication_p.h>
|
# include <QtGui/private/qguiapplication_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -263,7 +265,9 @@ QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button
|
||||||
|
|
||||||
bool Utils::shouldAppsUseDarkMode()
|
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()) {
|
if (const QPlatformTheme * const theme = QGuiApplicationPrivate::platformTheme()) {
|
||||||
return (theme->appearance() == QPlatformTheme::Appearance::Dark);
|
return (theme->appearance() == QPlatformTheme::Appearance::Dark);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "sysapiloader_p.h"
|
#include "sysapiloader_p.h"
|
||||||
#include "registrykey_p.h"
|
#include "registrykey_p.h"
|
||||||
#include <uxtheme.h>
|
#include <uxtheme.h>
|
||||||
|
#include <d2d1.h>
|
||||||
|
|
||||||
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
|
||||||
SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
|
SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
|
||||||
|
@ -165,6 +166,9 @@ FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
|
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(CreateDCW)
|
FRAMELESSHELPER_STRING_CONSTANT(CreateDCW)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(DeleteDC)
|
FRAMELESSHELPER_STRING_CONSTANT(DeleteDC)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(d2d1)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(D2D1CreateFactory)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(ReloadSystemMetrics)
|
||||||
|
|
||||||
struct Win32UtilsHelperData
|
struct Win32UtilsHelperData
|
||||||
{
|
{
|
||||||
|
@ -843,7 +847,9 @@ bool Utils::isHighContrastModeEnabled()
|
||||||
|
|
||||||
quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
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)) {
|
if (const HMONITOR hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY)) {
|
||||||
|
// GetDpiForMonitor() is only available on Windows 8 and onwards.
|
||||||
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
|
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
|
||||||
UINT dpiX = 0, dpiY = 0;
|
UINT dpiX = 0, dpiY = 0;
|
||||||
const HRESULT hr = API_CALL_FUNCTION(GetDpiForMonitor, hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
|
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);
|
WARNING << __getSystemErrorMessage(kGetDpiForMonitor, hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// GetScaleFactorForMonitor() is only available on Windows 8 and onwards.
|
||||||
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
|
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
|
||||||
DEVICE_SCALE_FACTOR factor = DEVICE_SCALE_FACTOR_INVALID;
|
DEVICE_SCALE_FACTOR factor = DEVICE_SCALE_FACTOR_INVALID;
|
||||||
const HRESULT hr = API_CALL_FUNCTION(GetScaleFactorForMonitor, hMonitor, &factor);
|
const HRESULT hr = API_CALL_FUNCTION(GetScaleFactorForMonitor, hMonitor, &factor);
|
||||||
|
@ -862,6 +869,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
||||||
WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr);
|
WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// This solution is supported on Windows 2000 and onwards.
|
||||||
MONITORINFOEXW monitorInfo;
|
MONITORINFOEXW monitorInfo;
|
||||||
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
||||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||||
|
@ -891,13 +899,14 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
||||||
WARNING << getSystemErrorMessage(kMonitorFromWindow);
|
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)) {
|
if (API_D2D_AVAILABLE(D2D1CreateFactory)) {
|
||||||
using D2D1CreateFactoryPtr =
|
using D2D1CreateFactoryPtr =
|
||||||
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
|
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
|
||||||
const auto pD2D1CreateFactory =
|
const auto pD2D1CreateFactory =
|
||||||
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kD2D1CreateFactory));
|
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),
|
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
|
||||||
nullptr, reinterpret_cast<void **>(&d2dFactory));
|
nullptr, reinterpret_cast<void **>(&d2dFactory));
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
@ -919,9 +928,14 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
||||||
} else {
|
} else {
|
||||||
WARNING << __getSystemErrorMessage(kD2D1CreateFactory, hr);
|
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)) {
|
if (const HDC hdc = GetDC(nullptr)) {
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||||
|
@ -940,6 +954,9 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
||||||
} else {
|
} else {
|
||||||
WARNING << getSystemErrorMessage(kGetDC);
|
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;
|
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)
|
// 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
|
// and this will also break the normal functionalities for our windows, so we do the
|
||||||
// correction here unconditionally.
|
// correction here unconditionally.
|
||||||
|
static constexpr const DWORD badWindowStyle = WS_POPUP;
|
||||||
static constexpr const DWORD goodWindowStyle =
|
static constexpr const DWORD goodWindowStyle =
|
||||||
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME);
|
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME);
|
||||||
if (!(windowStyle & goodWindowStyle)) {
|
if ((windowStyle & badWindowStyle) || !(windowStyle & goodWindowStyle)) {
|
||||||
SetLastError(ERROR_SUCCESS);
|
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);
|
WARNING << getSystemErrorMessage(kSetWindowLongPtrW);
|
||||||
} else {
|
} else {
|
||||||
shouldUpdateFrame = true;
|
shouldUpdateFrame = true;
|
||||||
|
|
Loading…
Reference in New Issue