Merge pull request #89540 from bruvzg/menu_fix_string_read
[NativeMenu] Fix changes lost due to incorrect rebase (menu goes under task bar, dark mode, item text get, docs) and check to ensure help menu is not using native menu on Windows.
This commit is contained in:
commit
fe01776f05
5 changed files with 70 additions and 14 deletions
|
@ -53,7 +53,7 @@
|
||||||
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_icon_check_item">
|
<method name="add_icon_check_item">
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_icon_item">
|
<method name="add_icon_item">
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_icon_radio_check_item">
|
<method name="add_icon_radio_check_item">
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
|
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_item">
|
<method name="add_item">
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_multistate_item">
|
<method name="add_multistate_item">
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
[b]Note:[/b] By default, there's no indication of the current item state, it should be changed manually.
|
[b]Note:[/b] By default, there's no indication of the current item state, it should be changed manually.
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_radio_check_item">
|
<method name="add_radio_check_item">
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
|
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
|
||||||
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
[b]Note:[/b] [param accelerator] and [param key_callback] are ignored on Windows.
|
[b]Note:[/b] On Windows, [param accelerator] and [param key_callback] are ignored.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_separator">
|
<method name="add_separator">
|
||||||
|
@ -496,7 +496,7 @@
|
||||||
<param index="0" name="rid" type="RID" />
|
<param index="0" name="rid" type="RID" />
|
||||||
<param index="1" name="is_rtl" type="bool" />
|
<param index="1" name="is_rtl" type="bool" />
|
||||||
<description>
|
<description>
|
||||||
Sets the menu text layout directtion.
|
Sets the menu text layout direction from right-to-left if [param is_rtl] is [code]true[/code].
|
||||||
[b]Note:[/b] This method is implemented on macOS and Windows.
|
[b]Note:[/b] This method is implemented on macOS and Windows.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
|
|
@ -6754,7 +6754,7 @@ EditorNode::EditorNode() {
|
||||||
ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings..."));
|
ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings..."));
|
||||||
ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KeyModifierMask::META + Key::COMMA);
|
ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KeyModifierMask::META + Key::COMMA);
|
||||||
#ifdef MACOS_ENABLED
|
#ifdef MACOS_ENABLED
|
||||||
if (global_menu) {
|
if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::APPLICATION_MENU_ID)) {
|
||||||
apple_menu = memnew(PopupMenu);
|
apple_menu = memnew(PopupMenu);
|
||||||
apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID);
|
apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID);
|
||||||
main_menu->add_child(apple_menu);
|
main_menu->add_child(apple_menu);
|
||||||
|
@ -6879,7 +6879,9 @@ EditorNode::EditorNode() {
|
||||||
|
|
||||||
help_menu = memnew(PopupMenu);
|
help_menu = memnew(PopupMenu);
|
||||||
help_menu->set_name(TTR("Help"));
|
help_menu->set_name(TTR("Help"));
|
||||||
|
if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::HELP_MENU_ID)) {
|
||||||
help_menu->set_system_menu(NativeMenu::HELP_MENU_ID);
|
help_menu->set_system_menu(NativeMenu::HELP_MENU_ID);
|
||||||
|
}
|
||||||
main_menu->add_child(help_menu);
|
main_menu->add_child(help_menu);
|
||||||
|
|
||||||
help_menu->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
|
help_menu->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
|
||||||
|
|
|
@ -5497,6 +5497,32 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
|
||||||
GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95));
|
GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95));
|
||||||
GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96));
|
GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96));
|
||||||
GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98));
|
GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98));
|
||||||
|
if (os_ver.dwBuildNumber >= 17763) {
|
||||||
|
AllowDarkModeForAppPtr AllowDarkModeForApp = nullptr;
|
||||||
|
SetPreferredAppModePtr SetPreferredAppMode = nullptr;
|
||||||
|
FlushMenuThemesPtr FlushMenuThemes = nullptr;
|
||||||
|
if (os_ver.dwBuildNumber < 18362) {
|
||||||
|
AllowDarkModeForApp = (AllowDarkModeForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
|
||||||
|
} else {
|
||||||
|
SetPreferredAppMode = (SetPreferredAppModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
|
||||||
|
FlushMenuThemes = (FlushMenuThemesPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136));
|
||||||
|
}
|
||||||
|
RefreshImmersiveColorPolicyStatePtr RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStatePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(104));
|
||||||
|
if (ShouldAppsUseDarkMode) {
|
||||||
|
bool dark_mode = ShouldAppsUseDarkMode();
|
||||||
|
if (SetPreferredAppMode) {
|
||||||
|
SetPreferredAppMode(dark_mode ? APPMODE_ALLOWDARK : APPMODE_DEFAULT);
|
||||||
|
} else if (AllowDarkModeForApp) {
|
||||||
|
AllowDarkModeForApp(dark_mode);
|
||||||
|
}
|
||||||
|
if (RefreshImmersiveColorPolicyState) {
|
||||||
|
RefreshImmersiveColorPolicyState();
|
||||||
|
}
|
||||||
|
if (FlushMenuThemes) {
|
||||||
|
FlushMenuThemes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ux_theme_available = ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference;
|
ux_theme_available = ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference;
|
||||||
if (os_ver.dwBuildNumber >= 18363) {
|
if (os_ver.dwBuildNumber >= 18363) {
|
||||||
|
|
|
@ -154,11 +154,23 @@ typedef UINT(WINAPI *WTInfoPtr)(UINT p_category, UINT p_index, LPVOID p_output);
|
||||||
typedef BOOL(WINAPI *WTPacketPtr)(HANDLE p_ctx, UINT p_param, LPVOID p_packets);
|
typedef BOOL(WINAPI *WTPacketPtr)(HANDLE p_ctx, UINT p_param, LPVOID p_packets);
|
||||||
typedef BOOL(WINAPI *WTEnablePtr)(HANDLE p_ctx, BOOL p_enable);
|
typedef BOOL(WINAPI *WTEnablePtr)(HANDLE p_ctx, BOOL p_enable);
|
||||||
|
|
||||||
|
enum PreferredAppMode {
|
||||||
|
APPMODE_DEFAULT = 0,
|
||||||
|
APPMODE_ALLOWDARK = 1,
|
||||||
|
APPMODE_FORCEDARK = 2,
|
||||||
|
APPMODE_FORCELIGHT = 3,
|
||||||
|
APPMODE_MAX = 4
|
||||||
|
};
|
||||||
|
|
||||||
typedef bool(WINAPI *ShouldAppsUseDarkModePtr)();
|
typedef bool(WINAPI *ShouldAppsUseDarkModePtr)();
|
||||||
typedef DWORD(WINAPI *GetImmersiveColorFromColorSetExPtr)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode);
|
typedef DWORD(WINAPI *GetImmersiveColorFromColorSetExPtr)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode);
|
||||||
typedef int(WINAPI *GetImmersiveColorTypeFromNamePtr)(const WCHAR *name);
|
typedef int(WINAPI *GetImmersiveColorTypeFromNamePtr)(const WCHAR *name);
|
||||||
typedef int(WINAPI *GetImmersiveUserColorSetPreferencePtr)(bool bForceCheckRegistry, bool bSkipCheckOnFail);
|
typedef int(WINAPI *GetImmersiveUserColorSetPreferencePtr)(bool bForceCheckRegistry, bool bSkipCheckOnFail);
|
||||||
typedef HRESULT(WINAPI *RtlGetVersionPtr)(OSVERSIONINFOW *lpVersionInformation);
|
typedef HRESULT(WINAPI *RtlGetVersionPtr)(OSVERSIONINFOW *lpVersionInformation);
|
||||||
|
typedef bool(WINAPI *AllowDarkModeForAppPtr)(bool darkMode);
|
||||||
|
typedef PreferredAppMode(WINAPI *SetPreferredAppModePtr)(PreferredAppMode appMode);
|
||||||
|
typedef void(WINAPI *RefreshImmersiveColorPolicyStatePtr)();
|
||||||
|
typedef void(WINAPI *FlushMenuThemesPtr)();
|
||||||
|
|
||||||
// Windows Ink API
|
// Windows Ink API
|
||||||
#ifndef POINTER_STRUCTURES
|
#ifndef POINTER_STRUCTURES
|
||||||
|
|
|
@ -141,7 +141,7 @@ RID NativeMenuWindows::create_menu() {
|
||||||
ZeroMemory(&menu_info, sizeof(menu_info));
|
ZeroMemory(&menu_info, sizeof(menu_info));
|
||||||
menu_info.cbSize = sizeof(menu_info);
|
menu_info.cbSize = sizeof(menu_info);
|
||||||
menu_info.fMask = MIM_STYLE;
|
menu_info.fMask = MIM_STYLE;
|
||||||
menu_info.dwStyle = MNS_NOTIFYBYPOS | MNS_MODELESS;
|
menu_info.dwStyle = MNS_NOTIFYBYPOS;
|
||||||
SetMenuInfo(md->menu, &menu_info);
|
SetMenuInfo(md->menu, &menu_info);
|
||||||
|
|
||||||
RID rid = menus.make_rid(md);
|
RID rid = menus.make_rid(md);
|
||||||
|
@ -189,7 +189,9 @@ void NativeMenuWindows::popup(const RID &p_rid, const Vector2i &p_position) {
|
||||||
if (md->is_rtl) {
|
if (md->is_rtl) {
|
||||||
flags |= TPM_LAYOUTRTL;
|
flags |= TPM_LAYOUTRTL;
|
||||||
}
|
}
|
||||||
|
SetForegroundWindow(hwnd);
|
||||||
TrackPopupMenuEx(md->menu, flags, p_position.x, p_position.y, hwnd, nullptr);
|
TrackPopupMenuEx(md->menu, flags, p_position.x, p_position.y, hwnd, nullptr);
|
||||||
|
PostMessage(hwnd, WM_NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeMenuWindows::set_interface_direction(const RID &p_rid, bool p_is_rtl) {
|
void NativeMenuWindows::set_interface_direction(const RID &p_rid, bool p_is_rtl) {
|
||||||
|
@ -556,12 +558,19 @@ int NativeMenuWindows::find_item_index_with_text(const RID &p_rid, const String
|
||||||
ZeroMemory(&item, sizeof(item));
|
ZeroMemory(&item, sizeof(item));
|
||||||
item.cbSize = sizeof(item);
|
item.cbSize = sizeof(item);
|
||||||
item.fMask = MIIM_STRING;
|
item.fMask = MIIM_STRING;
|
||||||
|
item.dwTypeData = nullptr;
|
||||||
if (GetMenuItemInfoW(md->menu, i, true, &item)) {
|
if (GetMenuItemInfoW(md->menu, i, true, &item)) {
|
||||||
if (String::utf16((const char16_t *)item.dwTypeData) == p_text) {
|
item.cch++;
|
||||||
|
Char16String str;
|
||||||
|
str.resize(item.cch);
|
||||||
|
item.dwTypeData = (LPWSTR)str.ptrw();
|
||||||
|
if (GetMenuItemInfoW(md->menu, i, true, &item)) {
|
||||||
|
if (String::utf16((const char16_t *)str.get_data()) == p_text) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,8 +709,15 @@ String NativeMenuWindows::get_item_text(const RID &p_rid, int p_idx) const {
|
||||||
ZeroMemory(&item, sizeof(item));
|
ZeroMemory(&item, sizeof(item));
|
||||||
item.cbSize = sizeof(item);
|
item.cbSize = sizeof(item);
|
||||||
item.fMask = MIIM_STRING;
|
item.fMask = MIIM_STRING;
|
||||||
|
item.dwTypeData = nullptr;
|
||||||
if (GetMenuItemInfoW(md->menu, p_idx, true, &item)) {
|
if (GetMenuItemInfoW(md->menu, p_idx, true, &item)) {
|
||||||
return String::utf16((const char16_t *)item.dwTypeData);
|
item.cch++;
|
||||||
|
Char16String str;
|
||||||
|
str.resize(item.cch);
|
||||||
|
item.dwTypeData = (LPWSTR)str.ptrw();
|
||||||
|
if (GetMenuItemInfoW(md->menu, p_idx, true, &item)) {
|
||||||
|
return String::utf16((const char16_t *)str.get_data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue