Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-10-15 10:41:35 +08:00
parent 6c6aada2ba
commit b736936a8a
2 changed files with 87 additions and 71 deletions

View File

@ -44,10 +44,6 @@
namespace {
#ifndef Q_OS_WINDOWS
FramelessHelper framelessHelper;
#endif
void reportError()
{
qFatal("Only top level QWidgets and QWindows are accepted.");
@ -89,8 +85,19 @@ void *getRawHandleFromWindow(QObject *window)
}
#endif
#ifndef Q_OS_WINDOWS
using FLWM_CORE_DATA = struct _FLWM_CORE_DATA
{
FramelessHelper framelessHelper;
};
#endif
} // namespace
#ifndef Q_OS_WINDOWS
Q_GLOBAL_STATIC(FLWM_CORE_DATA, coreData)
#endif
FramelessWindowsManager::FramelessWindowsManager() {}
void FramelessWindowsManager::addWindow(QObject *window, const bool center)
@ -99,7 +106,7 @@ void FramelessWindowsManager::addWindow(QObject *window, const bool center)
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::addFramelessWindow(window);
#else
framelessHelper.removeWindowFrame(window);
coreData()->framelessHelper.removeWindowFrame(window);
#endif
if (center) {
moveWindowToDesktopCenter(window);
@ -194,7 +201,7 @@ void FramelessWindowsManager::addIgnoreArea(QObject *window, const QRect &area)
data->ignoreAreas.append(area);
}
#else
framelessHelper.addIgnoreArea(window, area);
coreData()->framelessHelper.addIgnoreArea(window, area);
#endif
}
@ -207,7 +214,7 @@ void FramelessWindowsManager::addDraggableArea(QObject *window, const QRect &are
data->draggableAreas.append(area);
}
#else
framelessHelper.addDraggableArea(window, area);
coreData()->framelessHelper.addDraggableArea(window, area);
#endif
}
@ -220,7 +227,7 @@ void FramelessWindowsManager::addIgnoreObject(QObject *window, QObject *object)
data->ignoreObjects.append(object);
}
#else
framelessHelper.addIgnoreObject(window, object);
coreData()->framelessHelper.addIgnoreObject(window, object);
#endif
}
@ -233,7 +240,7 @@ void FramelessWindowsManager::addDraggableObject(QObject *window, QObject *objec
data->draggableObjects.append(object);
}
#else
framelessHelper.addDraggableObject(window, object);
coreData()->framelessHelper.addDraggableObject(window, object);
#endif
}
@ -245,7 +252,7 @@ int FramelessWindowsManager::getBorderWidth(QObject *window)
WinNativeEventFilter::SystemMetric::BorderWidth);
#else
Q_UNUSED(window)
return framelessHelper.getBorderWidth();
return coreData()->framelessHelper.getBorderWidth();
#endif
}
@ -259,7 +266,7 @@ void FramelessWindowsManager::setBorderWidth(QObject *window, const int value)
}
#else
Q_UNUSED(window)
framelessHelper.setBorderWidth(value);
coreData()->framelessHelper.setBorderWidth(value);
#endif
}
@ -271,7 +278,7 @@ int FramelessWindowsManager::getBorderHeight(QObject *window)
WinNativeEventFilter::SystemMetric::BorderHeight);
#else
Q_UNUSED(window)
return framelessHelper.getBorderHeight();
return coreData()->framelessHelper.getBorderHeight();
#endif
}
@ -285,7 +292,7 @@ void FramelessWindowsManager::setBorderHeight(QObject *window, const int value)
}
#else
Q_UNUSED(window)
framelessHelper.setBorderHeight(value);
coreData()->framelessHelper.setBorderHeight(value);
#endif
}
@ -297,7 +304,7 @@ int FramelessWindowsManager::getTitleBarHeight(QObject *window)
WinNativeEventFilter::SystemMetric::TitleBarHeight);
#else
Q_UNUSED(window)
return framelessHelper.getTitleBarHeight();
return coreData()->framelessHelper.getTitleBarHeight();
#endif
}
@ -311,7 +318,7 @@ void FramelessWindowsManager::setTitleBarHeight(QObject *window, const int value
}
#else
Q_UNUSED(window)
framelessHelper.setTitleBarHeight(value);
coreData()->framelessHelper.setTitleBarHeight(value);
#endif
}
@ -322,7 +329,7 @@ bool FramelessWindowsManager::getResizable(QObject *window)
const auto data = WinNativeEventFilter::windowData(window);
return data ? !data->fixedSize : false;
#else
return framelessHelper.getResizable(window);
return coreData()->framelessHelper.getResizable(window);
#endif
}
@ -335,7 +342,7 @@ void FramelessWindowsManager::setResizable(QObject *window, const bool value)
data->fixedSize = !value;
}
#else
framelessHelper.setResizable(window, value);
coreData()->framelessHelper.setResizable(window, value);
#endif
}
@ -436,7 +443,7 @@ bool FramelessWindowsManager::getTitleBarEnabled(QObject *window)
const auto data = WinNativeEventFilter::windowData(window);
return data ? !data->disableTitleBar : false;
#else
return framelessHelper.getTitleBarEnabled(window);
return coreData()->framelessHelper.getTitleBarEnabled(window);
#endif
}
@ -449,6 +456,6 @@ void FramelessWindowsManager::setTitleBarEnabled(QObject *window, const bool val
data->disableTitleBar = !value;
}
#else
framelessHelper.setTitleBarEnabled(window, value);
coreData()->framelessHelper.setTitleBarEnabled(window, value);
#endif
}

