diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF b/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF
index 76a78133ca0..e8dfd9f7c67 100644
--- a/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF
+++ b/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.terminal.view.ui;singleton:=true
-Bundle-Version: 1.1.100.qualifier
+Bundle-Version: 1.1.200.qualifier
Bundle-Activator: org.eclipse.terminal.view.ui.internal.UIPlugin
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.9.0,4.0.0)",
@@ -10,6 +10,7 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.9.0,4.0.0)",
org.eclipse.core.resources;bundle-version="[3.22.0,4.0.0)";resolution:=optional,
org.eclipse.core.variables;bundle-version="[3.6.0,4.0.0)",
org.eclipse.debug.ui;bundle-version="[3.18.0,4.0.0)";resolution:=optional,
+ org.eclipse.swt;bundle-version="[3.135.0,4.0.0)",
org.eclipse.ui;bundle-version="[3.208.0,4.0.0)",
org.eclipse.ui.ide;bundle-version="[3.22.0,4.0.0)";resolution:=optional,
org.eclipse.ui.editors;bundle-version="[3.20.0,4.0.0)";resolution:=optional,
diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/view/TerminalsView.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/view/TerminalsView.java
index ef41338cbd9..f9faac493d4 100644
--- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/view/TerminalsView.java
+++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/view/TerminalsView.java
@@ -261,12 +261,9 @@ private void addDropSupport() {
target.addDropListener(new DropTargetListener() {
@Override
public void dragEnter(DropTargetEvent event) {
- // only if the drop target is different then the drag source
- if (TerminalTransfer.getInstance().getTabFolderManager() == tabFolderManager) {
- event.detail = DND.DROP_NONE;
- } else {
- event.detail = DND.DROP_MOVE;
- }
+ // Accept the move both for a different terminals view (the terminal is moved
+ // to the other view) and for the same view (the tab is reordered).
+ event.detail = DND.DROP_MOVE;
}
@Override
@@ -290,6 +287,12 @@ public void drop(DropTargetEvent event) {
if (TerminalTransfer.getInstance().getDraggedFolderItem() != null && tabFolderManager != null) {
CTabItem draggedItem = TerminalTransfer.getInstance().getDraggedFolderItem();
+ // Drop within the same terminals view: reorder the dragged tab in place.
+ if (TerminalTransfer.getInstance().getTabFolderManager() == tabFolderManager) {
+ reorderTabItem(draggedItem, event.x, event.y);
+ return;
+ }
+
CTabItem item = tabFolderManager.cloneTabItemAfterDrop(draggedItem);
tabFolderManager.bringToTop(item);
switchToTabFolderControl();
@@ -313,6 +316,61 @@ public void drop(DropTargetEvent event) {
});
}
+ /**
+ * Reorder the dragged tab item within its own tab folder so that it is dropped at the position
+ * the mouse points to.
+ *
+ * @param draggedItem the tab item being dragged, must not be null.
+ * @param x the x coordinate of the drop, in display-relative coordinates.
+ * @param y the y coordinate of the drop, in display-relative coordinates.
+ */
+ private void reorderTabItem(CTabItem draggedItem, int x, int y) {
+ if (tabFolderControl == null || tabFolderControl.isDisposed()) {
+ return;
+ }
+
+ int from = tabFolderControl.indexOf(draggedItem);
+ if (from == -1) {
+ return;
+ }
+
+ // Map the display-relative drop coordinates to the tab folder and find the tab below them.
+ // A drop next to the tabs (e.g. on the trailing empty space) targets the last position.
+ Point point = tabFolderControl.toControl(x, y);
+ CTabItem targetItem = tabFolderControl.getItem(point);
+ int indexUnderCursor = targetItem != null ? tabFolderControl.indexOf(targetItem) : -1;
+
+ int to = computeReorderIndex(from, indexUnderCursor, tabFolderControl.getItemCount());
+ if (to != -1) {
+ tabFolderControl.moveItem(from, to);
+ }
+
+ // Keep the moved terminal selected and focused.
+ tabFolderManager.bringToTop(draggedItem);
+ setFocus();
+ }
+
+ /**
+ * Computes the destination index for a tab reorder triggered by a drop.
+ *
+ * This method is internal and only exposed for testing. + *
+ * + * @param from the current index of the dragged tab. + * @param indexUnderCursor the index of the tab below the drop location, or-1 if the
+ * drop did not happen over a tab (for example on the empty space following the last tab).
+ * @param itemCount the total number of tabs in the folder.
+ * @return the index the dragged tab should be moved to, or -1 if no move is required
+ * because the tab would keep its position.
+ */
+ public static int computeReorderIndex(int from, int indexUnderCursor, int itemCount) {
+ int to = indexUnderCursor != -1 ? indexUnderCursor : itemCount - 1;
+ if (to < 0 || to == from) {
+ return -1;
+ }
+ return to;
+ }
+
@Override
public void dispose() {
// Dispose the tab folder manager
diff --git a/terminal/features/org.eclipse.terminal.feature/feature.xml b/terminal/features/org.eclipse.terminal.feature/feature.xml
index 94b37131c25..044c0b1ba2c 100644
--- a/terminal/features/org.eclipse.terminal.feature/feature.xml
+++ b/terminal/features/org.eclipse.terminal.feature/feature.xml
@@ -2,7 +2,7 @@