From 77f6f06f1d60a0127fa6740311f58b8fd4939445 Mon Sep 17 00:00:00 2001 From: raghucssit Date: Thu, 11 Jan 2024 14:52:41 +0100 Subject: [PATCH] Move selection calculation out of the Job that calculates tool-tip for launch config button. SelectedResourceManager#getCurrentSelection() needs UI thread to determine selection. Job sometimes don't get access to UI for more than 10 secs. So it is good to move selection compute out of the job and pass the selection to job. Fixes https://github.com/eclipse-platform/eclipse.platform/issues/1084 --- .../tests/launching/LaunchManagerTests.java | 53 +++++++++++++++++++ .../LaunchingResourceManager.java | 26 ++++++--- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchManagerTests.java b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchManagerTests.java index 11deb31fa28..f8cfdb473ab 100644 --- a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchManagerTests.java +++ b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchManagerTests.java @@ -17,9 +17,15 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.debug.core.ILaunch; @@ -28,9 +34,13 @@ import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.internal.core.LaunchManager; +import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.tests.launching.CancellingLaunchDelegate.CancellingLaunch; import org.eclipse.debug.tests.launching.ThrowingLaunchDelegate.ThrowingEnum; import org.eclipse.debug.tests.launching.ThrowingLaunchDelegate.ThrowingLaunch; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; import org.junit.Test; /** @@ -503,4 +513,47 @@ public void testThrowingBuildForLaunch() throws Exception { public void testThrowingLaunch() throws Exception { testThrowingLaunchDelegateMethod(ThrowingEnum.launch); } + + /** + * Tooltip calculation was done in Job scheduled by + * LaunchingResourceManager$fMouseListener. This Job was trying to get + * selection from UI using API + * SelectedResourceManager#getCurrentSelection(). For any reason if the UI + * was locked for more than 10 secs + * SelectedResourceManager#getCurrentSelection() API throws an exception as + * it did not find opportunity to get UI thread to fetch selection. + * + * This test case checks if there were any errors were logged while + * calculating tooltip. + * + * + * @throws Exception + */ + @Test + public void testToolTipCalculationLogsError() throws Exception { + LogListener logListener = new LogListener(); + Platform.addLogListener(logListener); + Event event = new Event(); + // Any widget is ok. We just need to check if + // SelectedResourceManager#getCurrentSelection() logs error or not. + Shell shell = DebugUIPlugin.getShell(); + event.widget = shell; + DebugUIPlugin.getDefault().getLaunchingResourceManager().getfMouseListener().mouseEnter(new MouseEvent(event)); + // This will lock this thread(UI) for 15 secs. + Thread.sleep(15000); + assertTrue("Tooltip calculation has logged exception", logListener.getLogs().isEmpty()); + } + + class LogListener implements ILogListener { + private Map logs = new HashMap<>(); + + @Override + public synchronized void logging(IStatus status, String plugin) { + logs.put(plugin, status); + } + + Map getLogs() { + return logs; + } + } } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/LaunchingResourceManager.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/LaunchingResourceManager.java index 900389b1aca..a4dd5e0b163 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/LaunchingResourceManager.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/LaunchingResourceManager.java @@ -138,10 +138,13 @@ public void mouseEnter(MouseEvent e) { if(fUpdateLabel) { fUpdateLabel = false; fCurrentLabels.clear(); + SelectedResourceManager srm = SelectedResourceManager.getDefault(); + IStructuredSelection selection = srm.getCurrentSelection(); + IResource resource = srm.getSelectedResource(); Job job = new Job("Compute launch button tooltip") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { - computeLabels(); + computeLabels(selection, resource); fConfigCache.clear(); fExtCache.clear(); return Status.OK_STATUS; @@ -153,6 +156,15 @@ protected IStatus run(IProgressMonitor monitor) { } }; + /** + * Hook for testing. No one else should use this except tests. + * + * @return + */ + public MouseTrackAdapter getfMouseListener() { + return fMouseListener; + } + /** * Returns if context launching is enabled * @return if context launching is enabled @@ -223,18 +235,18 @@ protected boolean shouldLaunchLast() { } /** - * Computes the current listing of labels for the given IResource context change or the - * current launch history changed event + * Computes the current listing of labels for the given IResource + * context change or the current launch history changed event + * + * @param resource + * @param selection */ - protected void computeLabels() { + protected void computeLabels(IStructuredSelection selection, IResource resource) { ILaunchGroup group = null; ILaunchConfiguration config = null; String label = null; - SelectedResourceManager srm = SelectedResourceManager.getDefault(); - IStructuredSelection selection = srm.getCurrentSelection(); List shortcuts = null; - IResource resource = srm.getSelectedResource(); for (ILaunchLabelChangedListener iLaunchLabelChangedListener : fLabelListeners) { group = iLaunchLabelChangedListener.getLaunchGroup(); if(group != null) {