picoe / Eto

Cross platform GUI framework for desktop and mobile applications in .NET
Other
3.67k stars 333 forks source link

OSX App Close on Form Close #535

Open tpitman opened 8 years ago

tpitman commented 8 years ago

I am writing a XamMac2 app. I would like the app to quit when the form is closed.

At first I tried to do it like other frameworks by overriding the Closed method in the form and calling Application.Instance.Quit. My override never gets called.

I then search on this wiki and found an obscure reference as part of another issue someone was having. In that post I read that if you set Application.MainForm to the form you want to quit the app on close that will work.

I set this:

Application.Instance.MainForm = this;

In the constructor of my Form and that didn't work.

I also tried changing my startup code in Main to create the application and form as variables and hook them together and that also did not work.

How do I make it so the app quits when you close the main form?

cwensley commented 8 years ago

adding these styles to the Program.cs in your XamMac project should do it:

Eto.Style.Add<Eto.Mac.Forms.ApplicationHandler>(null, handler => handler.AllowClosingMainForm = true);
Eto.Style.Add<Form>("main", form => form.Closed += (sender, e) => Application.Instance.Quit());

Then in the constructor of your main form:

MainForm()
{
  Style = "main";
  ...
}

It would be nice to have a general way to do this without resorting to platform specific code, but has not been done yet.

Hope this helps! Curtis.

tpitman commented 8 years ago

Thank you for the way to do this, but OUCH. For something as simple as closing the app when the main window closes that is rough.

Does it work differently on the Gtk, Windows or MonoMac build? Is this something specific to Xamain.Mac that we are working around?

tpitman commented 8 years ago

Works like a charm, btw. Thank you!

tpitman commented 8 years ago

One problem. When I use the menu to quit, now I get an exception when the form also tries to quit. What can I check in the lambda that calls Application.Instance.Quit to check and make sure we are not already quitting?

joshua-software-dev commented 4 years ago

Just sharing how I made this work without exception on quit.

namespace MyProgramGui.Mac
{
    internal static class MainClass
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Eto.Style.Add<Eto.Mac.Forms.ApplicationHandler>(null, handler => handler.AllowClosingMainForm = true);
            new Application(Eto.Platforms.Mac64).Run(new MainForm());
        }
    }
}

and in whatever the main form is

public class MainForm : Form
{
    private static void KillProgramOnMainWindowExit(object sender, EventArgs e)
    {
        Application.Instance.Quit();
    }

    public MainForm()
    {
        Closed += KillProgramOnMainWindowExit;
        Application.Instance.Terminating += (s, e) => Closed -= KillProgramOnMainWindowExit;
    }
}