From f8acd2d985d798e7844074585fed64d8d43e6b33 Mon Sep 17 00:00:00 2001 From: Maximilian Wittmer Date: Mon, 17 Jun 2024 13:23:04 +0200 Subject: [PATCH] Find/Replace overlay: fix Ctrl+F6 crash on Linux Avoid being stuck in an event loop by reacting asynchronously to part activation events. Additionally, manually give focus to the editor part after switching. This behavior is default on windows but not consistent on Linux. fixes #1951 --- .../overlay/FindReplaceOverlay.java | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java index 5686d3ac6d6..16a035a3a40 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java @@ -247,21 +247,17 @@ public void shellDeactivated(ShellEvent e) { private IPartListener partListener = new IPartListener() { @Override public void partActivated(IWorkbenchPart part) { - if (getShell() != null) { - getShell().setVisible(isPartCurrentlyDisplayedInPartSash()); - } + getShell().getDisplay().asyncExec(this::adaptToPartActivationChange); } @Override public void partDeactivated(IWorkbenchPart part) { - // Do nothing + getShell().getDisplay().asyncExec(this::adaptToPartActivationChange); } @Override public void partBroughtToTop(IWorkbenchPart part) { - if (getShell() != null) { - getShell().setVisible(isPartCurrentlyDisplayedInPartSash()); - } + getShell().getDisplay().asyncExec(this::adaptToPartActivationChange); } @Override @@ -273,6 +269,35 @@ public void partClosed(IWorkbenchPart part) { public void partOpened(IWorkbenchPart part) { // Do nothing } + + private void adaptToPartActivationChange() { + if (getShell() == null || targetPart.getSite().getPart() == null) { + return; + } + + boolean isOverlayVisible = isPartCurrentlyDisplayedInPartSash(); + + getShell().setVisible(isOverlayVisible); + + if (isOverlayVisible) { + targetPart.getSite().getShell().setActive(); + targetPart.setFocus(); + getShell().getDisplay().asyncExec(this::focusTargetWidget); + } + } + + private void focusTargetWidget() { + if (getShell() == null || targetPart.getSite().getPart() == null) { + return; + } + if (!(targetPart instanceof StatusTextEditor)) { + return; + } + StatusTextEditor textEditor = (StatusTextEditor) targetPart; + Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget(); + + targetWidget.forceFocus(); + } }; private boolean isPartCurrentlyDisplayedInPartSash() {