<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">Windows applications often have an “Exit” menu item, but since it isn’t standardized like it is on macOS, calling a quit handler for it would need to be a manual step - but the exact same method for the quit handler could be called, leaving it up to the programmer to continue or not with the application exit depending on the return value. This manual coding isn’t a big deal since you would also need to have some app-specific handling to avoid making an Exit menu item on macOS, where it would look out of place. <div><br></div><div>You could add a standard “requestExit()” method to Platform that you could manually bind to an Exit menu item on Windows or Linux, but it would be automatically called via an internal macOS Quit handler implementation. The implementation of Platform.requestExit() on *all* platforms would call a boolean method if one was registered and then conditionally call Platform.exit() depending on the return value, the default being to always exit if nothing was registered. On macOS it would pass on the value to veto the native Quit handler as needed. <font color="#000000"><span style="caret-color: rgb(0, 0, 0);">I haven’t checked, does Application.stop() get called on macOS if you exit via the Quit menu or Command-Q? If it doesn’t, that’s another benefit. This idea should probably be opt-in via some API or system property, I suppose it would have to be if it changes behaviour of having Application.stop() called in some circumstances. Or you can just make the setting of the handler function the “opt-in”.</span></font></div><div><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><br></span></font><div>Btw, t<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">his reminds me of the long-standing request for system tray support, along with with various other features that have equivalents across multiple OS’, like showing progress on the dock icon, or a numbered badge (for notifications, or unread msgs, etc). I think there are already issues in Jira for these, maybe just as a general request to support some features that AWT/Swing has that JFX is still missing. Most of these features are available on both Mac and Windows, possibly Linux. It would be irritating to code to different APIs for each if it can be avoided, so I agree with going for a platform-neutral way.</span></div><div><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><br></span></font></div><div><font color="#000000"><span style="caret-color: rgb(0, 0, 0);">Cheers, </span></font></div><div><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><br></span></font><div dir="ltr">Scott</div><div dir="ltr"><br><blockquote type="cite">On Sep 19, 2022, at 8:11 PM, Kevin Rushforth <kevin.rushforth@oracle.com> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
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"; }
@font-face { font-family: Calibri; }
@font-face { font-family: "Times New Roman (Body CS)"; }
p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0in; font-size: 10pt; font-family: Calibri, sans-serif; }
a:link, span.MsoHyperlink { color: blue; text-decoration: underline; }
span.EmailStyle19 { font-family: "Courier New", serif; color: windowtext; }
.MsoChpDefault { font-size: 10pt; }
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>
</div></blockquote></div></div></body></html>