<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    I don't see us adding 100s of OS-specific API calls, but even if we
    did, going down the path of exposing them as Mac APIs or Windows
    APIs, doesn't really seem like the direction we want to go. Whatever
    we do needs to balance the desire to integrate with, e.g., the macOS
    or Windows platform with a desire to leave the door open for it to
    later be implemented on the other platform(s). And the most
    cross-platform way to do that from an API point of view is by
    defining API that delivers the desired functionality in as
    platform-neutral a way as possible. It also needs to fit cleanly
    into the existing API.<br>
    <br>
    So in the specific case of a quit handler, we could define a
    platform API that an app could call to register a handler that gets
    called if the platform quit menu is selected and is able to cancel
    the Quit action(basically, that's what is being proposed). We could
    decide to provide some way for an app to query whether it is
    supported, but maybe we just don't need to worry about it in this
    specific case. We could just document that it will get called when
    the platform quit action is called, if there is such an action on
    that platform. Other than maybe mentioning in the docs that the
    macOS system menu "quit" action is an example of an action that
    would invoke this, it doesn't need to be platform-specific. One
    question to answer is whether we should just put this in the
    Platform class (where we have other similar "global" application
    state), the Application class (which has the life-cycle APIs), or
    somewhere else (which might make sense if we wanted to define an
    analog to the AWT Desktop class, although the existing Platform
    class already has some APIs like this).<br>
    <br>
    -- Kevin<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 9/19/2022 1:46 PM, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:BL0PR10MB2948F5480A765DD3F0C73B78E54D9@BL0PR10MB2948.namprd10.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Courier New",serif;
        color:windowtext;}.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}div.WordSection1
        {page:WordSection1;}</style>
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">Thank you, Kevin.  Your insightful feedback
            always pulls the discussion in the right direction.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">The initial problem we are facing is access
            to Mac menu in general and additional API specifically.  I
            can see a possibility of extending the list of APIs that app
            devs would want on Mac growing, so there should be a better
            way to add them.  Using hacks like com.apple.eawt, or system
            properties is probably not the best solution.  Ideally,
            there should be away that does not require creative linking
            of stub classes on non-Mac platforms, i.e. we should be able
            to use a single code base for all the platforms.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">ConditionalFeature might work well
            internally for openjfx, but I don't think it is a good
            solution for actually exposing the platform APIs to the
            user.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">So, in order to provide platform-specific
            API in such a way that still allows for a single code base
            for multiple platform, and one that potentially scales to
            tens or hundreds of API calls, I see two solutions:<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">1. one start starts with a single entry
            point, like PlatformAPI, described earlier.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">2. a lookup-based approach, where the
            client code requests a (possibly fine-grained and narrowly
            defined) implementation from the system.  For example:<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">IMacMenu impl =
            PlatformAPI.lookup(IMacMenu.class);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">(where IMacMenu is an interface that, in
            this example, provides access to Mac menu, adding shutdown
            listeners, and so forth).<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">if we are on windows, this method either
            returns null or throws an exception, if we are on Mac, we
            get a working instance (a singleton or a new instance each
            time, depending on the circumstances).<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">This way we are free to extend or version
            the APIs without modifying the core classes.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">PlatformAPI.isSupported(IMacMenu.class)
            might provide a way to see whether the capability is
            present.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">The platform-specific interfaces like
            IMacMenu might in turn extend some base interface that
            provides introspection into common properties, such as
            version, description, possibly a list of other similar
            capabilities that the platform supports (may be a number of
            earlier versions?) and so forth.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">What do you think?<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">-andy<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <div style="border:none;border-top:solid #B5C4DF
          1.0pt;padding:3.0pt 0in 0in 0in">
          <p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
              </span></b><span style="font-size:12.0pt;color:black">openjfx-dev
              <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a> on behalf of Kevin
              Rushforth <a class="moz-txt-link-rfc2396E" href="mailto:kevin.rushforth@oracle.com"><kevin.rushforth@oracle.com></a><br>
              <b>Date: </b>Monday, 2022/09/19 at 09:33<br>
              <b>To: </b><a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
              <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a><br>
              <b>Subject: </b>Re: Provide Quit handler for system menu
              bar<o:p></o:p></span></p>
        </div>
        <p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:11.0pt">I like the idea of looking at this
            holistically, even if we do end up adding such features one
            at a time.<br>
            <br>
            As for how to expose such an API, I don't much like the idea
            of exposing the underlying platform explicitly unless there
            is no viable alternative. A better approach is one where a
            feature is optional based on whether the platform you are
            running on supports that feature. Especially given, as you
            pointed out, that features that are only available in one
            platform today might make their way into other platforms
            tomorrow. As for how to let an application know whether they
            can use a particular API, we already have
            ConditionalFeature, so adding to that would be a reasonable
            thing to consider.<br>
            <br>
            -- Kevin<br>
            <br>
            <o:p></o:p></span></p>
        <div>
          <p class="MsoNormal"><span style="font-size:11.0pt">On
              9/19/2022 9:06 AM, Andy Goryachev wrote:<o:p></o:p></span></p>
        </div>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">Greetings!</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">Thank you for proposing a solution,
              Florian.  I wonder if we should extrapolate the problem
              further.  Given the fact that app developers always need
              access to platform specific APIs, be it integration with
              Mac menu, perhaps we should consider a way to do so in
              such a way that does not require various tricks.</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">For example, we might invent a way to
              query whether we are running on a certain platform and get
              the corresponding APIs.  Let's say the class is
              PlatformAPI:</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">These methods allow for querying whether
              the specific platform APIs are available</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">PlatformAPI.isWindows();</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">PlatformAPI.isMacOS();</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">PlatformAPI.isLinux(); // isUnix()?
              isPosix() ?</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">and these will actually return a service
              object that provides access to the APIs, or throws some
              kind of exception:</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">IWindowsAPI PlatformAPI.getWindowsAPI();</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">IMacOSAPI PlatformAPI.getMacOSAPI();</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">the service object returned by one of
              these methods might provide further information about the
              platform version, as well as access to platform-specific
              APIs.</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">Another thought is perhaps we ought to
              think about expanding functionality that became available
              on every platform in the XXI century (example: going to
              sleep/hibernate).  Possibly external shutdown via Mac menu
              or a signal discussed by the OP would be considered as
              platform-independent.</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">What do you think?</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">-andy</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
              New",serif"> </span><o:p></o:p></p>
          <div style="border:none;border-top:solid #B5C4DF
            1.0pt;padding:3.0pt 0in 0in 0in">
            <p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
                </span></b><span style="font-size:12.0pt;color:black">openjfx-dev
                <a href="mailto:openjfx-dev-retn@openjdk.org" moz-do-not-send="true">
                  <openjfx-dev-retn@openjdk.org></a> on behalf of
                Florian Kirmaier <a href="mailto:florian.kirmaier@gmail.com" moz-do-not-send="true">
                  <florian.kirmaier@gmail.com></a><br>
                <b>Date: </b>Tuesday, 2022/09/13 at 08:11<br>
                <b>To: </b><a href="mailto:openjfx-dev@openjdk.java.net" moz-do-not-send="true" class="moz-txt-link-freetext">openjfx-dev@openjdk.java.net</a>
                <a href="mailto:openjfx-dev@openjdk.java.net" moz-do-not-send="true"><openjfx-dev@openjdk.java.net></a><br>
                <b>Subject: </b>Provide Quit handler for system menu
                bar</span><o:p></o:p></p>
          </div>
          <div>
            <div>
              <p class="MsoNormal"><span style="font-size:11.0pt">Hi
                  Everyone,</span><o:p></o:p></p>
            </div>
            <div>
              <p class="MsoNormal"><span style="font-size:11.0pt"><br>
                  In one project, we have to handle the quit-logic for
                  MacOS ourselves,<br>
                  when the <quit app> menu entry is used.<br>
                  As background information - this menu entry is set in
                  the class com.sun.glass.ui.mac.MacApplication.<br>
                  It's basically hard coded. Currently, in this project,
                  the menu entry doesn't work in some cases.<br>
                  <br>
                  My Solution would be:<br>
                  <br>
                  Provide a method
                  "Platform.setQuiteHandler(Supplier<Boolean>)"<br>
                  This handler is called when quit <appname> from
                  the menu is called.<br>
                  If the handler returns true, all windows are closed.
                  Otherwise, nothing happens.<br>
                  <br>
                  It would look like the following:<br>
                  ```<br>
                  /**<br>
                   * Sets the handler to be called when the application
                  is about to quit.<br>
                   * Currently, this can only happen on MacOS.<br>
                   *<br>
                   * This handler is called, when the user selects<br>
                   * the "Quit <appname>" from the application
                  menu.<br>
                   * When the provided handler returns true,<br>
                   * the application will close all windows.<br>
                   * If the handler returns false, the application will
                  not quit.<br>
                   *<br>
                   * @param The new quit handler.<br>
                   */<br>
                  public static void setQuitHandler(Supplier x) {<br>
                      ...<br>
                  }<br>
                  ```<br>
                  I've created a ticket for this topic. <a href="https://bugs.openjdk.org/browse/JDK-8293700" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8293700</a></span><o:p></o:p></p>
            </div>
            <div>
              <p class="MsoNormal"><span style="font-size:11.0pt"><br>
                  I've got a working version for this change. </span><o:p></o:p></p>
            </div>
            <div>
              <p class="MsoNormal"><span style="font-size:11.0pt">According
                  to Kevin Rushforth this need a prior dicussion on the
                  mailing list.</span><o:p></o:p></p>
            </div>
            <div>
              <p class="MsoNormal"><span style="font-size:11.0pt">Any
                  opinion regarding this?<br>
                  <br>
                  I could provide a pullrequest, if someone is
                  interested.<br>
                  <br>
                  Florian Kirmaier</span><o:p></o:p></p>
            </div>
          </div>
        </blockquote>
        <p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
      </div>
    </blockquote>
    <br>
  </body>
</html>