This commit is contained in:
zhuzichu 2024-10-31 11:32:57 +08:00
parent e771293269
commit 5c63b7b73a
2 changed files with 256 additions and 82 deletions

View File

@ -4,6 +4,7 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QScreen> #include <QScreen>
#include <QDateTime> #include <QDateTime>
#include <optional>
#include "FluTools.h" #include "FluTools.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -13,6 +14,8 @@ static DwmExtendFrameIntoClientAreaFunc pDwmExtendFrameIntoClientArea = nullptr;
static DwmIsCompositionEnabledFunc pDwmIsCompositionEnabled = nullptr; static DwmIsCompositionEnabledFunc pDwmIsCompositionEnabled = nullptr;
static DwmEnableBlurBehindWindowFunc pDwmEnableBlurBehindWindow = nullptr; static DwmEnableBlurBehindWindowFunc pDwmEnableBlurBehindWindow = nullptr;
static SetWindowCompositionAttributeFunc pSetWindowCompositionAttribute = nullptr; static SetWindowCompositionAttributeFunc pSetWindowCompositionAttribute = nullptr;
static GetDpiForWindowFunc pGetDpiForWindow = nullptr;
static GetSystemMetricsForDpiFunc pGetSystemMetricsForDpi = nullptr;
static RTL_OSVERSIONINFOW GetRealOSVersionImpl() { static RTL_OSVERSIONINFOW GetRealOSVersionImpl() {
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
@ -108,30 +111,47 @@ static inline bool initializeFunctionPointers() {
} }
} }
if (!pDwmEnableBlurBehindWindow) { if (!pDwmEnableBlurBehindWindow) {
pDwmEnableBlurBehindWindow = pDwmEnableBlurBehindWindow = reinterpret_cast<DwmEnableBlurBehindWindowFunc>(
reinterpret_cast<DwmEnableBlurBehindWindowFunc>(
GetProcAddress(module, "DwmEnableBlurBehindWindow")); GetProcAddress(module, "DwmEnableBlurBehindWindow"));
if (!pDwmEnableBlurBehindWindow) { if (!pDwmEnableBlurBehindWindow) {
return false; return false;
} }
} }
if (!pSetWindowCompositionAttribute) {
HMODULE user32 = LoadLibraryW(L"user32.dll");
if (!user32) {
return false;
} }
HMODULE user32 = LoadLibraryW(L"user32.dll");
if (module) {
if (!pSetWindowCompositionAttribute) {
pSetWindowCompositionAttribute = reinterpret_cast<SetWindowCompositionAttributeFunc>( pSetWindowCompositionAttribute = reinterpret_cast<SetWindowCompositionAttributeFunc>(
GetProcAddress(user32, "SetWindowCompositionAttribute")); GetProcAddress(user32, "SetWindowCompositionAttribute"));
if (!pSetWindowCompositionAttribute) { if (!pSetWindowCompositionAttribute) {
return false; return false;
} }
} }
if (!pGetDpiForWindow) {
pGetDpiForWindow =
reinterpret_cast<GetDpiForWindowFunc>(GetProcAddress(user32, "GetDpiForWindow"));
if (!pGetDpiForWindow) {
return false;
} }
}
if (!pGetSystemMetricsForDpi) {
pGetSystemMetricsForDpi = reinterpret_cast<GetSystemMetricsForDpiFunc>(
GetProcAddress(user32, "GetSystemMetricsForDpi"));
if (!pGetSystemMetricsForDpi) {
return false;
}
}
}
return true; return true;
} }
static inline bool isCompositionEnabled() { static inline bool isCompositionEnabled() {
if(initializeFunctionPointers()){ if (initializeFunctionPointers()) {
BOOL composition_enabled = false; BOOL composition_enabled = false;
pDwmIsCompositionEnabled(&composition_enabled); pDwmIsCompositionEnabled(&composition_enabled);
return composition_enabled; return composition_enabled;
@ -144,7 +164,7 @@ static inline void setShadow(HWND hwnd) {
if (initializeFunctionPointers()) { if (initializeFunctionPointers()) {
pDwmExtendFrameIntoClientArea(hwnd, &shadow); pDwmExtendFrameIntoClientArea(hwnd, &shadow);
} }
if(isWin7Only()){ if (isWin7Only()) {
SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_DROPSHADOW); SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_DROPSHADOW);
} }
} }
@ -156,6 +176,83 @@ static inline bool setWindowDarkMode(HWND hwnd, const BOOL enable) {
return bool(pDwmSetWindowAttribute(hwnd, 20, &enable, sizeof(BOOL))); return bool(pDwmSetWindowAttribute(hwnd, 20, &enable, sizeof(BOOL)));
} }
static inline std::optional<MONITORINFOEXW> getMonitorForWindow(const HWND hwnd) {
Q_ASSERT(hwnd);
if (!hwnd) {
return std::nullopt;
}
const HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitor) {
return std::nullopt;
}
MONITORINFOEXW monitorInfo;
::SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
if (::GetMonitorInfoW(monitor, &monitorInfo) == FALSE) {
return std::nullopt;
}
return monitorInfo;
};
static inline bool isFullScreen(const HWND hwnd) {
RECT windowRect = {};
if (::GetWindowRect(hwnd, &windowRect) == FALSE) {
return false;
}
const std::optional<MONITORINFOEXW> mi = getMonitorForWindow(hwnd);
if (!mi.has_value()) {
return false;
}
RECT rcMonitor = mi.value().rcMonitor;
return windowRect.top == rcMonitor.top && windowRect.left == rcMonitor.left &&
windowRect.right == rcMonitor.right && windowRect.bottom == rcMonitor.bottom;
}
static inline bool isMaximized(const HWND hwnd) {
WINDOWPLACEMENT wp;
::GetWindowPlacement(hwnd, &wp);
return wp.showCmd == SW_MAXIMIZE;
}
static inline quint32 getDpiForWindow(const HWND hwnd, const bool horizontal) {
if (const UINT dpi = pGetDpiForWindow(hwnd)) {
return dpi;
}
if (const HDC hdc = ::GetDC(hwnd)) {
bool valid = false;
const int dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX);
const int dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY);
if ((dpiX > 0) && (dpiY > 0)) {
valid = true;
}
::ReleaseDC(hwnd, hdc);
if (valid) {
return (horizontal ? dpiX : dpiY);
}
}
return 96;
}
static inline int getSystemMetrics(const HWND hwnd, const int index, const bool horizontal) {
const UINT dpi = getDpiForWindow(hwnd, horizontal);
if (const int result = pGetSystemMetricsForDpi(index, dpi); result > 0) {
return result;
}
return ::GetSystemMetrics(index);
}
static inline quint32 getResizeBorderThickness(const HWND hwnd, const bool horizontal,
const qreal devicePixelRatio) {
auto frame = horizontal ? SM_CXSIZEFRAME : SM_CYSIZEFRAME;
auto result =
getSystemMetrics(hwnd, frame, horizontal) + getSystemMetrics(hwnd, 92, horizontal);
if (result > 0) {
return result;
}
int thickness = isCompositionEnabled() ? 8 : 4;
return qRound(thickness * devicePixelRatio);
}
static inline bool setWindowEffect(HWND hwnd, const QString &key, const bool &enable) { static inline bool setWindowEffect(HWND hwnd, const QString &key, const bool &enable) {
static constexpr const MARGINS extendedMargins = {-1, -1, -1, -1}; static constexpr const MARGINS extendedMargins = {-1, -1, -1, -1};
if (key == QStringLiteral("mica")) { if (key == QStringLiteral("mica")) {
@ -294,7 +391,7 @@ void FluFrameless::componentComplete() {
if (isWin11OrGreater()) { if (isWin11OrGreater()) {
availableEffects({"mica", "mica-alt", "acrylic", "dwm-blur", "normal"}); availableEffects({"mica", "mica-alt", "acrylic", "dwm-blur", "normal"});
} else { } else {
availableEffects({"dwm-blur","normal"}); availableEffects({"dwm-blur", "normal"});
} }
if (!_effect.isEmpty() && _useSystemEffect) { if (!_effect.isEmpty() && _useSystemEffect) {
effective(setWindowEffect(hwnd, _effect, true)); effective(setWindowEffect(hwnd, _effect, true));
@ -336,10 +433,15 @@ void FluFrameless::componentComplete() {
int w = window()->width(); int w = window()->width();
int h = window()->height(); int h = window()->height();
_current = window()->winId(); _current = window()->winId();
window()->setFlags((window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); #ifdef Q_OS_MACOS
if (!_fixSize) { window()->setFlag(Qt::FramelessWindowHint, true);
window()->setFlag(Qt::WindowMaximizeButtonHint); window()->setProperty("__borderWidth", 1);
} #endif
#ifdef Q_OS_LINUX
window()->setFlag(Qt::CustomizeWindowHint, true);
window()->setFlag(Qt::FramelessWindowHint, true);
window()->setProperty("__borderWidth", 1);
#endif
window()->installEventFilter(this); window()->installEventFilter(this);
QGuiApplication::instance()->installNativeEventFilter(this); QGuiApplication::instance()->installNativeEventFilter(this);
if (_maximizeButton) { if (_maximizeButton) {
@ -352,10 +454,11 @@ void FluFrameless::componentComplete() {
setHitTestVisible(_closeButton); setHitTestVisible(_closeButton);
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3)) # if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3))
qWarning()<<"Qt's own frameless bug, currently only exist in 6.5.3, please use other versions"; qWarning()
#endif << "Qt's own frameless bug, currently only exist in 6.5.3, please use other versions";
if(!hwnd){ # endif
if (!hwnd) {
hwnd = reinterpret_cast<HWND>(window()->winId()); hwnd = reinterpret_cast<HWND>(window()->winId());
} }
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE); DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
@ -363,18 +466,24 @@ void FluFrameless::componentComplete() {
style &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU); style &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
# endif # endif
if (_fixSize) { if (_fixSize) {
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);; ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);
;
for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) { for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) {
connect(QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] { connect(
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED); QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] {
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
}); });
} }
} else { } else {
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION); ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
} }
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
connect(window(), &QQuickWindow::screenChanged, this, [hwnd] { connect(window(), &QQuickWindow::screenChanged, this, [hwnd] {
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER); ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED |
SWP_NOOWNERZORDER);
::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); ::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
}); });
if (!window()->property("_hideShadow").toBool()) { if (!window()->property("_hideShadow").toBool()) {
@ -391,13 +500,12 @@ void FluFrameless::componentComplete() {
window()->setMaximumHeight(window()->maximumHeight() + appBarHeight); window()->setMaximumHeight(window()->maximumHeight() + appBarHeight);
} }
window()->resize(QSize(w, h)); window()->resize(QSize(w, h));
connect(this, &FluFrameless::topmostChanged, this, [this] { connect(this, &FluFrameless::topmostChanged, this, [this] { _setWindowTopmost(topmost()); });
_setWindowTopmost(topmost());
});
_setWindowTopmost(topmost()); _setWindowTopmost(topmost());
} }
[[maybe_unused]] bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) { [[maybe_unused]] bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message,
QT_NATIVE_EVENT_RESULT_TYPE *result) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if ((eventType != qtNativeEventType()) || !message) { if ((eventType != qtNativeEventType()) || !message) {
return false; return false;
@ -418,19 +526,71 @@ void FluFrameless::componentComplete() {
auto *wp = reinterpret_cast<WINDOWPOS *>(lParam); auto *wp = reinterpret_cast<WINDOWPOS *>(lParam);
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) { if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) {
wp->flags |= SWP_NOCOPYBITS; wp->flags |= SWP_NOCOPYBITS;
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(::DefWindowProcW(hwnd, uMsg, wParam, lParam)); *result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(
::DefWindowProcW(hwnd, uMsg, wParam, lParam));
return true; return true;
} }
return false; return false;
} else if (uMsg == WM_NCCALCSIZE && wParam == TRUE) { } else if (uMsg == WM_NCCALCSIZE && wParam == TRUE) {
bool isMaximum = ::IsZoomed(hwnd); const auto clientRect =
if (isMaximum) { ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam)
window()->setProperty("__margins",7); : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
}else{ bool isMax = ::isMaximized(hwnd);
window()->setProperty("__margins",0); bool isFull = ::isFullScreen(hwnd);
if (isMax && !isFull) {
auto ty = getResizeBorderThickness(hwnd, false, window()->devicePixelRatio());
clientRect->top += ty;
clientRect->bottom -= ty;
auto tx = getResizeBorderThickness(hwnd, true, window()->devicePixelRatio());
clientRect->left += tx;
clientRect->right -= tx;
} }
_setMaximizeHovered(false); if (isMax || isFull) {
*result = WVR_REDRAW; APPBARDATA abd;
SecureZeroMemory(&abd, sizeof(abd));
abd.cbSize = sizeof(abd);
const UINT taskbarState = ::SHAppBarMessage(ABM_GETSTATE, &abd);
if (taskbarState & ABS_AUTOHIDE) {
bool top = false, bottom = false, left = false, right = false;
int edge = -1;
APPBARDATA abd2;
SecureZeroMemory(&abd2, sizeof(abd2));
abd2.cbSize = sizeof(abd2);
abd2.hWnd = ::FindWindowW(L"Shell_TrayWnd", nullptr);
if (abd2.hWnd) {
const HMONITOR windowMonitor =
::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (windowMonitor) {
const HMONITOR taskbarMonitor =
::MonitorFromWindow(abd2.hWnd, MONITOR_DEFAULTTOPRIMARY);
if (taskbarMonitor) {
if (taskbarMonitor == windowMonitor) {
::SHAppBarMessage(ABM_GETTASKBARPOS, &abd2);
edge = abd2.uEdge;
}
}
}
}
top = (edge == ABE_TOP);
bottom = (edge == ABE_BOTTOM);
left = (edge == ABE_LEFT);
right = (edge == ABE_RIGHT);
if (top) {
clientRect->top += 1;
} else if (bottom) {
clientRect->bottom -= 1;
} else if (left) {
clientRect->left += 1;
} else if (right) {
clientRect->right -= 1;
} else {
clientRect->bottom -= 1;
}
} else {
clientRect->bottom += 1;
}
}
*result = 0;
return true; return true;
} else if (uMsg == WM_NCHITTEST) { } else if (uMsg == WM_NCHITTEST) {
if (_isWindows11OrGreater) { if (_isWindows11OrGreater) {
@ -486,24 +646,29 @@ void FluFrameless::componentComplete() {
*result = HTCLIENT; *result = HTCLIENT;
return true; return true;
} else if (uMsg == WM_NCPAINT) { } else if (uMsg == WM_NCPAINT) {
*result = FALSE; if (isCompositionEnabled() && !this->_isFullScreen()) {
return false;
} else if (uMsg == WM_NCACTIVATE) {
*result = TRUE;
if (effective() || (!effect().isEmpty() && _currentEffect!="normal")) {
return false; return false;
} }
*result = FALSE;
return true;
} else if (uMsg == WM_NCACTIVATE) {
if (isCompositionEnabled()) {
return false;
}
*result = true;
return true; return true;
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) { } else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) {
if (_hitMaximizeButton()) { if (_hitMaximizeButton()) {
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(),
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(_maximizeButton, &event); QGuiApplication::sendEvent(_maximizeButton, &event);
_setMaximizePressed(true); _setMaximizePressed(true);
return true; return true;
} }
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP)) { } else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP)) {
if (_hitMaximizeButton()) { if (_hitMaximizeButton()) {
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(),
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(_maximizeButton, &event); QGuiApplication::sendEvent(_maximizeButton, &event);
_setMaximizePressed(false); _setMaximizePressed(false);
return true; return true;
@ -558,7 +723,8 @@ void FluFrameless::_showSystemMenu(QPoint point) {
return; return;
} }
const QPoint origin = screen->geometry().topLeft(); const QPoint origin = screen->geometry().topLeft();
auto nativePos = QPointF(QPointF(point - origin) * window()->devicePixelRatio()).toPoint() + origin; auto nativePos =
QPointF(QPointF(point - origin) * window()->devicePixelRatio()).toPoint() + origin;
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
auto hMenu = ::GetSystemMenu(hwnd, FALSE); auto hMenu = ::GetSystemMenu(hwnd, FALSE);
if (_isMaximized() || _isFullScreen()) { if (_isMaximized() || _isFullScreen()) {
@ -575,8 +741,10 @@ void FluFrameless::_showSystemMenu(QPoint point) {
::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED); ::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED);
::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED); ::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED);
} }
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), nativePos.x(), const int result = ::TrackPopupMenu(
nativePos.y(), 0, hwnd, nullptr); hMenu,
(TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)),
nativePos.x(), nativePos.y(), 0, hwnd, nullptr);
if (result) { if (result) {
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0); ::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
} }
@ -682,7 +850,7 @@ void FluFrameless::_setWindowTopmost(bool topmost) {
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); ::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} }
#else #else
window()->setFlag(Qt::WindowStaysOnTopHint,topmost); window()->setFlag(Qt::WindowStaysOnTopHint, topmost);
#endif #endif
} }
@ -690,24 +858,24 @@ bool FluFrameless::eventFilter(QObject *obj, QEvent *ev) {
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
switch (ev->type()) { switch (ev->type()) {
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
if(_edges!=0){ if (_edges != 0) {
QMouseEvent *event = static_cast<QMouseEvent*>(ev); QMouseEvent *event = static_cast<QMouseEvent *>(ev);
if(event->button() == Qt::LeftButton){ if (event->button() == Qt::LeftButton) {
_updateCursor(_edges); _updateCursor(_edges);
window()->startSystemResize(Qt::Edges(_edges)); window()->startSystemResize(Qt::Edges(_edges));
} }
}else{ } else {
if(_hitAppBar()){ if (_hitAppBar()) {
qint64 clickTimer = QDateTime::currentMSecsSinceEpoch(); qint64 clickTimer = QDateTime::currentMSecsSinceEpoch();
qint64 offset = clickTimer - this->_clickTimer; qint64 offset = clickTimer - this->_clickTimer;
this->_clickTimer = clickTimer; this->_clickTimer = clickTimer;
if(offset<300){ if (offset < 300) {
if(_isMaximized()){ if (_isMaximized()) {
showNormal(); showNormal();
}else{ } else {
showMaximized(); showMaximized();
} }
}else{ } else {
window()->startSystemMove(); window()->startSystemMove();
} }
} }
@ -717,37 +885,38 @@ bool FluFrameless::eventFilter(QObject *obj, QEvent *ev) {
_edges = 0; _edges = 0;
break; break;
case QEvent::MouseMove: { case QEvent::MouseMove: {
if(_isMaximized() || _isFullScreen()){ if (_isMaximized() || _isFullScreen()) {
break; break;
} }
if(_fixSize){ if (_fixSize) {
break; break;
} }
QMouseEvent *event = static_cast<QMouseEvent*>(ev); QMouseEvent *event = static_cast<QMouseEvent *>(ev);
QPoint p = QPoint p =
#if QT_VERSION < QT_VERSION_CHECK(6,0,0) # if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
event->pos(); event->pos();
#else # else
event->position().toPoint(); event->position().toPoint();
#endif # endif
if(p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins && p.y() <= (window()->height() - _margins)){ if (p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins &&
if(_edges != 0){ p.y() <= (window()->height() - _margins)) {
if (_edges != 0) {
_edges = 0; _edges = 0;
_updateCursor(_edges); _updateCursor(_edges);
} }
break; break;
} }
_edges = 0; _edges = 0;
if ( p.x() < _margins ) { if (p.x() < _margins) {
_edges |= Qt::LeftEdge; _edges |= Qt::LeftEdge;
} }
if ( p.x() > (window()->width() - _margins) ) { if (p.x() > (window()->width() - _margins)) {
_edges |= Qt::RightEdge; _edges |= Qt::RightEdge;
} }
if ( p.y() < _margins ) { if (p.y() < _margins) {
_edges |= Qt::TopEdge; _edges |= Qt::TopEdge;
} }
if ( p.y() > (window()->height() - _margins) ) { if (p.y() > (window()->height() - _margins)) {
_edges |= Qt::BottomEdge; _edges |= Qt::BottomEdge;
} }
_updateCursor(_edges); _updateCursor(_edges);

View File

@ -8,12 +8,12 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment (lib, "user32.lib") # pragma comment(lib, "user32.lib")
#pragma comment (lib, "dwmapi.lib") # pragma comment(lib, "dwmapi.lib")
#include <windows.h> # include <windows.h>
#include <windowsx.h> # include <windowsx.h>
#include <dwmapi.h> # include <dwmapi.h>
enum _DWM_SYSTEMBACKDROP_TYPE { enum _DWM_SYSTEMBACKDROP_TYPE {
_DWMSBT_AUTO, // [Default] Let DWM automatically decide the system-drawn backdrop for this _DWMSBT_AUTO, // [Default] Let DWM automatically decide the system-drawn backdrop for this
// window. // window.
@ -89,11 +89,16 @@ struct WINDOWCOMPOSITIONATTRIBDATA {
}; };
using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *; using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
typedef HRESULT (WINAPI *DwmSetWindowAttributeFunc)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); typedef HRESULT(WINAPI *DwmSetWindowAttributeFunc)(HWND hwnd, DWORD dwAttribute,
typedef HRESULT (WINAPI *DwmExtendFrameIntoClientAreaFunc)(HWND hwnd, const MARGINS *pMarInset); LPCVOID pvAttribute, DWORD cbAttribute);
typedef HRESULT (WINAPI *DwmIsCompositionEnabledFunc)(BOOL *pfEnabled); typedef HRESULT(WINAPI *DwmExtendFrameIntoClientAreaFunc)(HWND hwnd, const MARGINS *pMarInset);
typedef HRESULT (WINAPI *DwmEnableBlurBehindWindowFunc)(HWND hWnd, const DWM_BLURBEHIND *pBlurBehind); typedef HRESULT(WINAPI *DwmIsCompositionEnabledFunc)(BOOL *pfEnabled);
typedef BOOL (WINAPI *SetWindowCompositionAttributeFunc)(HWND hwnd, const WINDOWCOMPOSITIONATTRIBDATA *); typedef HRESULT(WINAPI *DwmEnableBlurBehindWindowFunc)(HWND hWnd,
const DWM_BLURBEHIND *pBlurBehind);
typedef BOOL(WINAPI *SetWindowCompositionAttributeFunc)(HWND hwnd,
const WINDOWCOMPOSITIONATTRIBDATA *);
typedef UINT(WINAPI *GetDpiForWindowFunc)(HWND hWnd);
typedef int(WINAPI *GetSystemMetricsForDpiFunc)(int nIndex, UINT dpi);
#endif #endif