Skip to content

Commit 28e6172

Browse files
committed
feat: update application name and enhance native menu structure
1 parent 9b99cf0 commit 28e6172

File tree

3 files changed

+64
-24
lines changed

3 files changed

+64
-24
lines changed

src/ProjectRover/App.axaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@
2626
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
2727
x:Class="ProjectRover.App"
2828
RequestedThemeVariant="Light"
29-
Name="ProjectRover">
29+
Name="Project Rover">
3030

31+
<NativeMenu.Menu>
32+
<NativeMenu />
33+
</NativeMenu.Menu>
3134
<Application.Styles>
3235
<FluentTheme />
3336
<dockThemes:DockFluentTheme />

src/ProjectRover/App.axaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public partial class App : Application
5555

5656
public override void Initialize()
5757
{
58+
Name = "Project Rover";
5859
AvaloniaXamlLoader.Load(this);
5960
}
6061

src/ProjectRover/Controls/MainMenu.axaml.cs

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,11 @@ static bool IsApiVisibilityMenuItem(MenuItem menuItem)
738738
|| string.Equals(menuItem.Tag as string, "ApiVisAll", StringComparison.Ordinal);
739739
}
740740

741+
static bool IsHelpMenuItem(MenuItem menuItem)
742+
{
743+
return string.Equals(menuItem.Tag as string, "_Help", StringComparison.Ordinal);
744+
}
745+
741746
static bool IsLanguageMenuItem(MenuItem menuItem)
742747
{
743748
var tag = menuItem.Tag as string;
@@ -980,8 +985,11 @@ void BuildNativeMenu(Menu mainMenu)
980985

981986
_nativeThemeMenuItems = new List<NativeMenuItem>();
982987

983-
var nativeRoot = new NativeMenu();
988+
var windowMenu = new NativeMenu();
989+
var appMenu = Application.Current != null ? NativeMenu.GetMenu(Application.Current) ?? new NativeMenu() : null;
990+
appMenu?.Items.Clear();
984991
var itemCount = 0;
992+
MenuItem? helpMenu = null;
985993

986994
NativeMenuItem Convert(MenuItem m)
987995
{
@@ -1004,6 +1012,15 @@ NativeMenuItem Convert(MenuItem m)
10041012
native.CommandParameter = m.CommandParameter;
10051013
}
10061014

1015+
if (m.InputGesture != null)
1016+
{
1017+
native.Gesture = m.InputGesture;
1018+
}
1019+
else if (m.HotKey != null)
1020+
{
1021+
native.Gesture = m.HotKey;
1022+
}
1023+
10071024
TryApplyNativeMenuIcon(native, m);
10081025

10091026
if (!suppressNativeToggle && m.ToggleType != MenuItemToggleType.None)
@@ -1091,34 +1108,51 @@ NativeMenuItem Convert(MenuItem m)
10911108
{
10921109
if (item is MenuItem mi)
10931110
{
1094-
nativeRoot.Items.Add(Convert(mi));
1111+
if (IsHelpMenuItem(mi))
1112+
{
1113+
helpMenu = mi;
1114+
continue;
1115+
}
1116+
1117+
windowMenu.Items.Add(Convert(mi));
10951118
}
10961119
}
10971120

10981121
log.Debug("BuildNativeMenu: Converted {ItemCount} menu items total", itemCount);
10991122

1100-
// Insert an explicit application menu to avoid the platform/Avalonia
1101-
// falling back to a default menu (which can show "About Avalonia").
1102-
try
1103-
{
1104-
var appName = Application.Current?.Name
1105-
?? Assembly.GetEntryAssembly()?.GetName().Name
1106-
?? "Project Rover";
1107-
var appSub = new NativeMenu();
1108-
// Optionally populate appSub with About/Preferences/Quit entries.
1109-
var appMenuItem = new NativeMenuItem { Header = appName, Menu = appSub };
1110-
nativeRoot.Items.Insert(0, appMenuItem);
1111-
log.Debug("BuildNativeMenu: Inserted application menu '{AppName}' to override default app menu", appName);
1112-
}
1113-
catch (Exception ex)
1123+
// Fill the application menu with Help items (no extra "Project Rover" tier).
1124+
if (appMenu != null)
11141125
{
1115-
log.Warning(ex, "BuildNativeMenu: Failed to insert application menu");
1126+
try
1127+
{
1128+
if (helpMenu != null)
1129+
{
1130+
foreach (var child in helpMenu.Items)
1131+
{
1132+
switch (child)
1133+
{
1134+
case Separator:
1135+
appMenu.Items.Add(new NativeMenuItemSeparator());
1136+
break;
1137+
case MenuItem childMi:
1138+
appMenu.Items.Add(Convert(childMi));
1139+
break;
1140+
}
1141+
}
1142+
}
1143+
1144+
log.Debug("BuildNativeMenu: Filled app menu with {Count} items", appMenu.Items.Count);
1145+
}
1146+
catch (Exception ex)
1147+
{
1148+
log.Warning(ex, "BuildNativeMenu: Failed to fill application menu");
1149+
}
11161150
}
11171151

11181152
// Always set a fresh native menu; avoid reusing existing items to prevent parent conflicts.
11191153
// Some native backends may throw when attempting to update menus that are still
11201154
// referenced by the platform. Always clear existing menu first before setting new one.
1121-
void TrySetNativeMenu(AvaloniaObject target)
1155+
void TrySetNativeMenu(AvaloniaObject target, NativeMenu menu)
11221156
{
11231157
try
11241158
{
@@ -1137,7 +1171,7 @@ void TrySetNativeMenu(AvaloniaObject target)
11371171
}
11381172
}
11391173

1140-
NativeMenu.SetMenu(target, nativeRoot);
1174+
NativeMenu.SetMenu(target, menu);
11411175
log.Debug("BuildNativeMenu: Successfully set native menu on target");
11421176
}
11431177
catch (Exception ex)
@@ -1149,7 +1183,7 @@ void TrySetNativeMenu(AvaloniaObject target)
11491183
try
11501184
{
11511185
log.Debug("BuildNativeMenu: Trying Application.Current as fallback");
1152-
NativeMenu.SetMenu(Application.Current, nativeRoot);
1186+
NativeMenu.SetMenu(Application.Current, menu);
11531187
log.Debug("BuildNativeMenu: Fallback succeeded");
11541188
}
11551189
catch (Exception fallbackEx)
@@ -1160,10 +1194,12 @@ void TrySetNativeMenu(AvaloniaObject target)
11601194
}
11611195
}
11621196

1163-
// Set native menu only on the window (rootObj); setting on both window and
1164-
// Application.Current causes "menu does not match" errors on macOS
1197+
// Set window menu on the window and app menu on Application.Current.
11651198
if (rootObj != null)
1166-
TrySetNativeMenu(rootObj);
1199+
TrySetNativeMenu(rootObj, windowMenu);
1200+
1201+
if (Application.Current != null && appMenu != null)
1202+
TrySetNativeMenu(Application.Current, appMenu);
11671203

11681204
log.Debug("BuildNativeMenu: Native menu set successfully");
11691205
MainMenuThemeHelpers.UpdateNativeThemeChecks(_nativeThemeMenuItems, settingsService?.SessionSettings?.Theme ?? ThemeManager.Current.Theme);

0 commit comments

Comments
 (0)