Skip to content

Commit e1a5ece

Browse files
committed
Guard shutdown dialog opener against workbench teardown
Review feedback: during postShutdown() the workbench may already be gone, so reaching through PlatformUI via ProgressManagerUtil.safeToOpen is unsafe. Scan display.getShells() for modal shells directly instead, rename the scheduled runnable to openDialogLater to make the schedule/cancel pairing obvious, and document the timerExec(-1, ...) cancel call.
1 parent 44b4cff commit e1a5ece

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.eclipse.swt.graphics.Resource;
6262
import org.eclipse.swt.widgets.Display;
6363
import org.eclipse.swt.widgets.Listener;
64+
import org.eclipse.swt.widgets.Shell;
6465
import org.eclipse.ui.PlatformUI;
6566
import org.eclipse.ui.application.IWorkbenchConfigurer;
6667
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
@@ -79,7 +80,6 @@
7980
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
8081
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
8182
import org.eclipse.ui.internal.ide.undo.WorkspaceUndoMonitor;
82-
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
8383
import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
8484
import org.eclipse.ui.progress.IProgressService;
8585
import org.eclipse.ui.statushandlers.AbstractStatusHandler;
@@ -498,12 +498,12 @@ protected void disconnectFromWorkspace() {
498498

499499
final Display display = Display.getCurrent();
500500
final int longOperationTime = savedLongOperationTime;
501-
final Runnable openDialog = () -> {
502-
if (ProgressManagerUtil.safeToOpen(dialog, null)) {
501+
final Runnable openDialogLater = () -> {
502+
if (!display.isDisposed() && !hasModalShell(display)) {
503503
dialog.open();
504504
}
505505
};
506-
display.timerExec(longOperationTime, openDialog);
506+
display.timerExec(longOperationTime, openDialogLater);
507507

508508
try {
509509
BusyIndicator.showWhile(display, () -> {
@@ -518,7 +518,8 @@ protected void disconnectFromWorkspace() {
518518
}
519519
});
520520
} finally {
521-
display.timerExec(-1, openDialog);
521+
// Cancel openDialogLater if it is still pending; no-op if it already ran.
522+
display.timerExec(-1, openDialogLater);
522523
}
523524

524525
if (!status.isOK()) {
@@ -528,6 +529,16 @@ protected void disconnectFromWorkspace() {
528529
}
529530
}
530531

532+
private static boolean hasModalShell(Display display) {
533+
final int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
534+
for (Shell shell : display.getShells()) {
535+
if (!shell.isDisposed() && shell.isVisible() && (shell.getStyle() & modal) != 0) {
536+
return true;
537+
}
538+
}
539+
return false;
540+
}
541+
531542
@Override
532543
public IAdaptable getDefaultPageInput() {
533544
return ResourcesPlugin.getWorkspace().getRoot();

0 commit comments

Comments
 (0)