View File

@ -1037,40 +1037,6 @@ HWND getHWNDFromQObject(QObject *object)
return reinterpret_cast<HWND>(wid);
}
// The standard values of border width, border height and title bar height
// when DPI is 96.
const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30;
int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1;
// The thickness of an auto-hide taskbar in pixels.
const int kAutoHideTaskbarThicknessPx = 2;
const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx;
QScopedPointer<WinNativeEventFilter> m_instance;
QList<HWND> m_framelessWindows = {};
void install()
{
qCoreAppFixup();
if (m_instance.isNull()) {
m_instance.reset(new WinNativeEventFilter);
qApp->installNativeEventFilter(m_instance.data());
}
}
void uninstall()
{
if (!m_instance.isNull()) {
qApp->removeNativeEventFilter(m_instance.data());
m_instance.reset();
}
if (!m_framelessWindows.isEmpty()) {
m_framelessWindows.clear();
}
}
void updateQtFrame_internal(const HWND handle)
{
Q_ASSERT(handle);
@ -1138,13 +1104,54 @@ QString getCurrentScreenSerialNumber(const HWND handle)
currentScreen = window->screen();
}
}
return currentScreen ? currentScreen->serialNumber().toUpper() : QString();
if (currentScreen) {
const QString sn = currentScreen->serialNumber().toUpper();
return sn.isEmpty() ? currentScreen->name().toUpper() : sn;
}
}
return {};
}
// The standard values of border width, border height and title bar height
// when DPI is 96.
const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30;
// The thickness of an auto-hide taskbar in pixels.
const int kAutoHideTaskbarThicknessPx = 2;
const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx;
// Internal data structure.
using WNEF_CORE_DATA = struct _WNEF_CORE_DATA
{
int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1;
QScopedPointer<WinNativeEventFilter> m_instance;
QList<HWND> m_framelessWindows = {};
};
} // namespace
Q_GLOBAL_STATIC(WNEF_CORE_DATA, coreData)
static void install()
{
qCoreAppFixup();
if (coreData()->m_instance.isNull()) {
coreData()->m_instance.reset(new WinNativeEventFilter);
qApp->installNativeEventFilter(coreData()->m_instance.data());
}
}
static void uninstall()
{
if (!coreData()->m_instance.isNull()) {
qApp->removeNativeEventFilter(coreData()->m_instance.data());
coreData()->m_instance.reset();
}
if (!coreData()->m_framelessWindows.isEmpty()) {
coreData()->m_framelessWindows.clear();
}
}
WinNativeEventFilter::WinNativeEventFilter()
{
ResolveWin32APIs();
@ -1165,8 +1172,9 @@ void WinNativeEventFilter::addFramelessWindow(void *window,
ResolveWin32APIs();
qCoreAppFixup();
const auto hwnd = reinterpret_cast<HWND>(window);
if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) && !m_framelessWindows.contains(hwnd)) {
m_framelessWindows.append(hwnd);
if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)
&& !coreData()->m_framelessWindows.contains(hwnd)) {
coreData()->m_framelessWindows.append(hwnd);
createUserData(hwnd, data);
install();
updateQtFrame_internal(hwnd);
@ -1195,8 +1203,8 @@ void WinNativeEventFilter::removeFramelessWindow(void *window)
{
Q_ASSERT(window);
const auto hwnd = reinterpret_cast<HWND>(window);
if (m_framelessWindows.contains(hwnd)) {
m_framelessWindows.removeAll(hwnd);
if (coreData()->m_framelessWindows.contains(hwnd)) {
coreData()->m_framelessWindows.removeAll(hwnd);
}
}
@ -1208,8 +1216,8 @@ void WinNativeEventFilter::removeFramelessWindow(QObject *window)
void WinNativeEventFilter::clearFramelessWindows()
{
if (!m_framelessWindows.isEmpty()) {
m_framelessWindows.clear();
if (!coreData()->m_framelessWindows.isEmpty()) {
coreData()->m_framelessWindows.clear();
}
}
@ -1246,12 +1254,12 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
// Anyway, we should skip it in this case.
return false;
}
if (m_framelessWindows.isEmpty()) {
if (coreData()->m_framelessWindows.isEmpty()) {
// Only top level windows can be frameless.
if (!IsTopLevel(msg->hwnd)) {
return false;
}
} else if (!m_framelessWindows.contains(msg->hwnd)) {
} else if (!coreData()->m_framelessWindows.contains(msg->hwnd)) {
return false;
}
const auto data = reinterpret_cast<WINDOWDATA *>(
@ -1287,6 +1295,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
data->initialized = true;
// Record the current screen.
data->currentScreen = getCurrentScreenSerialNumber(msg->hwnd);
Q_ASSERT(!data->currentScreen.isEmpty());
// Don't restore the window styles to default when you are
// developing Qt Quick applications because the QWindow
// will disappear once you do it. However, Qt Widgets applications
@ -2045,17 +2054,17 @@ WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::windowData(QObject *wind
void WinNativeEventFilter::setBorderWidth(const int bw)
{
m_borderWidth = bw;
coreData()->m_borderWidth = bw;
}
void WinNativeEventFilter::setBorderHeight(const int bh)
{
m_borderHeight = bh;
coreData()->m_borderHeight = bh;
}
void WinNativeEventFilter::setTitleBarHeight(const int tbh)
{
m_titleBarHeight = tbh;
coreData()->m_titleBarHeight = tbh;
}
void WinNativeEventFilter::updateWindow(void *handle,
@ -2145,20 +2154,20 @@ int WinNativeEventFilter::getSystemMetric(void *handle,
}
switch (metric) {
case SystemMetric::BorderWidth:
if (m_borderWidth > 0) {
return qRound(m_borderWidth * dpr);
if (coreData()->m_borderWidth > 0) {
return qRound(coreData()->m_borderWidth * dpr);
} else {
return qRound(m_defaultBorderWidth * dpr);
}
case SystemMetric::BorderHeight:
if (m_borderHeight > 0) {
return qRound(m_borderHeight * dpr);
if (coreData()->m_borderHeight > 0) {
return qRound(coreData()->m_borderHeight * dpr);
} else {
return qRound(m_defaultBorderHeight * dpr);
}
case SystemMetric::TitleBarHeight:
if (m_titleBarHeight > 0) {
return qRound(m_titleBarHeight * dpr);
if (coreData()->m_titleBarHeight > 0) {
return qRound(coreData()->m_titleBarHeight * dpr);
} else {
return qRound(m_defaultTitleBarHeight * dpr);
}