Skip to content

Commit

Permalink
Merge pull request #2653 from cwensley/curtis/mac-menus-on-dialogs
Browse files Browse the repository at this point in the history
Mac: Fix disabled menu items with a Dialog
  • Loading branch information
cwensley authored May 24, 2024
2 parents 32486aa + 2790957 commit fbee392
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 7 deletions.
3 changes: 3 additions & 0 deletions src/Eto.Mac/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public override void DidFinishLaunching(NSNotification notification)
{
var handler = Application.Instance.Handler as ApplicationHandler;
if (handler != null)
{
handler.InitialMenu = Messaging.IntPtr_objc_msgSend(NSApplication.SharedApplication.Handle, MacWindow.selMainMenu);
handler.Initialize(this);
}
}

public override NSApplicationTerminateReply ApplicationShouldTerminate(NSApplication sender)
Expand Down
5 changes: 4 additions & 1 deletion src/Eto.Mac/Forms/ApplicationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public class ApplicationHandler : WidgetHandler<NSApplication, Application, Appl

public bool AllowClosingMainForm { get; set; }

// pointer to the initial menu so we know whether we want to keep it or not for the main form
internal IntPtr InitialMenu { get; set; }

/// <summary>
/// Gets or sets a value indicating whether native macOS crash reports are generated for uncaught .NET exceptions.
/// </summary>
Expand Down Expand Up @@ -193,7 +196,7 @@ public void Run()


EtoBundle.Init();

EtoFontManager.Install();

if (Control.Delegate == null)
Expand Down
3 changes: 3 additions & 0 deletions src/Eto.Mac/Forms/MacWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,9 @@ void SetMenu()
if (oldMenu == IntPtr.Zero)
{
oldMenu = Messaging.IntPtr_objc_msgSend(NSApplication.SharedApplication.Handle, MacWindow.selMainMenu);
// don't save the initial menu which macOS creates on startup
if (oldMenu == ApplicationHandler.Instance.InitialMenu)
oldMenu = IntPtr.Zero;
if (oldMenu != IntPtr.Zero)
{
// remember old native menu so we can restore it later
Expand Down
25 changes: 19 additions & 6 deletions src/Eto.Mac/Forms/Menu/MenuHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,28 @@ public bool WorksWhenModal
var worksWhenModal = Widget.Properties.Get<bool?>(MenuHandler.WorksWhenModal_Key);
if (worksWhenModal == null)
{
// find top level menu
// traverse menu tree to find any parent that specifies it should work when modal
var menu = Control.Menu;
while (menu.Supermenu != null)
menu = menu.Supermenu;
do
{
if (menu is EtoMenu etoMenu && etoMenu.WorksWhenModal)
return true;

worksWhenModal = (menu as EtoMenu)?.WorksWhenModal ?? false;
Widget.Properties.Set(MenuHandler.WorksWhenModal_Key, worksWhenModal);
menu = menu.Supermenu;
} while (menu.Supermenu != null);

// check the top menu (e.g. context menu or menu bar)
if (menu is EtoMenu topEtoMenu && topEtoMenu.WorksWhenModal)
return true;

// allow all items if it is in current dialog's menu.
if (NSApplication.SharedApplication.KeyWindow is EtoWindow window && window.Handler?.Widget is Dialog dialog)
{
var currentMenu = MenuBarHandler.GetControl(dialog.Menu);
return currentMenu == menu;
}
}
return worksWhenModal.Value;
return worksWhenModal ?? false;
}
set => Widget.Properties.Set(MenuHandler.WorksWhenModal_Key, value);
}
Expand Down

0 comments on commit fbee392

Please sign in to comment.