From 0da504769df58cb2f648d2fcc8048978c7997c5b Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jan 2022 19:59:47 -0500 Subject: [PATCH] ui: set DO_NOTHING_ON_CLOSE close op prior to disposing Disposed frames are still reachable via Window.getWindows() until gcd, and can receive and process events. We don't want the splash screen to close the app if it receives a window close event after being disposed. --- .../main/java/net/runelite/client/ui/SplashScreen.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/SplashScreen.java b/runelite-client/src/main/java/net/runelite/client/ui/SplashScreen.java index 8eca11dd17..3668072a1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/SplashScreen.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/SplashScreen.java @@ -30,7 +30,6 @@ import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; import javax.swing.ImageIcon; @@ -66,7 +65,7 @@ public class SplashScreen extends JFrame implements ActionListener private volatile String subActionText = ""; private volatile String progressText = null; - private SplashScreen() throws IOException + private SplashScreen() { BufferedImage logo = ImageUtil.loadImageResource(SplashScreen.class, "runelite_transparent.png"); @@ -204,6 +203,12 @@ public class SplashScreen extends JFrame implements ActionListener } INSTANCE.timer.stop(); + // The CLOSE_ALL_WINDOWS quit strategy on MacOS dispatches WINDOW_CLOSING events to each frame + // from Window.getWindows. However, getWindows uses weak refs and relies on gc to remove windows + // from its list, causing events to get dispatched to disposed frames. The frames handle the events + // regardless of being disposed and will run the configured close operation. Set the close operation + // to DO_NOTHING_ON_CLOSE prior to disposing to prevent this. + INSTANCE.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); INSTANCE.dispose(); INSTANCE = null; });