I always understood Alt+F4 as simply being a keyboard shortcut on Windows for 
closing the window of the active application.  The same as clicking the close 
widget.  I don’t think there is anything special about it.  As far as being an 
equivalent to the macOS Quit action, I don’t think it is quite the same. Does 
an application even know the difference between a window closed with the widget 
vs. Alt+F4? CTRL+F4 closes the current document window or tab - similar to 
Command-W on macOS. 

I’m not aware of any special handlers being called on Windows for these 
shortcuts other than what is called when the equivalent close widget is 
pressed. If I’m wrong about that, then sure, a quit handler for JavaFX could be 
wired in to the same mechanism automatically.  Maybe Linux has an equivalent as 
well, I don’t know.

While we are at it, custom handling for the ‘About’ menu item in the 
application menu is also needed, is it not?  

For now I’m currently using Jan Gassen’s port of NSMenuFX to hook into this 
stuff. https://github.com/0x4a616e/NSMenuFX


Scott

> On Sep 20, 2022, at 5:55 AM, John Hendrikx <john.hendr...@gmail.com> wrote:
> 
> 
> What about Alt + F4 and Ctrl + F4 on Windows?  Alt + F4 closes the 
> application (which works with JavaFX already) and Ctrl + F4 is supposed to 
> close a single window, but that doesn't work for JavaFX.
> 
> Also very much in favor of Keeping the API platform neutral, that's just how 
> Java has worked since its inception.
> 
> --John
> 
> On 20/09/2022 06:25, Scott Palmer wrote:
>> 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.  
>> 
>> 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.  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”.
>> 
>> Btw, this 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.
>> 
>> Cheers, 
>> 
>> Scott
>> 
>>> On Sep 19, 2022, at 8:11 PM, Kevin Rushforth <kevin.rushfo...@oracle.com> 
>>> wrote:
>>> 
>>>  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.
>>> 
>>> 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).
>>> 
>>> -- Kevin
>>> 
>>> 
>>> On 9/19/2022 1:46 PM, Andy Goryachev wrote:
>>>> Thank you, Kevin.  Your insightful feedback always pulls the discussion in 
>>>> the right direction.
>>>>  
>>>> 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.
>>>>  
>>>> 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.
>>>>  
>>>> 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:
>>>>  
>>>> 1. one start starts with a single entry point, like PlatformAPI, described 
>>>> earlier.
>>>>  
>>>> 2. a lookup-based approach, where the client code requests a (possibly 
>>>> fine-grained and narrowly defined) implementation from the system.  For 
>>>> example:
>>>>  
>>>> IMacMenu impl = PlatformAPI.lookup(IMacMenu.class);
>>>>  
>>>> (where IMacMenu is an interface that, in this example, provides access to 
>>>> Mac menu, adding shutdown listeners, and so forth).
>>>>  
>>>> 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).
>>>>  
>>>> This way we are free to extend or version the APIs without modifying the 
>>>> core classes.
>>>>  
>>>> PlatformAPI.isSupported(IMacMenu.class) might provide a way to see whether 
>>>> the capability is present.
>>>>  
>>>> 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.
>>>>  
>>>> What do you think?
>>>>  
>>>> -andy
>>>>  
>>>>  
>>>> From: openjfx-dev <openjfx-dev-r...@openjdk.org> on behalf of Kevin 
>>>> Rushforth <kevin.rushfo...@oracle.com>
>>>> Date: Monday, 2022/09/19 at 09:33
>>>> To: openjfx-dev@openjdk.org <openjfx-dev@openjdk.org>
>>>> Subject: Re: Provide Quit handler for system menu bar
>>>> 
>>>> I like the idea of looking at this holistically, even if we do end up 
>>>> adding such features one at a time.
>>>> 
>>>> 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.
>>>> 
>>>> -- Kevin
>>>> 
>>>> 
>>>> On 9/19/2022 9:06 AM, Andy Goryachev wrote:
>>>> Greetings!
>>>>  
>>>> 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.
>>>>  
>>>> 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:
>>>>  
>>>> These methods allow for querying whether the specific platform APIs are 
>>>> available
>>>>  
>>>> PlatformAPI.isWindows();
>>>> PlatformAPI.isMacOS();
>>>> PlatformAPI.isLinux(); // isUnix()? isPosix() ?
>>>>  
>>>>  
>>>> and these will actually return a service object that provides access to 
>>>> the APIs, or throws some kind of exception:
>>>>  
>>>> IWindowsAPI PlatformAPI.getWindowsAPI();
>>>> IMacOSAPI PlatformAPI.getMacOSAPI();
>>>>  
>>>> 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.
>>>>  
>>>>  
>>>> 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.
>>>>  
>>>> What do you think?
>>>>  
>>>> -andy
>>>>  
>>>>  
>>>>  
>>>>  
>>>> From: openjfx-dev <openjfx-dev-r...@openjdk.org> on behalf of Florian 
>>>> Kirmaier <florian.kirma...@gmail.com>
>>>> Date: Tuesday, 2022/09/13 at 08:11
>>>> To: openjfx-...@openjdk.java.net <openjfx-...@openjdk.java.net>
>>>> Subject: Provide Quit handler for system menu bar
>>>> 
>>>> Hi Everyone,
>>>> 
>>>> In one project, we have to handle the quit-logic for MacOS ourselves,
>>>> when the <quit app> menu entry is used.
>>>> As background information - this menu entry is set in the class 
>>>> com.sun.glass.ui.mac.MacApplication.
>>>> It's basically hard coded. Currently, in this project, the menu entry 
>>>> doesn't work in some cases.
>>>> 
>>>> My Solution would be:
>>>> 
>>>> Provide a method "Platform.setQuiteHandler(Supplier<Boolean>)"
>>>> This handler is called when quit <appname> from the menu is called.
>>>> If the handler returns true, all windows are closed. Otherwise, nothing 
>>>> happens.
>>>> 
>>>> It would look like the following:
>>>> ```
>>>> /**
>>>>  * Sets the handler to be called when the application is about to quit.
>>>>  * Currently, this can only happen on MacOS.
>>>>  *
>>>>  * This handler is called, when the user selects
>>>>  * the "Quit <appname>" from the application menu.
>>>>  * When the provided handler returns true,
>>>>  * the application will close all windows.
>>>>  * If the handler returns false, the application will not quit.
>>>>  *
>>>>  * @param The new quit handler.
>>>>  */
>>>> public static void setQuitHandler(Supplier x) {
>>>>     ...
>>>> }
>>>> ```
>>>> I've created a ticket for this topic. 
>>>> https://bugs.openjdk.org/browse/JDK-8293700
>>>> 
>>>> I've got a working version for this change. 
>>>> According to Kevin Rushforth this need a prior dicussion on the mailing 
>>>> list.
>>>> Any opinion regarding this?
>>>> 
>>>> I could provide a pullrequest, if someone is interested.
>>>> 
>>>> Florian Kirmaier
>>>>  
>>> 

Reply via email to