Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Thu, 23 May 2024 14:21:27 GMT, Marius Hanl wrote: > That is exactly what I also figured out. If a second new nested event loop is > started directly after the first one was requested to leave, the native code > will never 'return'. That's why this code exists: > https://github.com/openjdk/jfx/blob/master/modules/javafx.graphics/src/main/java/com/sun/glass/ui/EventLoop.java#L118 > which I slightly modified to not run `invokeLater` in my PR. I think the invokeLater call is required. On Mac and Windows calls into Glass can only affect the innermost loop. For each loop you want to exit you have to call `Application.leaveNestedEventLoop` and then allow the execution stack to unwind to Glass so it can remove the loop. Only then can you initiate the process of leaving the next loop. So if there’s multiple loops in a LEAVING state each one needs to be handled in a separate runnable so the execution stack can unwind between runnables. When leaving the innermost loop the steps of interest are: 1. call Application.leaveNestedEventLoop 2. disable the InvokeLaterDispatcher 3. unwind the execution stack to glass 4. enable the InvokeLaterDispatcher My tweak to the code ensures that the InvokeLaterDispatcher is re-enabled if we start at step 1 but enter a new event loop before we can reach step 3. On Mac and Windows we’ll always restart the leaving process at step 1 for all loops. That’s not happening on Linux, the old loop is leaving without starting at step 1. I’m pretty sure this is opening a window where the InvokeLaterDispatcher can dispatch a runnable to the old loop while it’s leaving. That’s not supposed to happen but I’m not sure what the consequences might be on Linux (I know it would be very bad on Mac). - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2137836685
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen [v9]
> This PR fixes the dialog freeze problem once and for all. > > This one is a bit tricky to understand, here is how it works: > This bug happens on every platform, although the implementation of nested > event loops differs on every platform. > E.g. on Linux we use `gtk_main` and `gtk_main_quit`, on Windows and Mac we > have an own implementation of a nested event loop (while loop), controlled by > a boolean flag. > > Funny enough, the reason why this bug happens is always the same: Timing. > > 1. When we hide a dialog, `_leaveNestedEventLoop` is called. > 2. This will call native code to get out of the nested event loop, e.g. on > Windows we try to break out of the while loop with a boolean flag, on Linux > we call `gtk_main_quit`. > 3. Now, if we immediately open a new dialog, we enter a new nested event loop > via `_enterNestedEventLoop`, as a consequence we do not break out of the > while loop on Windows (the flag is set back again, the while loop is still > running), and we do not return from `gtk_main` on Linux. > 4. And this will result in the Java code never returning and calling > `notifyLeftNestedEventLoop`, which we need to recover the UI. > > So it is actually not trivial to fix this problem, and we can not really do > anything on the Java side. We may can try to wait until one more frame has > run so that things will hopefully be right, but that sounds rather hacky. > > I therefore analyzed, if we even need to return from `_enterNestedEventLoop`. > Turns out, we don't need to. > There is a return value which we actually do not use (it does not have any > meaning to us, other that it is used inside an assert statement). > ~Without the need of a return value, we also do not need to care when > `_enterNestedEventLoop` is returning - instead we cleanup and call > `notifyLeftNestedEventLoop` in `_leaveNestedEventLoop`, after the native code > was called.~ > See below for more information. To recover the UI (and in general nested > nested event loops ;) we need to set a flag for the `InvokeLaterDispatcher`. > > Lets see if this is the right approach (for all platforms). > Testing appreciated. > # > - [x] Tested on Windows > - [x] Tested on Linux > - [x] Tested on Mac > - [ ] Tested on iOS (although the nested event loop code is the same as for > Mac) (I would appreciate if someone can do this as I have no access to an iOS > device) > - [x] Adjust copyright > - [x] Write Systemtest > - [x] Document the new behaviour - in general, there should be more > information what to expect Marius Hanl has updated the pull request incrementally with one additional commit since the last revision: Fix javadoc - Changes: - all: https://git.openjdk.org/jfx/pull/1324/files - new: https://git.openjdk.org/jfx/pull/1324/files/ec43f2e3..ede84ef1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx=1324=08 - incr: https://webrevs.openjdk.org/?repo=jfx=1324=07-08 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1324.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1324/head:pull/1324 PR: https://git.openjdk.org/jfx/pull/1324
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Tue, 14 May 2024 18:42:47 GMT, Martin Fox wrote: > On Linux leaveNestedEventLoop makes changes in glass that cannot be erased or > undone (it calls gtk_main_quit which updates internal GTK state that we don’t > have access to). In the end GTK will exit the loops in the correct order but > it will exit loop A before the core code has a chance to call > Application.leaveNestedEventLoop again. This is throwing off the bookkeeping > including some debug checks. That is exactly what I also figured out. If a second new nested event loop is started directly after the first one was requested to leave, the native code will never 'return'. That's why this code exists: https://github.com/openjdk/jfx/blob/master/modules/javafx.graphics/src/main/java/com/sun/glass/ui/EventLoop.java#L118 which I slightly modified to not run `invokeLater` in my PR. Otherwise it would never return any value and code after `enterNestedEventLoop` is never called: Object o = Platform.enterNestedEventLoop(this); System.out.println(o); // <- never called And since you fixed the event jam so that we are not stuck anymore and Linux is implemented different with a global stateful variable, we will get that 'inconsistency', which I don't think is relevant or a problem here, hence I removed it in my PR. I also don't found any other way to deal with that situation, as you also stated, there is nothing else we can do, and while the other OS implementation have some kind of while loop where we can try to implement something, on the Linux side we completely rely on `gtk_main` and `gtk_main_quit`. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2127252021
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen [v8]
> This PR fixes the dialog freeze problem once and for all. > > This one is a bit tricky to understand, here is how it works: > This bug happens on every platform, although the implementation of nested > event loops differs on every platform. > E.g. on Linux we use `gtk_main` and `gtk_main_quit`, on Windows and Mac we > have an own implementation of a nested event loop (while loop), controlled by > a boolean flag. > > Funny enough, the reason why this bug happens is always the same: Timing. > > 1. When we hide a dialog, `_leaveNestedEventLoop` is called. > 2. This will call native code to get out of the nested event loop, e.g. on > Windows we try to break out of the while loop with a boolean flag, on Linux > we call `gtk_main_quit`. > 3. Now, if we immediately open a new dialog, we enter a new nested event loop > via `_enterNestedEventLoop`, as a consequence we do not break out of the > while loop on Windows (the flag is set back again, the while loop is still > running), and we do not return from `gtk_main` on Linux. > 4. And this will result in the Java code never returning and calling > `notifyLeftNestedEventLoop`, which we need to recover the UI. > > So it is actually not trivial to fix this problem, and we can not really do > anything on the Java side. We may can try to wait until one more frame has > run so that things will hopefully be right, but that sounds rather hacky. > > I therefore analyzed, if we even need to return from `_enterNestedEventLoop`. > Turns out, we don't need to. > There is a return value which we actually do not use (it does not have any > meaning to us, other that it is used inside an assert statement). > ~Without the need of a return value, we also do not need to care when > `_enterNestedEventLoop` is returning - instead we cleanup and call > `notifyLeftNestedEventLoop` in `_leaveNestedEventLoop`, after the native code > was called.~ > See below for more information. To recover the UI (and in general nested > nested event loops ;) we need to set a flag for the `InvokeLaterDispatcher`. > > Lets see if this is the right approach (for all platforms). > Testing appreciated. > # > - [x] Tested on Windows > - [x] Tested on Linux > - [x] Tested on Mac > - [ ] Tested on iOS (although the nested event loop code is the same as for > Mac) (I would appreciate if someone can do this as I have no access to an iOS > device) > - [x] Adjust copyright > - [x] Write Systemtest > - [x] Document the new behaviour - in general, there should be more > information what to expect Marius Hanl has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 11 additional commits since the last revision: - Merge branch 'master' of https://github.com/openjdk/jfx into JDK-8285893-dialog-freezing-略 - Integrate changes as outline by beldenfox - test for multiple nested event loops - try leave outer loop after finishing inner loop - update copyright - trigger an outer nested event loop leave attempt - do not attempt to leave eventloop after leaving another eventloop - Merge branch 'master' of https://github.com/openjdk/jfx into JDK-8285893-dialog-freezing-略 - Merge remote-tracking branch 'openjfx/master' into JDK-8285893-dialog-freezing-略 - JDK-8285893: Decrement nestedEventLoopCounter in leaveNestedEventLoop - ... and 1 more: https://git.openjdk.org/jfx/compare/ea0d1a15...ec43f2e3 - Changes: - all: https://git.openjdk.org/jfx/pull/1324/files - new: https://git.openjdk.org/jfx/pull/1324/files/bba7fc23..ec43f2e3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx=1324=07 - incr: https://webrevs.openjdk.org/?repo=jfx=1324=06-07 Stats: 86781 lines in 1031 files changed: 46446 ins; 20952 del; 19383 mod Patch: https://git.openjdk.org/jfx/pull/1324.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1324/head:pull/1324 PR: https://git.openjdk.org/jfx/pull/1324
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Mon, 6 May 2024 21:11:35 GMT, Martin Fox wrote: > I'll look into the Linux failure. The core EventLoop code passes an object > into the application's leaveNestedEventLoop and expects to see that object > returned from the applications's matching enterNestedEventLoop call. On Mac > and Windows this object is passed through to glass as an argument on the > stack. On Linux this value is handled as an application global. I suspect the > Linux bookkeeping isn't robust enough to handle this case but it will take a > bit to nail down the details. There is one additional change I made, which might be relevant for Linux: https://github.com/openjdk/jfx/pull/1324/files#diff-af779aafb50953f57cab2478dd220d0322592b60e92065cf658644866572b7e7R117 Worth to check. I remember that the code there was problematic to me. Otherwise this looks good. https://github.com/openjdk/jfx/pull/1324 also cleans up the unused return value which is allocated in the C++/Objective-C side, but never really used on the Java side. So might be worth to do at some point, but I would agree to do the minimal changes first. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2114266915
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Sat, 4 May 2024 22:55:13 GMT, Martin Fox wrote: > This PR is based on a discussion that happened over in PR #1324. Some of this > explanation is copied from that thread. > > When `exitNestedEventLoop` is called on the innermost loop the > invokeLaterDispatcher suspends operation until the loop finishes. But if you > immediately start a new event loop the previous one won't finish and the > dispatcher will jam up and stop dispatching indefinitely. > > When the invokeLaterDispatcher is told that the innermost loop is exiting it > sets `leavingNestedEventLoop` to true expecting it to be set to false when > the loop actually exits. When the dispatcher is told that a new event loop > has started it is not clearing `leavingNestedEventLoop` which is causing the > jam. Basically it should follow the same logic used in glass; leaving the > innermost loop updates a boolean indicating that the loop should exit but if > a new loop is started the boolean is set back to a running state since it now > applies to the new loop, not the previous one. > > I suspect the invokeLaterDispatcher exists in part to deal with the specifics > of how deferred runnables are handled on the Mac. I investigated this a bit > and wrote up some comments in the Mac glass code. I now understand what’s going wrong on Linux but I don’t know how to fix it. When the test case tries to leave the innermost loop (let’s call it A) the cross-platform Java code calls Application.leaveNestedEventLoop to tell glass that the loop should exit. But before the loop can exit the test case starts a new loop leading to a call to Application.enterNestedEventLoop. On Mac the leaveNestedEventLoop call sets a few global state variables in glass and the enterNestedEventLoop call wipes out all those changes. So as far as glass is concerned the leaveNestedEventLoop call was never made. This works because the cross-platform Java code is holding onto an object that represents loop A; it’s down one level in the event loop stack and marked as LEAVING. When that object reaches the top of the event loop stack the core will once again call Application.leaveNestedEventLoop to exit loop A. On Linux leaveNestedEventLoop makes changes in glass that cannot be erased or undone (it calls gtk_main_quit which updates internal GTK state that we don’t have access to). In the end GTK will exit the loops in the correct order but it will exit loop A before the core code has a chance to call Application.leaveNestedEventLoop again. This is throwing off the bookkeeping including some debug checks. (JavaFX struggles with this scenario because the original test case behaves in such an unexpected way. While processing a click event on a modal stage the event handler hides that modal and then immediately starts a new modal. The original modal can’t really go away; the handler for the click event originated there and is still in progress. That first modal might not be visible but it can’t truly close until the second modal is dismissed.) - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2110892622
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Sat, 4 May 2024 22:55:13 GMT, Martin Fox wrote: > This PR is based on a discussion that happened over in PR #1324. Some of this > explanation is copied from that thread. > > When `exitNestedEventLoop` is called on the innermost loop the > invokeLaterDispatcher suspends operation until the loop finishes. But if you > immediately start a new event loop the previous one won't finish and the > dispatcher will jam up and stop dispatching indefinitely. > > When the invokeLaterDispatcher is told that the innermost loop is exiting it > sets `leavingNestedEventLoop` to true expecting it to be set to false when > the loop actually exits. When the dispatcher is told that a new event loop > has started it is not clearing `leavingNestedEventLoop` which is causing the > jam. Basically it should follow the same logic used in glass; leaving the > innermost loop updates a boolean indicating that the loop should exit but if > a new loop is started the boolean is set back to a running state since it now > applies to the new loop, not the previous one. > > I suspect the invokeLaterDispatcher exists in part to deal with the specifics > of how deferred runnables are handled on the Mac. I investigated this a bit > and wrote up some comments in the Mac glass code. I'll look into the Linux failure. The core EventLoop code passes an object into the application's leaveNestedEventLoop and expects to see that object returned from the applications's matching enterNestedEventLoop call. On Mac and Windows this object is passed through to glass as an argument on the stack. On Linux this value is handled as an application global. I suspect the Linux bookkeeping isn't robust enough to handle this case but it will take a bit to nail down the details. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2096926552
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Sat, 4 May 2024 22:55:13 GMT, Martin Fox wrote: > This PR is based on a discussion that happened over in PR #1324. Some of this > explanation is copied from that thread. > > When `exitNestedEventLoop` is called on the innermost loop the > invokeLaterDispatcher suspends operation until the loop finishes. But if you > immediately start a new event loop the previous one won't finish and the > dispatcher will jam up and stop dispatching indefinitely. > > When the invokeLaterDispatcher is told that the innermost loop is exiting it > sets `leavingNestedEventLoop` to true expecting it to be set to false when > the loop actually exits. When the dispatcher is told that a new event loop > has started it is not clearing `leavingNestedEventLoop` which is causing the > jam. Basically it should follow the same logic used in glass; leaving the > innermost loop updates a boolean indicating that the loop should exit but if > a new loop is started the boolean is set back to a running state since it now > applies to the new loop, not the previous one. > > I suspect the invokeLaterDispatcher exists in part to deal with the specifics > of how deferred runnables are handled on the Mac. I investigated this a bit > and wrote up some comments in the Mac glass code. I get the following internal assertion failure when running the test on Linux: NestedEventLoopTest > testCanExitAndThenEnterNewLoop FAILED java.lang.AssertionError: Internal inconsistency - wrong EventLoop at javafx.graphics@23-ea/com.sun.glass.ui.EventLoop.enter(EventLoop.java:108) at javafx.graphics@23-ea/com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:656) at javafx.graphics@23-ea/javafx.application.Platform.enterNestedEventLoop(Platform.java:310) at test.javafx.stage.NestedEventLoopTest.lambda$testCanExitAndThenEnterNewLoop$29(NestedEventLoopTest.java:326 It ran cleanly on Mac and Windows. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2096641134
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Sat, 4 May 2024 22:55:13 GMT, Martin Fox wrote: > This PR is based on a discussion that happened over in PR #1324. Some of this > explanation is copied from that thread. > > When `exitNestedEventLoop` is called on the innermost loop the > invokeLaterDispatcher suspends operation until the loop finishes. But if you > immediately start a new event loop the previous one won't finish and the > dispatcher will jam up and stop dispatching indefinitely. > > When the invokeLaterDispatcher is told that the innermost loop is exiting it > sets `leavingNestedEventLoop` to true expecting it to be set to false when > the loop actually exits. When the dispatcher is told that a new event loop > has started it is not clearing `leavingNestedEventLoop` which is causing the > jam. Basically it should follow the same logic used in glass; leaving the > innermost loop updates a boolean indicating that the loop should exit but if > a new loop is started the boolean is set back to a running state since it now > applies to the new loop, not the previous one. > > I suspect the invokeLaterDispatcher exists in part to deal with the specifics > of how deferred runnables are handled on the Mac. I investigated this a bit > and wrote up some comments in the Mac glass code. This looks like a safe, targeted fix for the problem. It will need to be tested on all platforms with a full run of all system tests. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2096441265
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
On Sat, 4 May 2024 22:55:13 GMT, Martin Fox wrote: > This PR is based on a discussion that happened over in PR #1324. Some of this > explanation is copied from that thread. > > When `exitNestedEventLoop` is called on the innermost loop the > invokeLaterDispatcher suspends operation until the loop finishes. But if you > immediately start a new event loop the previous one won't finish and the > dispatcher will jam up and stop dispatching indefinitely. > > When the invokeLaterDispatcher is told that the innermost loop is exiting it > sets `leavingNestedEventLoop` to true expecting it to be set to false when > the loop actually exits. When the dispatcher is told that a new event loop > has started it is not clearing `leavingNestedEventLoop` which is causing the > jam. Basically it should follow the same logic used in glass; leaving the > innermost loop updates a boolean indicating that the loop should exit but if > a new loop is started the boolean is set back to a running state since it now > applies to the new loop, not the previous one. > > I suspect the invokeLaterDispatcher exists in part to deal with the specifics > of how deferred runnables are handled on the Mac. I investigated this a bit > and wrote up some comments in the Mac glass code. As with the earlier PR, this will need a lot of testing and careful review. @Maran23 I'd be interested in your thoughts on this approach. - PR Comment: https://git.openjdk.org/jfx/pull/1449#issuecomment-2096342944
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen [v7]
On Thu, 7 Mar 2024 22:32:13 GMT, Marius Hanl wrote: >> This PR fixes the dialog freeze problem once and for all. >> >> This one is a bit tricky to understand, here is how it works: >> This bug happens on every platform, although the implementation of nested >> event loops differs on every platform. >> E.g. on Linux we use `gtk_main` and `gtk_main_quit`, on Windows and Mac we >> have an own implementation of a nested event loop (while loop), controlled >> by a boolean flag. >> >> Funny enough, the reason why this bug happens is always the same: Timing. >> >> 1. When we hide a dialog, `_leaveNestedEventLoop` is called. >> 2. This will call native code to get out of the nested event loop, e.g. on >> Windows we try to break out of the while loop with a boolean flag, on Linux >> we call `gtk_main_quit`. >> 3. Now, if we immediately open a new dialog, we enter a new nested event >> loop via `_enterNestedEventLoop`, as a consequence we do not break out of >> the while loop on Windows (the flag is set back again, the while loop is >> still running), and we do not return from `gtk_main` on Linux. >> 4. And this will result in the Java code never returning and calling >> `notifyLeftNestedEventLoop`, which we need to recover the UI. >> >> So it is actually not trivial to fix this problem, and we can not really do >> anything on the Java side. We may can try to wait until one more frame has >> run so that things will hopefully be right, but that sounds rather hacky. >> >> I therefore analyzed, if we even need to return from >> `_enterNestedEventLoop`. Turns out, we don't need to. >> There is a return value which we actually do not use (it does not have any >> meaning to us, other that it is used inside an assert statement). >> ~Without the need of a return value, we also do not need to care when >> `_enterNestedEventLoop` is returning - instead we cleanup and call >> `notifyLeftNestedEventLoop` in `_leaveNestedEventLoop`, after the native >> code was called.~ >> See below for more information. To recover the UI (and in general nested >> nested event loops ;) we need to set a flag for the `InvokeLaterDispatcher`. >> >> Lets see if this is the right approach (for all platforms). >> Testing appreciated. >> # >> - [x] Tested on Windows >> - [x] Tested on Linux >> - [x] Tested on Mac >> - [ ] Tested on iOS (although the nested event loop code is the same as for >> Mac) (I would appreciate if someone can do this as I have no access to an >> iOS device) >> - [x] Adjust copyright >> - [x] Write Systemtest >> - [x] Document the new behaviour - in general, there should be more >> information what to expect > > Marius Hanl has updated the pull request incrementally with one additional > commit since the last revision: > > Integrate changes as outline by beldenfox I just submitted my proposed fix for this issue as PR #1449. - PR Comment: https://git.openjdk.org/jfx/pull/1324#issuecomment-2094495851
RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen
This PR is based on a discussion that happened over in PR #1324. Some of this explanation is copied from that thread. When `exitNestedEventLoop` is called on the innermost loop the invokeLaterDispatcher suspends operation until the loop finishes. But if you immediately start a new event loop the previous one won't finish and the dispatcher will jam up and stop dispatching indefinitely. When the invokeLaterDispatcher is told that the innermost loop is exiting it sets `leavingNestedEventLoop` to true expecting it to be set to false when the loop actually exits. When the dispatcher is told that a new event loop has started it is not clearing `leavingNestedEventLoop` which is causing the jam. Basically it should follow the same logic used in glass; leaving the innermost loop updates a boolean indicating that the loop should exit but if a new loop is started the boolean is set back to a running state since it now applies to the new loop, not the previous one. I suspect the invokeLaterDispatcher exists in part to deal with the specifics of how deferred runnables are handled on the Mac. I investigated this a bit and wrote up some comments in the Mac glass code. - Commit messages: - Merge remote-tracking branch 'upstream/master' into eventloopjam - Background information on how Mac Glass handles invokeLater runnables - Unblock invokeLater runnables when entering new loop just after exiting current one Changes: https://git.openjdk.org/jfx/pull/1449/files Webrev: https://webrevs.openjdk.org/?repo=jfx=1449=00 Issue: https://bugs.openjdk.org/browse/JDK-8285893 Stats: 58 lines in 3 files changed: 58 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1449.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1449/head:pull/1449 PR: https://git.openjdk.org/jfx/pull/1449
Re: RFR: 8285893: Hiding dialog and showing new one causes dialog to be frozen [v7]
On Thu, 7 Mar 2024 22:32:13 GMT, Marius Hanl wrote: >> This PR fixes the dialog freeze problem once and for all. >> >> This one is a bit tricky to understand, here is how it works: >> This bug happens on every platform, although the implementation of nested >> event loops differs on every platform. >> E.g. on Linux we use `gtk_main` and `gtk_main_quit`, on Windows and Mac we >> have an own implementation of a nested event loop (while loop), controlled >> by a boolean flag. >> >> Funny enough, the reason why this bug happens is always the same: Timing. >> >> 1. When we hide a dialog, `_leaveNestedEventLoop` is called. >> 2. This will call native code to get out of the nested event loop, e.g. on >> Windows we try to break out of the while loop with a boolean flag, on Linux >> we call `gtk_main_quit`. >> 3. Now, if we immediately open a new dialog, we enter a new nested event >> loop via `_enterNestedEventLoop`, as a consequence we do not break out of >> the while loop on Windows (the flag is set back again, the while loop is >> still running), and we do not return from `gtk_main` on Linux. >> 4. And this will result in the Java code never returning and calling >> `notifyLeftNestedEventLoop`, which we need to recover the UI. >> >> So it is actually not trivial to fix this problem, and we can not really do >> anything on the Java side. We may can try to wait until one more frame has >> run so that things will hopefully be right, but that sounds rather hacky. >> >> I therefore analyzed, if we even need to return from >> `_enterNestedEventLoop`. Turns out, we don't need to. >> There is a return value which we actually do not use (it does not have any >> meaning to us, other that it is used inside an assert statement). >> ~Without the need of a return value, we also do not need to care when >> `_enterNestedEventLoop` is returning - instead we cleanup and call >> `notifyLeftNestedEventLoop` in `_leaveNestedEventLoop`, after the native >> code was called.~ >> See below for more information. To recover the UI (and in general nested >> nested event loops ;) we need to set a flag for the `InvokeLaterDispatcher`. >> >> Lets see if this is the right approach (for all platforms). >> Testing appreciated. >> # >> - [x] Tested on Windows >> - [x] Tested on Linux >> - [x] Tested on Mac >> - [ ] Tested on iOS (although the nested event loop code is the same as for >> Mac) (I would appreciate if someone can do this as I have no access to an >> iOS device) >> - [x] Adjust copyright >> - [x] Write Systemtest >> - [x] Document the new behaviour - in general, there should be more >> information what to expect > > Marius Hanl has updated the pull request incrementally with one additional > commit since the last revision: > > Integrate changes as outline by beldenfox Please don't close this pull request. I really need this fix. - PR Comment: https://git.openjdk.org/jfx/pull/1324#issuecomment-2089657232