diff --git a/qtacrylicwidget.cpp b/qtacrylicwidget.cpp index fddf3c0..812e4e5 100644 --- a/qtacrylicwidget.cpp +++ b/qtacrylicwidget.cpp @@ -143,7 +143,9 @@ void QtAcrylicWidget::setAcrylicEnabled(const bool value) { if (m_acrylicEnabled != value) { m_acrylicEnabled = value; - Utilities::setBlurEffectEnabled(windowHandle(), m_acrylicEnabled); + if (m_inited) { + Utilities::setBlurEffectEnabled(windowHandle(), m_acrylicEnabled); + } setAutoFillBackground(!m_acrylicEnabled); setAttribute(Qt::WA_NoSystemBackground, m_acrylicEnabled); setAttribute(Qt::WA_OpaquePaintEvent, m_acrylicEnabled); @@ -156,25 +158,25 @@ void QtAcrylicWidget::setAcrylicEnabled(const bool value) void QtAcrylicWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); - static bool inited = false; - if (!inited) { + if (!m_inited) { FramelessWindowsManager::addWindow(windowHandle()); m_acrylicHelper.install(windowHandle()); m_acrylicHelper.updateAcrylicBrush(tintColor()); connect(&m_acrylicHelper, &QtAcrylicEffectHelper::needsRepaint, this, qOverload<>(&QtAcrylicWidget::update)); setAcrylicEnabled(true); - inited = true; + m_inited = true; } } void QtAcrylicWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); + const QRect rect = {0, 0, width(), height()}; if (acrylicEnabled()) { - m_acrylicHelper.paintWindowBackground(&painter, QRect{0, 0, width(), height()}); + m_acrylicHelper.paintWindowBackground(&painter, rect); } if (frameVisible()) { - m_acrylicHelper.paintWindowFrame(&painter); + m_acrylicHelper.paintWindowFrame(&painter, rect); } QWidget::paintEvent(event); } diff --git a/qtacrylicwidget.h b/qtacrylicwidget.h index ca56e92..9849f59 100644 --- a/qtacrylicwidget.h +++ b/qtacrylicwidget.h @@ -82,4 +82,5 @@ private: QtAcrylicEffectHelper m_acrylicHelper; bool m_frameVisible = true; bool m_acrylicEnabled = false; + bool m_inited = false; }; diff --git a/utilities.h b/utilities.h index db3e86b..10df702 100644 --- a/utilities.h +++ b/utilities.h @@ -98,6 +98,8 @@ FRAMELESSHELPER_EXPORT void updateQtFrameMargins(QWindow *window, const bool ena FRAMELESSHELPER_EXPORT quint32 getWindowDpi(const QWindow *window); FRAMELESSHELPER_EXPORT QMargins getWindowNativeFrameMargins(const QWindow *window); FRAMELESSHELPER_EXPORT QColor getNativeWindowFrameColor(const bool isActive = true); + +FRAMELESSHELPER_EXPORT void displaySystemMenu(const QWindow *window, const QPoint pos = {}); #endif } diff --git a/utilities_win32.cpp b/utilities_win32.cpp index abb9e52..9b1700e 100644 --- a/utilities_win32.cpp +++ b/utilities_win32.cpp @@ -713,3 +713,72 @@ bool Utilities::shouldUseTraditionalBlur() } return false; } + +void Utilities::displaySystemMenu(const QWindow *window, const QPoint pos) +{ + Q_ASSERT(window); + if (!window) { + return; + } + const auto hwnd = reinterpret_cast(window->winId()); + Q_ASSERT(hwnd); + if (!hwnd) { + return; + } + const HMENU hMenu = GetSystemMenu(hwnd, FALSE); + if (!hMenu) { + qWarning() << "Failed to acquire the system menu."; + return; + } + MENUITEMINFOW mii; + SecureZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE; + mii.fType = 0; + mii.fState = MF_ENABLED; + SetMenuItemInfoW(hMenu, SC_RESTORE, FALSE, &mii); + SetMenuItemInfoW(hMenu, SC_SIZE, FALSE, &mii); + SetMenuItemInfoW(hMenu, SC_MOVE, FALSE, &mii); + SetMenuItemInfoW(hMenu, SC_MAXIMIZE, FALSE, &mii); + SetMenuItemInfoW(hMenu, SC_MINIMIZE, FALSE, &mii); + mii.fState = MF_GRAYED; + const auto isMin = [window]{ + return (window->windowState() == Qt::WindowMinimized); + }(); + const auto isMax = [window]{ + return (window->windowState() == Qt::WindowMaximized); + }(); + const auto isFull = [window]{ + return (window->windowState() == Qt::WindowFullScreen); + }(); + const bool isNormal = !isMin && !isMax && !isFull; + const auto isFix = [window]{ + if (window->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)) { + return true; + } + const QSize minSize = window->minimumSize(); + const QSize maxSize = window->maximumSize(); + if (!minSize.isEmpty() && !maxSize.isEmpty() && (minSize == maxSize)) { + return true; + } + return false; + }(); + if (isFix || isMax || isFull) { + SetMenuItemInfoW(hMenu, SC_SIZE, FALSE, &mii); + SetMenuItemInfoW(hMenu, SC_MAXIMIZE, FALSE, &mii); + } + if (isFix || isFull || isNormal) { + SetMenuItemInfoW(hMenu, SC_RESTORE, FALSE, &mii); + } + if (isMax || isFull) { + SetMenuItemInfoW(hMenu, SC_MOVE, FALSE, &mii); + } + if (isMin) { + SetMenuItemInfoW(hMenu, SC_MINIMIZE, FALSE, &mii); + } + const QPoint point = pos.isNull() ? QCursor::pos(window->screen()) : pos; + const LPARAM cmd = TrackPopupMenu(hMenu, (TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN), point.x(), point.y(), 0, hwnd, nullptr); + if (cmd) { + PostMessageW(hwnd, WM_SYSCOMMAND, cmd, 0); + } +}