diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/handlers/TraversePageHandler.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/handlers/TraversePageHandler.java index 3697e69de4a..1e3e1cd4f32 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/handlers/TraversePageHandler.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/handlers/TraversePageHandler.java @@ -41,6 +41,15 @@ public final Object execute(final ExecutionEvent event) { int traversalDirection = translateToTraversalDirection(forward); Control control = focusControl; do { + if (control instanceof CTabFolder folder && !isRootCTabFolder(folder)) { + // For multi-page editors, we want to skip inner CTabFolders + // If not skipped there are two issues: + // 1. loopToFirstOrLastItem would change the selection of the inner CTabFolder + // 2. control.traverse itself would navigate up to the outer CTabFolder and + // navigate there + control = control.getParent(); + continue; + } if (control instanceof CTabFolder folder && isFinalItemInCTabFolder(folder, forward) && !hasHiddenItem(folder)) { loopToFirstOrLastItem(folder, forward); @@ -59,6 +68,15 @@ public final Object execute(final ExecutionEvent event) { return null; } + private boolean isRootCTabFolder(CTabFolder folder) { + for (var current = folder.getParent(); current != null; current = current.getParent()) { + if (current instanceof CTabFolder) { + return false; + } + } + return true; + } + private boolean hasHiddenItem(CTabFolder folder) { return Arrays.stream(folder.getItems()).anyMatch(i -> !i.isShowing()); }