Skip to content

Commit c389093

Browse files
committed
Fix modal dialogs freezing all IDE windows (#1375)
- Change FileDialog modality from APPLICATION_MODAL to DOCUMENT_MODAL in Base.java, Sketch.java, and ShimAWT.java so file dialogs only block their parent window on Linux/Windows. - Replace orphan Frame() parents in Messages.kt with a helper that uses KeyboardFocusManager to find the active window and creates DOCUMENT_MODAL dialogs, preventing message popups from freezing all IDE windows. Note: Native macOS file dialogs ignore Java modality settings (Apple limitation), but all JOptionPane-based messages are now fixed across all platforms.
1 parent 821d62c commit c389093

File tree

4 files changed

+24
-20
lines changed

4 files changed

+24
-20
lines changed

app/src/processing/app/Base.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,7 @@ public void handleOpenPrompt() {
11551155
// use the front-most window frame for placing file dialog
11561156
FileDialog openDialog =
11571157
new FileDialog(activeEditor, prompt, FileDialog.LOAD);
1158+
openDialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
11581159

11591160
// Only show .pde files as eligible bachelors
11601161
openDialog.setFilenameFilter((dir, name) -> {

app/src/processing/app/Messages.kt

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@ import javax.swing.UIManager
4848

4949
class Messages {
5050
companion object {
51+
52+
/**
53+
* Shows a modal dialog that only blocks its parent window,
54+
* not all windows in the application.
55+
*/
56+
private fun showModalDialog(message: Any, title: String, messageType: Int) {
57+
val activeWindow = java.awt.KeyboardFocusManager
58+
.getCurrentKeyboardFocusManager().activeWindow
59+
val pane = JOptionPane(message, messageType)
60+
val dialog = pane.createDialog(activeWindow, title)
61+
dialog.modalityType = java.awt.Dialog.ModalityType.DOCUMENT_MODAL
62+
dialog.isVisible = true
63+
}
5164
/**
5265
* "No cookie for you" type messages. Nothing fatal or all that
5366
* much of a bummer, but something to notify the user about.
@@ -57,10 +70,7 @@ class Messages {
5770
if (Base.isCommandLine()) {
5871
println("$title: $message")
5972
} else {
60-
JOptionPane.showMessageDialog(
61-
Frame(), message, title,
62-
JOptionPane.INFORMATION_MESSAGE
63-
)
73+
showModalDialog(message, title, JOptionPane.INFORMATION_MESSAGE)
6474
}
6575
}
6676

@@ -77,10 +87,7 @@ class Messages {
7787
if (Base.isCommandLine()) {
7888
println("$title: $message")
7989
} else {
80-
JOptionPane.showMessageDialog(
81-
Frame(), message, title,
82-
JOptionPane.WARNING_MESSAGE
83-
)
90+
showModalDialog(message, title, JOptionPane.WARNING_MESSAGE)
8491
}
8592
e?.printStackTrace()
8693
}
@@ -101,11 +108,7 @@ class Messages {
101108
println("$title: $primary\n$secondary")
102109
} else {
103110
EventQueue.invokeLater {
104-
JOptionPane.showMessageDialog(
105-
JFrame(),
106-
Toolkit.formatMessage(primary, secondary),
107-
title, JOptionPane.WARNING_MESSAGE
108-
)
111+
showModalDialog(Toolkit.formatMessage(primary, secondary), title, JOptionPane.WARNING_MESSAGE)
109112
}
110113
}
111114
e?.printStackTrace()
@@ -122,10 +125,7 @@ class Messages {
122125
if (Base.isCommandLine()) {
123126
System.err.println("$title: $message")
124127
} else {
125-
JOptionPane.showMessageDialog(
126-
Frame(), message, title,
127-
JOptionPane.ERROR_MESSAGE
128-
)
128+
showModalDialog(message, title, JOptionPane.ERROR_MESSAGE)
129129
}
130130
e?.printStackTrace()
131131
System.exit(1)
@@ -151,9 +151,7 @@ class Messages {
151151
val sw = StringWriter()
152152
t!!.printStackTrace(PrintWriter(sw))
153153

154-
JOptionPane.showMessageDialog(
155-
Frame(), // first <br/> clears to the next line
156-
// second <br/> is a shorter height blank space before the trace
154+
showModalDialog(
157155
Toolkit.formatMessage("$message<br/><tt><br/>$sw</tt>"),
158156
title,
159157
if (fatal) JOptionPane.ERROR_MESSAGE else JOptionPane.WARNING_MESSAGE

app/src/processing/app/Sketch.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.awt.Container;
3535
import java.awt.EventQueue;
3636
import java.awt.FileDialog;
37+
import java.awt.Dialog;
3738
import java.awt.event.ActionListener;
3839
import java.awt.event.KeyAdapter;
3940
import java.awt.event.KeyEvent;
@@ -866,6 +867,7 @@ public boolean saveAs() throws IOException {
866867
if (useNative) {
867868
// get new name for folder
868869
FileDialog fd = new FileDialog(editor, PROMPT, FileDialog.SAVE);
870+
fd.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
869871
if (isReadOnly() || isUntitled()) {
870872
// default to the sketchbook folder
871873
fd.setDirectory(Preferences.getSketchbookPath());
@@ -1387,6 +1389,7 @@ public void handleAddFile() {
13871389
String prompt = Language.text("file");
13881390
//FileDialog fd = new FileDialog(new Frame(), prompt, FileDialog.LOAD);
13891391
FileDialog fd = new FileDialog(editor, prompt, FileDialog.LOAD);
1392+
fd.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
13901393
fd.setVisible(true);
13911394

13921395
String directory = fd.getDirectory();

core/src/processing/awt/ShimAWT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static public void selectImpl(final String prompt,
818818

819819
if (PApplet.useNativeSelect) {
820820
FileDialog dialog = new FileDialog(parentFrame, prompt, mode);
821+
dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
821822
if (defaultSelection != null) {
822823
dialog.setDirectory(defaultSelection.getParent());
823824
dialog.setFile(defaultSelection.getName());
@@ -910,6 +911,7 @@ static public void selectFolderImpl(final String prompt,
910911
if (PApplet.platform == PConstants.MACOS && PApplet.useNativeSelect) {
911912
FileDialog fileDialog =
912913
new FileDialog(parentFrame, prompt, FileDialog.LOAD);
914+
fileDialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
913915
if (defaultSelection != null) {
914916
fileDialog.setDirectory(defaultSelection.getAbsolutePath());
915917
}

0 commit comments

Comments
 (0)