win: system menu: allow user remove menu items
This commit is contained in:
parent
2cb8ec0aeb
commit
4821e8982f
|
@ -40,6 +40,7 @@ foreach(_component ${@PROJECT_NAME@_FIND_COMPONENTS})
|
||||||
if(EXISTS "${__targets_file}")
|
if(EXISTS "${__targets_file}")
|
||||||
include("${__targets_file}")
|
include("${__targets_file}")
|
||||||
add_library(${__target} ALIAS @PROJECT_NAME@::${__target_full})
|
add_library(${__target} ALIAS @PROJECT_NAME@::${__target_full})
|
||||||
|
list(APPEND _@PROJECT_NAME@_available_components ${_component})
|
||||||
else()
|
else()
|
||||||
set(@PROJECT_NAME@_FOUND FALSE)
|
set(@PROJECT_NAME@_FOUND FALSE)
|
||||||
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Can't find necessary configuration file for ${__target}, please make sure this component is built successfully and installed properly.")
|
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Can't find necessary configuration file for ${__target}, please make sure this component is built successfully and installed properly.")
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <FramelessHelper/Widgets/standardtitlebar.h>
|
#include <FramelessHelper/Widgets/standardtitlebar.h>
|
||||||
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
|
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
|
||||||
#include <FramelessHelper/Widgets/standardsystembutton.h>
|
#include <FramelessHelper/Widgets/standardsystembutton.h>
|
||||||
|
#include <FramelessHelper/Widgets/private/framelesswidgetshelper_p.h>
|
||||||
#include "../shared/settings.h"
|
#include "../shared/settings.h"
|
||||||
|
|
||||||
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
|
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
|
||||||
|
@ -134,6 +135,14 @@ void Dialog::setupUi()
|
||||||
#if FRAMELESSHELPER_CONFIG(titlebar)
|
#if FRAMELESSHELPER_CONFIG(titlebar)
|
||||||
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
|
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
|
||||||
helper->setTitleBarWidget(titleBar);
|
helper->setTitleBarWidget(titleBar);
|
||||||
|
# ifdef Q_OS_WINDOWS
|
||||||
|
FramelessWidgetsHelperPrivate *helperPriv = FramelessWidgetsHelperPrivate::get(helper);
|
||||||
|
helperPriv->setProperty(kSysMenuRemoveRestoreVar, true);
|
||||||
|
helperPriv->setProperty(kSysMenuRemoveSizeVar, true);
|
||||||
|
helperPriv->setProperty(kSysMenuRemoveMinimizeVar, true);
|
||||||
|
helperPriv->setProperty(kSysMenuRemoveMaximizeVar, true);
|
||||||
|
helperPriv->setProperty(kSysMenuRemoveSeparatorVar, true);
|
||||||
|
# endif
|
||||||
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
|
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
|
||||||
helper->setSystemButton(titleBar->minimizeButton(), SystemButtonType::Minimize);
|
helper->setSystemButton(titleBar->minimizeButton(), SystemButtonType::Minimize);
|
||||||
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
|
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
|
|
|
@ -395,9 +395,19 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API)
|
||||||
|
|
||||||
[[maybe_unused]] inline constexpr const char kDontOverrideCursorVar[] = "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR";
|
[[maybe_unused]] inline constexpr const char kDontOverrideCursorVar[] = "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR";
|
||||||
[[maybe_unused]] inline constexpr const char kDontToggleMaximizeVar[] = "FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE";
|
[[maybe_unused]] inline constexpr const char kDontToggleMaximizeVar[] = "FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableMoveVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MOVE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableSizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_SIZE";
|
||||||
[[maybe_unused]] inline constexpr const char kSysMenuDisableMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE";
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE";
|
||||||
[[maybe_unused]] inline constexpr const char kSysMenuDisableMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE";
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE";
|
||||||
[[maybe_unused]] inline constexpr const char kSysMenuDisableRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE";
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuDisableCloseVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_CLOSE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMoveVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MOVE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveSizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_SIZE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MINIMIZE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MAXIMIZE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_RESTORE";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveSeparatorVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_SEPARATOR";
|
||||||
|
[[maybe_unused]] inline constexpr const char kSysMenuRemoveCloseVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_CLOSE";
|
||||||
|
|
||||||
enum class Option : quint8
|
enum class Option : quint8
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,6 +135,9 @@ FRAMELESSHELPER_STRING_CONSTANT(EnableMenuItem)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(SetMenuDefaultItem)
|
FRAMELESSHELPER_STRING_CONSTANT(SetMenuDefaultItem)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(HiliteMenuItem)
|
FRAMELESSHELPER_STRING_CONSTANT(HiliteMenuItem)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(TrackPopupMenu)
|
FRAMELESSHELPER_STRING_CONSTANT(TrackPopupMenu)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(DrawMenuBar)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(DeleteMenu)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(RemoveMenu)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(ClientToScreen)
|
FRAMELESSHELPER_STRING_CONSTANT(ClientToScreen)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(DwmEnableBlurBehindWindow)
|
FRAMELESSHELPER_STRING_CONSTANT(DwmEnableBlurBehindWindow)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(SetWindowCompositionAttribute)
|
FRAMELESSHELPER_STRING_CONSTANT(SetWindowCompositionAttribute)
|
||||||
|
@ -1315,11 +1318,45 @@ bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tweak the menu items according to the current window status and user settings.
|
// Tweak the menu items according to the current window status and user settings.
|
||||||
|
const bool disableClose = data->callbacks->getProperty(kSysMenuDisableCloseVar, false).toBool();
|
||||||
const bool disableRestore = data->callbacks->getProperty(kSysMenuDisableRestoreVar, false).toBool();
|
const bool disableRestore = data->callbacks->getProperty(kSysMenuDisableRestoreVar, false).toBool();
|
||||||
const bool disableMinimize = data->callbacks->getProperty(kSysMenuDisableMinimizeVar, false).toBool();
|
const bool disableMinimize = data->callbacks->getProperty(kSysMenuDisableMinimizeVar, false).toBool();
|
||||||
const bool disableMaximize = data->callbacks->getProperty(kSysMenuDisableMaximizeVar, false).toBool();
|
const bool disableMaximize = data->callbacks->getProperty(kSysMenuDisableMaximizeVar, false).toBool();
|
||||||
|
const bool disableSize = data->callbacks->getProperty(kSysMenuDisableSizeVar, false).toBool();
|
||||||
|
const bool disableMove = data->callbacks->getProperty(kSysMenuDisableMoveVar, false).toBool();
|
||||||
|
const bool removeClose = data->callbacks->getProperty(kSysMenuRemoveCloseVar, false).toBool();
|
||||||
|
const bool removeSeparator = data->callbacks->getProperty(kSysMenuRemoveSeparatorVar, false).toBool();
|
||||||
|
const bool removeRestore = data->callbacks->getProperty(kSysMenuRemoveRestoreVar, false).toBool();
|
||||||
|
const bool removeMinimize = data->callbacks->getProperty(kSysMenuRemoveMinimizeVar, false).toBool();
|
||||||
|
const bool removeMaximize = data->callbacks->getProperty(kSysMenuRemoveMaximizeVar, false).toBool();
|
||||||
|
const bool removeSize = data->callbacks->getProperty(kSysMenuRemoveSizeVar, false).toBool();
|
||||||
|
const bool removeMove = data->callbacks->getProperty(kSysMenuRemoveMoveVar, false).toBool();
|
||||||
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
||||||
const bool fixedSize = data->callbacks->isWindowFixedSize();
|
const bool fixedSize = data->callbacks->isWindowFixedSize();
|
||||||
|
if (removeClose) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | (disableClose ? MFS_DISABLED : MFS_ENABLED)));
|
||||||
|
}
|
||||||
|
if (removeSeparator) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_SEPARATOR, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeMaximize) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_MAXIMIZE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
::EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize && !disableMaximize) ? MFS_ENABLED : MFS_DISABLED)));
|
||||||
|
}
|
||||||
|
if (removeRestore) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_RESTORE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
::EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize && !disableRestore) ? MFS_ENABLED : MFS_DISABLED)));
|
::EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize && !disableRestore) ? MFS_ENABLED : MFS_DISABLED)));
|
||||||
// The first menu item should be selected by default if the menu is brought
|
// The first menu item should be selected by default if the menu is brought
|
||||||
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
||||||
|
@ -1331,33 +1368,63 @@ bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
||||||
// highlight bar to indicate the current selected menu item, which will make
|
// highlight bar to indicate the current selected menu item, which will make
|
||||||
// the menu look kind of weird. Currently I don't know how to fix this issue.
|
// the menu look kind of weird. Currently I don't know how to fix this issue.
|
||||||
::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
|
::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
|
||||||
::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_DISABLED)));
|
}
|
||||||
::EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize && !(disableMinimize || disableMaximize)) ? MFS_ENABLED : MFS_DISABLED)));
|
if (removeMinimize) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_MINIMIZE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | (disableMinimize ? MFS_DISABLED : MFS_ENABLED)));
|
::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | (disableMinimize ? MFS_DISABLED : MFS_ENABLED)));
|
||||||
::EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize && !disableMaximize) ? MFS_ENABLED : MFS_DISABLED)));
|
}
|
||||||
::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
|
if (removeSize) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_SIZE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
::EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize && !(disableSize || disableMinimize || disableMaximize)) ? MFS_ENABLED : MFS_DISABLED)));
|
||||||
|
}
|
||||||
|
if (removeMove) {
|
||||||
|
if (::DeleteMenu(hMenu, SC_MOVE, MF_BYCOMMAND) == FALSE) {
|
||||||
|
//WARNING << getSystemErrorMessage(kDeleteMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | ((disableMove || maxOrFull) ? MFS_DISABLED : MFS_ENABLED)));
|
||||||
|
}
|
||||||
|
|
||||||
// The default menu item will appear in bold font. There can only be one default
|
// The default menu item will appear in bold font. There can only be one default
|
||||||
// menu item per menu at most. Set the item ID to "UINT_MAX" (or simply "-1")
|
// menu item per menu at most. Set the item ID to "UINT_MAX" (or simply "-1")
|
||||||
// can clear the default item for the given menu.
|
// can clear the default item for the given menu.
|
||||||
UINT defaultItemId = UINT_MAX;
|
std::optional<UINT> defaultItemId = std::nullopt;
|
||||||
if (WindowsVersionHelper::isWin11OrGreater()) {
|
if (WindowsVersionHelper::isWin11OrGreater()) {
|
||||||
if (maxOrFull) {
|
if (maxOrFull) {
|
||||||
|
if (!removeRestore) {
|
||||||
defaultItemId = SC_RESTORE;
|
defaultItemId = SC_RESTORE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!removeMaximize) {
|
||||||
defaultItemId = SC_MAXIMIZE;
|
defaultItemId = SC_MAXIMIZE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
if (!(defaultItemId.has_value() || removeClose)) {
|
||||||
defaultItemId = SC_CLOSE;
|
defaultItemId = SC_CLOSE;
|
||||||
}
|
}
|
||||||
::SetMenuDefaultItem(hMenu, defaultItemId, FALSE);
|
if (::SetMenuDefaultItem(hMenu, defaultItemId.value_or(UINT_MAX), FALSE) == FALSE) {
|
||||||
|
WARNING << getSystemErrorMessage(kSetMenuDefaultItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::DrawMenuBar(hWnd) == FALSE) {
|
||||||
|
WARNING << getSystemErrorMessage(kDrawMenuBar);
|
||||||
|
}
|
||||||
|
|
||||||
// Popup the system menu at the required position.
|
// Popup the system menu at the required position.
|
||||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr);
|
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr);
|
||||||
|
|
||||||
|
if (!removeRestore) {
|
||||||
// Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
|
// Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
|
||||||
// highlighting until we unhighlight it manually.
|
// highlighting until we unhighlight it manually.
|
||||||
::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
|
::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
|
||||||
|
}
|
||||||
|
|
||||||
if (result == FALSE) {
|
if (result == FALSE) {
|
||||||
// The user canceled the menu, no need to continue.
|
// The user canceled the menu, no need to continue.
|
||||||
|
|
Loading…
Reference in New Issue