<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@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;}
/* Style Definitions */
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;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<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 <openjfx-dev-retn@openjdk.org> on behalf of Kevin Rushforth <kevin.rushforth@oracle.com><br>
<b>Date: </b>Monday, 2022/09/19 at 09:33<br>
<b>To: </b>openjfx-dev@openjdk.org <openjfx-dev@openjdk.org><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">
<openjfx-dev-retn@openjdk.org></a> on behalf of Florian Kirmaier <a href="mailto:florian.kirmaier@gmail.com">
<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">openjfx-dev@openjdk.java.net</a>
<a href="mailto:openjfx-dev@openjdk.java.net"><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">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>
</body>
</html>