From d6f7a2c8b2d7d215edab2278f507914729e1735c Mon Sep 17 00:00:00 2001 From: Sougandh S Date: Fri, 5 Jun 2026 13:47:51 +0530 Subject: [PATCH] Add support for the Resume Other Threads operation. Introduces a new debug command handler and action that resumes all suspended threads in the same debug target except the selected thread. This allows developers to continue execution of other suspended threads while keeping the current thread suspended for inspection. --- .../META-INF/MANIFEST.MF | 2 +- .../core/commands/IResumeOthersHandler.java | 28 ++ .../core/commands/CommandAdapterFactory.java | 9 + .../core/commands/ResumeOthersCommand.java | 67 ++++ .../eclipse/debug/tests/AutomatedSuite.java | 4 +- .../tests/ui/ResumeOthersCommandTests.java | 326 ++++++++++++++++++ debug/org.eclipse.debug.ui/plugin.properties | 6 +- debug/org.eclipse.debug.ui/plugin.xml | 23 ++ .../internal/ui/actions/ActionMessages.java | 2 + .../ui/actions/ActionMessages.properties | 2 + .../actions/ResumeOthersCommandAction.java | 71 ++++ .../ResumeOthersCommandActionDelegate.java | 64 ++++ .../actions/ResumeOthersCommandHandler.java | 33 ++ .../internal/ui/views/launch/LaunchView.java | 12 +- 14 files changed, 645 insertions(+), 4 deletions(-) create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/commands/IResumeOthersHandler.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/ResumeOthersCommand.java create mode 100644 debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/ui/ResumeOthersCommandTests.java create mode 100644 debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandAction.java create mode 100644 debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandActionDelegate.java create mode 100644 debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandHandler.java diff --git a/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF index 0da7e243db5..25dd2cac8fd 100644 --- a/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true -Bundle-Version: 3.23.400.qualifier +Bundle-Version: 3.24.0.qualifier Bundle-Activator: org.eclipse.debug.core.DebugPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/commands/IResumeOthersHandler.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/commands/IResumeOthersHandler.java new file mode 100644 index 00000000000..86b7804f854 --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/commands/IResumeOthersHandler.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core.commands; + +/** + * A resume others handler typically resumes all suspended threads associated + * with the same debug target, excluding the selected thread. + *

+ * Clients may implement this interface. The debug platform provides a "Resume + * Others" action that delegates to this handler interface. + *

+ * + * @since 3.24 + */ +public interface IResumeOthersHandler extends IDebugCommandHandler { + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/CommandAdapterFactory.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/CommandAdapterFactory.java index e0ea4e64bf1..7f1da866362 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/CommandAdapterFactory.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/CommandAdapterFactory.java @@ -18,6 +18,7 @@ import org.eclipse.debug.core.commands.IDisconnectHandler; import org.eclipse.debug.core.commands.IDropToFrameHandler; import org.eclipse.debug.core.commands.IResumeHandler; +import org.eclipse.debug.core.commands.IResumeOthersHandler; import org.eclipse.debug.core.commands.IStepFiltersHandler; import org.eclipse.debug.core.commands.IStepIntoHandler; import org.eclipse.debug.core.commands.IStepOverHandler; @@ -31,6 +32,7 @@ import org.eclipse.debug.core.model.IStep; import org.eclipse.debug.core.model.ISuspendResume; import org.eclipse.debug.core.model.ITerminate; +import org.eclipse.debug.core.model.IThread; /** * Adapter factory for debug commands. @@ -48,6 +50,7 @@ public class CommandAdapterFactory implements IAdapterFactory { private static IDisconnectHandler fgDisconnectCommand = new DisconnectCommand(); private static ISuspendHandler fgSuspendCommand = new SuspendCommand(); private static IResumeHandler fgResumeCommand = new ResumeCommand(); + private static IResumeOthersHandler fgResumeOthersCommand = new ResumeOthersCommand(); private static IStepFiltersHandler fgStepFiltersCommand = new StepFiltersCommand(); @SuppressWarnings("unchecked") @@ -91,6 +94,11 @@ public T getAdapter(Object adaptableObject, Class adapterType) { return (T) fgResumeCommand; } } + if (IResumeOthersHandler.class.equals(adapterType)) { + if (adaptableObject instanceof ISuspendResume && adaptableObject instanceof IThread) { + return (T) fgResumeOthersCommand; + } + } if (IDisconnectHandler.class.equals(adapterType)) { if (adaptableObject instanceof IDisconnect) { return (T) fgDisconnectCommand; @@ -113,6 +121,7 @@ public Class[] getAdapterList() { IStepReturnHandler.class, ISuspendHandler.class, IResumeHandler.class, + IResumeOthersHandler.class, IDropToFrameHandler.class, IDisconnectHandler.class, IStepFiltersHandler.class}; diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/ResumeOthersCommand.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/ResumeOthersCommand.java new file mode 100644 index 00000000000..66265b1d4cc --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/commands/ResumeOthersCommand.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.core.commands; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.IRequest; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IResumeOthersHandler; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IThread; + +/** + * Default resume others command for the standard debug model. + * + * @since 3.3 + */ +public class ResumeOthersCommand extends SuspendCommand implements IResumeOthersHandler { + + @Override + protected void execute(Object target) throws CoreException { + IThread currentThread = (IThread) target; + if (currentThread.canResume()) { + currentThread.resume(); + } + } + @Override + protected void doExecute(Object[] targets, IProgressMonitor monitor, IRequest request) throws CoreException { + + Set selectedThreads = Arrays.stream(targets).map(IThread.class::cast).collect(Collectors.toSet()); + + IDebugTarget debugTarget = ((IThread) targets[0]).getDebugTarget(); + + for (IThread thread : debugTarget.getThreads()) { + if (!selectedThreads.contains(thread)) { + execute(thread); + monitor.worked(1); + } + } + } + + @Override + protected boolean isExecutable(Object target) { + return ((IThread) target).canResume(); + } + + @Override + protected Object getEnabledStateJobFamily(IDebugCommandRequest request) { + return IResumeOthersHandler.class; + } + +} diff --git a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java index efd2349e0c8..9ca4736a1db 100644 --- a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java +++ b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2023 IBM Corporation and others. + * Copyright (c) 2009, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -48,6 +48,7 @@ import org.eclipse.debug.tests.statushandlers.StatusHandlerTests; import org.eclipse.debug.tests.stepfilters.StepFiltersTests; import org.eclipse.debug.tests.ui.LaunchConfigurationTabGroupViewerTest; +import org.eclipse.debug.tests.ui.ResumeOthersCommandTests; import org.eclipse.debug.tests.ui.VariableValueEditorManagerTests; import org.eclipse.debug.tests.view.memory.MemoryRenderingTests; import org.eclipse.debug.tests.view.memory.TableRenderingTests; @@ -142,6 +143,7 @@ // Logical structure LogicalStructureCacheTest.class, // + ResumeOthersCommandTests.class, }) public class AutomatedSuite { } diff --git a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/ui/ResumeOthersCommandTests.java b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/ui/ResumeOthersCommandTests.java new file mode 100644 index 00000000000..9719edfadc0 --- /dev/null +++ b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/ui/ResumeOthersCommandTests.java @@ -0,0 +1,326 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.tests.ui; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.IRequest; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.internal.core.commands.ResumeOthersCommand; +import org.junit.jupiter.api.Test; + +public class ResumeOthersCommandTests { + + @Test + public void testResumeOthers() throws Exception { + + FakeDebugTarget target = new FakeDebugTarget(); + + FakeThread threadA = new FakeThread(target); + FakeThread threadB = new FakeThread(target); + FakeThread threadC = new FakeThread(target); + + target.setThreads(threadA, threadB, threadC); + + assertTrue(threadA.isSuspended()); + assertTrue(threadB.isSuspended()); + assertTrue(threadC.isSuspended()); + + TestResumeOthersCommand command = new TestResumeOthersCommand(); + + command.run(new Object[] { threadA }); + + assertTrue(threadA.isSuspended()); + assertFalse(threadB.isSuspended()); + assertFalse(threadC.isSuspended()); + } + + private static class TestResumeOthersCommand extends ResumeOthersCommand { + + void run(Object[] targets) throws Exception { + doExecute(targets, new NullProgressMonitor(), (IRequest) null); + } + } + + private static class FakeDebugTarget implements IDebugTarget { + + private IThread[] threads; + + void setThreads(IThread... threads) { + this.threads = threads; + } + + @Override + public IThread[] getThreads() { + return threads; + } + + @Override + public String getModelIdentifier() { + return null; + } + + @Override + public IDebugTarget getDebugTarget() { + return null; + } + + @Override + public ILaunch getLaunch() { + return null; + } + + @Override + public T getAdapter(Class adapter) { + return null; + } + + @Override + public boolean canTerminate() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public void terminate() throws DebugException { + + } + + @Override + public boolean canResume() { + return false; + } + + @Override + public boolean canSuspend() { + return false; + } + + @Override + public boolean isSuspended() { + return false; + } + + @Override + public void resume() throws DebugException { + } + + @Override + public void suspend() throws DebugException { + } + + @Override + public void breakpointAdded(IBreakpoint breakpoint) { + } + + @Override + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { + } + + @Override + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { + } + + @Override + public boolean canDisconnect() { + return false; + } + + @Override + public void disconnect() throws DebugException { + + } + + @Override + public boolean isDisconnected() { + return false; + } + + @Override + public boolean supportsStorageRetrieval() { + return false; + } + + @Override + public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { + return null; + } + + @Override + public IProcess getProcess() { + return null; + } + + @Override + public boolean hasThreads() throws DebugException { + return false; + } + + @Override + public String getName() throws DebugException { + return null; + } + + @Override + public boolean supportsBreakpoint(IBreakpoint breakpoint) { + return false; + } + } + + private static class FakeThread implements IThread { + + private boolean suspended = true; + private final IDebugTarget target; + + FakeThread(IDebugTarget target) { + this.target = target; + } + + @Override + public boolean canResume() { + return suspended; + } + + @Override + public void resume() { + suspended = false; + } + + @Override + public boolean isSuspended() { + return suspended; + } + + @Override + public IDebugTarget getDebugTarget() { + return target; + } + + @Override + public boolean canSuspend() { + return !suspended; + } + + @Override + public void suspend() { + suspended = true; + } + + @Override + public String getModelIdentifier() { + return null; + } + + @Override + public ILaunch getLaunch() { + return null; + } + + @Override + public T getAdapter(Class adapter) { + return null; + } + + @Override + public boolean canStepInto() { + return false; + } + + @Override + public boolean canStepOver() { + return false; + } + + @Override + public boolean canStepReturn() { + return false; + } + + @Override + public boolean isStepping() { + return false; + } + + @Override + public void stepInto() throws DebugException { + } + + @Override + public void stepOver() throws DebugException { + } + + @Override + public void stepReturn() throws DebugException { + } + + @Override + public boolean canTerminate() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public void terminate() throws DebugException { + } + + @Override + public IStackFrame[] getStackFrames() throws DebugException { + return null; + } + + @Override + public boolean hasStackFrames() throws DebugException { + + return false; + } + + @Override + public int getPriority() throws DebugException { + return 0; + } + + @Override + public IStackFrame getTopStackFrame() throws DebugException { + return null; + } + + @Override + public String getName() throws DebugException { + return null; + } + + @Override + public IBreakpoint[] getBreakpoints() { + return null; + } + } +} \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/plugin.properties b/debug/org.eclipse.debug.ui/plugin.properties index 7238fb2d65e..104e6a5d502 100644 --- a/debug/org.eclipse.debug.ui/plugin.properties +++ b/debug/org.eclipse.debug.ui/plugin.properties @@ -426,4 +426,8 @@ prototype.decorator.description = Decorates launch configurations that are marke breakpointLabel.label= Label breakpointLabel.tooltip= Provide a custom label to quickly identify breakpoint breakpointLabelCommand = EditBreakpointLabel -breakpointLabelCommand.description = Opens inline editor to change breakpoint label \ No newline at end of file +breakpointLabelCommand.description = Opens inline editor to change breakpoint label + +ResumeOthers.name = Resume Others +ResumeOthers.description= Resume all other suspended threads in the same debug target +ResumeOthersAction.label = Resume Others \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/plugin.xml b/debug/org.eclipse.debug.ui/plugin.xml index cb04a05a725..d12eeb62fbb 100644 --- a/debug/org.eclipse.debug.ui/plugin.xml +++ b/debug/org.eclipse.debug.ui/plugin.xml @@ -419,6 +419,16 @@ toolbarPath="org.eclipse.debug.ui.main.toolbar/threadGroup" initialEnabled="false"> + + + + + + getCommandType() { + return IResumeOthersHandler.class; + } + + @Override + public ImageDescriptor getDisabledImageDescriptor() { + return null; + } + + @Override + public ImageDescriptor getHoverImageDescriptor() { + return null; + } + + @Override + public ImageDescriptor getImageDescriptor() { + return null; + } +} diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandActionDelegate.java new file mode 100644 index 00000000000..cbe4263b113 --- /dev/null +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandActionDelegate.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.debug.internal.ui.commands.actions; + +import org.eclipse.debug.ui.actions.DebugCommandAction; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IActionDelegate2; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +/** + * Resume others action delegate. + * + * @since 3.3 + */ +public class ResumeOthersCommandActionDelegate implements IWorkbenchWindowActionDelegate, IActionDelegate2 { + + private final DebugCommandAction fDebugAction = new ResumeOthersCommandAction(); + + @Override + public void dispose() { + fDebugAction.dispose(); + } + + @Override + public void init(IWorkbenchWindow window) { + fDebugAction.init(window); + } + + @Override + public void run(IAction action) { + fDebugAction.run(); + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + // do nothing + } + + @Override + public void init(IAction action) { + fDebugAction.setActionProxy(action); + + } + + @Override + public void runWithEvent(IAction action, Event event) { + run(action); + } +} diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandHandler.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandHandler.java new file mode 100644 index 00000000000..0f0c1235d07 --- /dev/null +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/ResumeOthersCommandHandler.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + * IBM Corporation - bug fixing + *******************************************************************************/ +package org.eclipse.debug.internal.ui.commands.actions; + +import org.eclipse.debug.core.commands.IResumeOthersHandler; +import org.eclipse.debug.ui.actions.DebugCommandHandler; + +/** + * Default handler for command. It ensures that the keyboard accelerator works even + * if the menu action set is not enabled. + * + * @since 3.8 + */ +public class ResumeOthersCommandHandler extends DebugCommandHandler { + + @Override + protected Class getCommandType() { + return IResumeOthersHandler.class; + } + +} diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java index c7227b7a33a..894a755a0c1 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java @@ -42,6 +42,7 @@ import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DelegatingModelPresentation; @@ -52,6 +53,7 @@ import org.eclipse.debug.internal.ui.commands.actions.DropToFrameCommandAction; import org.eclipse.debug.internal.ui.commands.actions.RestartCommandAction; import org.eclipse.debug.internal.ui.commands.actions.ResumeCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.ResumeOthersCommandAction; import org.eclipse.debug.internal.ui.commands.actions.StepIntoCommandAction; import org.eclipse.debug.internal.ui.commands.actions.StepOverCommandAction; import org.eclipse.debug.internal.ui.commands.actions.StepReturnCommandAction; @@ -154,6 +156,8 @@ public class LaunchView extends AbstractDebugView private static final String RESUME = "resume"; //$NON-NLS-1$ + private static final String RESUME_OTHERS = "resume_others"; //$NON-NLS-1$ + private static final String STEP_RETURN = "step_return"; //$NON-NLS-1$ private static final String STEP_OVER = "step_over"; //$NON-NLS-1$ @@ -538,6 +542,7 @@ protected void createActions() { addCapabilityAction(new DisconnectCommandAction(), DISCONNECT); addCapabilityAction(new SuspendCommandAction(), SUSPEND); addCapabilityAction(new ResumeCommandAction(), RESUME); + addCapabilityAction(new ResumeOthersCommandAction(), RESUME_OTHERS); addCapabilityAction(new StepReturnCommandAction(), STEP_RETURN); addCapabilityAction(new StepOverCommandAction(), STEP_OVER); addCapabilityAction(new StepIntoCommandAction(), STEP_INTO); @@ -976,6 +981,7 @@ protected void configureToolBar(IToolBarManager tbm) { protected void addDebugToolbarActions(IToolBarManager tbm) { tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME)); + tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME_OTHERS)); tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(SUSPEND)); tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE)); tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(DISCONNECT)); @@ -995,6 +1001,7 @@ protected void addDebugToolbarActions(IToolBarManager tbm) { */ protected void removeDebugToolbarActions(IToolBarManager tbm) { tbm.remove(new ActionContributionItem(getAction(RESUME))); + tbm.remove(new ActionContributionItem(getAction(RESUME_OTHERS))); tbm.remove(new ActionContributionItem(getAction(SUSPEND))); tbm.remove(new ActionContributionItem(getAction(TERMINATE))); tbm.remove(new ActionContributionItem(getAction(DISCONNECT))); @@ -1092,6 +1099,7 @@ private void disposeActions() { disposeCommandAction(DISCONNECT); disposeCommandAction(SUSPEND); disposeCommandAction(RESUME); + disposeCommandAction(RESUME_OTHERS); disposeCommandAction(STEP_RETURN); disposeCommandAction(STEP_OVER); disposeCommandAction(STEP_INTO); @@ -1204,8 +1212,10 @@ protected void fillContextMenu(IMenuManager menu) { menu.appendToGroup(IDebugUIConstants.LAUNCH_GROUP, getAction(TERMINATE_AND_REMOVE)); menu.appendToGroup(IDebugUIConstants.LAUNCH_GROUP, getAction(TERMINATE_ALL)); - menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME)); + if (element instanceof IThread) { + menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME_OTHERS)); + } menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(SUSPEND)); menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE)); menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE_AND_RELAUNCH));