Skip to content

Commit 27e9339

Browse files
committed
Find/replace overlay: improve focus/tab order #2161
The FindReplaceOverlay currently uses the default focus order. When tabbing through the widgets, this means that when starting from the find input field you have to tab over all the search options before coming to the replace input field. Since the most often used navigation is between the two input fields for find and replace, they should come after each other in the focus order. This change adapts the focus order of the involved elements: - Tab between find and replace input field - Tab between replace input field and the tools (starting from the search tools) - Tab between search/close and replace search tools (instead of coming from search/close tools to the replace input field) Fixes #2161
1 parent 64af72a commit 27e9339

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/AccessibleToolBar.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,9 @@ void registerActionShortcutsAtControl(Control control) {
7474
}
7575
}
7676

77+
Control getFirstControl() {
78+
Control[] children = getChildren();
79+
return children.length == 0 ? null : getChildren()[0];
80+
}
81+
7782
}

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.eclipse.swt.widgets.Composite;
3838
import org.eclipse.swt.widgets.Control;
3939
import org.eclipse.swt.widgets.Display;
40+
import org.eclipse.swt.widgets.Listener;
4041
import org.eclipse.swt.widgets.ScrollBar;
4142
import org.eclipse.swt.widgets.Scrollable;
4243
import org.eclipse.swt.widgets.Shell;
@@ -178,6 +179,81 @@ private void setTextEditorActionsActivated(boolean state) {
178179
}
179180
};
180181

182+
private final CustomFocusOrder customFocusOrder = new CustomFocusOrder();
183+
184+
private class CustomFocusOrder {
185+
private final Listener searchBarToReplaceBar = e -> {
186+
if (e.detail == SWT.TRAVERSE_TAB_NEXT) {
187+
e.doit = false;
188+
replaceBar.forceFocus();
189+
}
190+
};
191+
192+
private final Listener replaceBarToSearchBarAndTools = e -> {
193+
switch (e.detail) {
194+
case SWT.TRAVERSE_TAB_NEXT:
195+
e.doit = false;
196+
searchBar.getDropDownTool().getFirstControl().forceFocus();
197+
break;
198+
case SWT.TRAVERSE_TAB_PREVIOUS:
199+
e.doit = false;
200+
searchBar.getTextBar().forceFocus();
201+
break;
202+
default:
203+
// Proceed as normal
204+
}
205+
};
206+
207+
private final Listener searchToolsToReplaceBar = e -> {
208+
switch (e.detail) {
209+
case SWT.TRAVERSE_TAB_PREVIOUS:
210+
e.doit = false;
211+
replaceBar.forceFocus();
212+
break;
213+
default:
214+
// Proceed as normal
215+
}
216+
};
217+
218+
private final Listener closeToolsToReplaceTools = e -> {
219+
switch (e.detail) {
220+
case SWT.TRAVERSE_TAB_NEXT:
221+
e.doit = false;
222+
replaceBar.getDropDownTool().getFirstControl().forceFocus();
223+
break;
224+
default:
225+
// Proceed as normal
226+
}
227+
};
228+
229+
private final Listener replaceToolsToCloseTools = e -> {
230+
switch (e.detail) {
231+
case SWT.TRAVERSE_TAB_PREVIOUS:
232+
e.doit = false;
233+
closeTools.getFirstControl().forceFocus();
234+
break;
235+
default:
236+
// Proceed as normal
237+
}
238+
};
239+
240+
void apply() {
241+
searchBar.getTextBar().addListener(SWT.Traverse, searchBarToReplaceBar);
242+
replaceBar.getTextBar().addListener(SWT.Traverse, replaceBarToSearchBarAndTools);
243+
searchBar.getDropDownTool().getFirstControl().addListener(SWT.Traverse, searchToolsToReplaceBar);
244+
closeTools.getFirstControl().addListener(SWT.Traverse, closeToolsToReplaceTools);
245+
replaceBar.getDropDownTool().getFirstControl().addListener(SWT.Traverse, replaceToolsToCloseTools);
246+
}
247+
248+
void dispose() {
249+
searchBar.getTextBar().removeListener(SWT.Traverse, searchBarToReplaceBar);
250+
replaceBar.getTextBar().removeListener(SWT.Traverse, replaceBarToSearchBarAndTools);
251+
searchBar.getDropDownTool().getFirstControl().removeListener(SWT.Traverse, searchToolsToReplaceBar);
252+
closeTools.getFirstControl().removeListener(SWT.Traverse, closeToolsToReplaceTools);
253+
replaceBar.getDropDownTool().getFirstControl().removeListener(SWT.Traverse, replaceToolsToCloseTools);
254+
}
255+
}
256+
181257
public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) {
182258
targetPart = part;
183259
targetControl = getTargetControl(parent, part);
@@ -607,6 +683,7 @@ public void focusLost(FocusEvent e) {
607683
searchBar.addModifyListener(Event -> {
608684
decorate();
609685
});
686+
searchBar.setTabList(null);
610687
}
611688

612689
private void updateIncrementalSearch() {
@@ -670,6 +747,7 @@ private void hideReplace() {
670747
if (!replaceBarOpen) {
671748
return;
672749
}
750+
customFocusOrder.dispose();
673751
searchBar.forceFocus();
674752
contentAssistReplaceField = null;
675753
replaceBarOpen = false;
@@ -688,6 +766,7 @@ private void createReplaceDialog() {
688766
updatePlacementAndVisibility();
689767
assignIDs();
690768
replaceBar.forceFocus();
769+
customFocusOrder.apply();
691770
}
692771

693772
private void initializeReplaceShortcutHandlers() {

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/HistoryTextWrapper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,8 @@ public Text getTextBar() {
207207
return textBar;
208208
}
209209

210+
AccessibleToolBar getDropDownTool() {
211+
return tools;
212+
}
213+
210214
}

0 commit comments

Comments
 (0)