Skip to content

Avoid flashing shutdown dialog when save is fast#3929

Merged
vogella merged 4 commits intoeclipse-platform:masterfrom
vogella:fix-shutdown-dialog-flash
Apr 27, 2026
Merged

Avoid flashing shutdown dialog when save is fast#3929
vogella merged 4 commits intoeclipse-platform:masterfrom
vogella:fix-shutdown-dialog-flash

Conversation

@vogella
Copy link
Copy Markdown
Contributor

@vogella vogella commented Apr 23, 2026

Fixes #1269. The IDE's shutdown save dialog currently pops up and vanishes in a blink on fast machines. This change replaces the eager CancelableProgressMonitorJobsDialog with a plain ProgressMonitorJobsDialog that opens only after IProgressService#getLongOperationTime has elapsed; fast shutdowns now just show a busy cursor, slow ones still show a real progress dialog.

The cancel path that went away was effectively broken anyway. Its button only cleared a sub-task label, and the CancelableProgressMonitorWrapper used hard-coded work-amount math (Math.abs(total - 4.0)) to toggle cancellation around history pruning, an assumption that had drifted out of sync with SaveManager. Removing it also drops three no-longer-referenced message keys.

A new IDEWorkbenchAdvisorTest#testShutdownWithSlowSave exercises the delayed-open path via a save participant that sleeps past the long-operation threshold, asserting that the save still completes and hooks fire.

status.merge(e.getStatus());
}
};
final Display display = PlatformUI.getWorkbench().getDisplay();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure workbench is still there at this time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Test Results

   852 files  ±0     852 suites  ±0   53m 22s ⏱️ - 1m 17s
 7 914 tests +1   7 671 ✅ +1  243 💤 ±0  0 ❌ ±0 
20 244 runs  +3  19 589 ✅ +3  655 💤 ±0  0 ❌ ±0 

Results for commit 7c22ccb. ± Comparison against base commit 233d793.

♻️ This comment has been updated with latest results.

@vogella vogella marked this pull request as ready for review April 24, 2026 08:49
@vogella
Copy link
Copy Markdown
Contributor Author

vogella commented Apr 24, 2026

Using this now in a custom SDK builds, it is please to close the IDE with this "non-flashing" patch. Thanks @HeikoKlare for the implementation suggestions.

}
});
} finally {
display.timerExec(-1, openDialog);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display.timerExec(-1, openDialog);

Why timerExec and why "-1"? The code will be not executed on Linux!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timerExec(-1, openDialogLater) is the documented SWT idiom for cancelling a previously scheduled runnable, and it behaves the same on all three platforms. The javadoc states "If milliseconds is less than zero, the runnable is not executed," and each Display implementation matches the Runnable by reference in timerList and cancels the native timer before returning: GTK calls g_source_remove, win32 calls OS.KillTimer, and cocoa calls timer.invalidate() / release(). That is exactly the intent here: schedule openDialogLater to open the dialog after the long-operation threshold, and cancel it in finally if the save already finished, so no dialog appears on fast shutdowns. I pushed a small rename (openDialog -> openDialogLater) and a one-line comment on the cancel to make the schedule/cancel pairing explicit.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reduces UI flicker during fast shutdown by delaying the shutdown save progress dialog until the long-operation threshold is exceeded, while preserving correct workspace-save behavior and adding regression coverage for slow saves.

Changes:

  • Replace the eager/cancelable shutdown save dialog with a delayed-open ProgressMonitorJobsDialog + busy cursor approach.
  • Remove now-unused cancellation/history-compaction message keys and their NLS fields.
  • Add a shutdown regression test that forces a slow workspace save to exercise the delayed-open path.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/org.eclipse.ui.ide.application.tests/src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisorTest.java Adds a regression test that simulates a slow save participant during shutdown.
bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties Removes obsolete message keys tied to the removed cancel/history-compaction path.
bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java Removes corresponding unused NLS fields.
bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java Implements delayed dialog opening during workspace disconnect/save at shutdown and removes broken cancel support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +501 to +505
final Runnable openDialog = () -> {
if (ProgressManagerUtil.safeToOpen(dialog, null)) {
dialog.open();
}
};
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openDialog calls ProgressManagerUtil.safeToOpen(...), which internally reaches through PlatformUI.getWorkbench() (see org.eclipse.ui.internal.progress.ProgressManagerUtil#getModalShellExcluding). Since disconnectFromWorkspace() is invoked from postShutdown(), the workbench may already be stopped/tearing down, and this can throw (or behave unpredictably) during shutdown. Consider either guarding the callback with PlatformUI.isWorkbenchRunning() (and skipping the dialog when false) or avoiding ProgressManagerUtil here by checking for modal shells via the already-captured Display (e.g., display.getShells()) before calling dialog.open().

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

vogella added 3 commits April 27, 2026 06:34
Replace the CancelableProgressMonitorJobsDialog used during workspace
shutdown with a plain ProgressMonitorJobsDialog that opens only after
IProgressService#getLongOperationTime has elapsed. During a fast save
only a busy cursor is shown, which fixes issue 1269.

The previous implementation eagerly opened the dialog and wired a cancel
button whose only effect was to clear a sub-task label. Its
CancelableProgressMonitorWrapper relied on hard-coded work-amount math
to toggle cancellation around the history-pruning phase, an assumption
that drifted out of sync with SaveManager. That plumbing is removed
along with its now-unused messages, since cancelling shutdown is no
longer offered.
Avoid calling PlatformUI.getWorkbench() from disconnectFromWorkspace(),
which runs from postShutdown() and may execute (via the workspace-locked
timerExec retry) after the workbench has been torn down. The display is
fetched via Display.getCurrent(), matching the existing pattern in
postShutdown(), and the long-operation time is captured in initialize().
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.
@vogella vogella force-pushed the fix-shutdown-dialog-flash branch from 5b053da to e1a5ece Compare April 27, 2026 04:34
The shutdown test hard-coded a 1200ms sleep based on the current 800ms
default of IProgressService#getLongOperationTime(). Read the live value
in postStartup() and add a fixed margin so the test still exercises
the delayed-open path if the platform default changes.
@vogella vogella merged commit afacf90 into eclipse-platform:master Apr 27, 2026
18 checks passed
@vogella vogella deleted the fix-shutdown-dialog-flash branch April 27, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Closing Eclipse IDE shows flashing popup if closing is really fast

3 participants