From d93628bf06e59a63852a7d51bbd486ff16adb760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= <51790620+jukzi@users.noreply.github.com> Date: Fri, 22 Apr 2022 13:27:41 +0200 Subject: [PATCH] Bug 578871 - use ISchedulableOperation (#18) to prevent UI freeze during UNDO --- .../OperationHistoryActionHandler.java | 32 ++++++++++++++++++- .../META-INF/MANIFEST.MF | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/operations/OperationHistoryActionHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/operations/OperationHistoryActionHandler.java index 2e5c3b0067e..ac11215626a 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/operations/OperationHistoryActionHandler.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/operations/OperationHistoryActionHandler.java @@ -26,10 +26,15 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.ISchedulableOperation; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.LegacyActionTools; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IPartListener; @@ -298,7 +303,32 @@ public final void run() { if (getOperation() instanceof IAdvancedUndoableOperation2) { runInBackground = ((IAdvancedUndoableOperation2) getOperation()).runInBackground(); } - progressDialog.run(runInBackground, true, runnable); + if (runInBackground) { + progressDialog.run(runInBackground, true, runnable); + } else { + final IJobManager manager = Job.getJobManager(); + final ISchedulingRule rule = (getOperation() instanceof ISchedulableOperation) + ? ((ISchedulableOperation) getOperation()).getSchedulingRule() + : null; + if (rule == null) { + progressDialog.run(runInBackground, true, runnable); + } else { + // prevent UI freeze during AutoBuild as in + // org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper#perform + try { + try { + // interrupt autobuild or show Wait/Cancel Dialog: + Runnable r = () -> manager.beginRule(rule, null); + BusyIndicator.showWhile(parent.getDisplay(), r); + } catch (OperationCanceledException e) { + throw new InterruptedException(e.getMessage()); + } + progressDialog.run(runInBackground, true, runnable); // <-- actual work + } finally { + manager.endRule(rule); + } + } + } } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t == null) { diff --git a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF index 8068b1fa385..f2bbb591c70 100644 --- a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF @@ -95,7 +95,7 @@ Export-Package: org.eclipse.e4.ui.workbench.addons.perspectiveswitcher;x-interna org.eclipse.ui.themes, org.eclipse.ui.views, org.eclipse.ui.wizards -Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.19.0,4.0.0)", +Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.25.0,4.0.0)", org.eclipse.help;bundle-version="[3.2.0,4.0.0)", org.eclipse.jface;bundle-version="[3.18.0,4.0.0)", org.eclipse.swt;bundle-version="[3.107.0,4.0.0)",