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
|
||||
|
||||
#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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ public:
|
|||
explicit Dialog(QWidget *parent = nullptr);
|
||||
~Dialog() override;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) :
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue