From 60c835b48a633515c735aa386e469dd13d52b875 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 30 Jul 2024 14:24:53 +0200 Subject: [PATCH] Find/replace overlay: asynchronously update on editor movement #2138 The update of the find/replace overlay placement and size while a repaint for its target editor is being processed (e.g., in order to handle minimizing/maximizing the target editor) is currently executed just-in-time. Other updates, reacting to movements and resizes of the shell, are processed asynchronously. The just-in-time execution leads to deadlocks on GTK. With this change, all update operations for the size and position of the overlay are performed via asynchronous executions scheduled via the Display. In addition, changing visibility for the overlay is only performed if the currently visibility state does not fit. Fixes https://github.com/eclipse-platform/eclipse.platform.ui/issues/2138 --- .../overlay/FindReplaceOverlay.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 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 69eff374af2..f7391b1c5b9 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 @@ -195,19 +195,24 @@ private void performSelectAll() { private ControlListener shellMovementListener = new ControlListener() { @Override public void controlMoved(ControlEvent e) { - if (getShell() != null) { - getShell().getDisplay().asyncExec(() -> updatePlacementAndVisibility()); - } + asyncUpdatePlacementAndVisibility(); } @Override public void controlResized(ControlEvent e) { - if (getShell() != null) { - getShell().getDisplay().asyncExec(() -> updatePlacementAndVisibility()); - } + asyncUpdatePlacementAndVisibility(); } }; + private PaintListener widgetMovementListener = __ -> asyncUpdatePlacementAndVisibility(); + + private void asyncUpdatePlacementAndVisibility() { + Shell shell = getShell(); + if (shell != null) { + shell.getDisplay().asyncExec(this::updatePlacementAndVisibility); + } + } + private ShellAdapter overlayDeactivationListener = new ShellAdapter() { @Override public void shellActivated(ShellEvent e) { @@ -220,8 +225,6 @@ public void shellDeactivated(ShellEvent e) { } }; - private PaintListener widgetMovementListener = __ -> updatePlacementAndVisibility(); - private static class TargetPartVisibilityHandler implements IPartListener2, IPageChangedListener { private final IWorkbenchPart targetPart; private final IWorkbenchPart topLevelPart; @@ -926,11 +929,16 @@ private void updatePosition(Rectangle overlayBounds) { } private void updateVisibility(Rectangle targetControlBounds, Rectangle overlayBounds) { + boolean shallBeVisible = true; if (positionAtTop) { - getShell().setVisible( - overlayBounds.y + overlayBounds.height <= targetControlBounds.y + targetControlBounds.height); + shallBeVisible = overlayBounds.y + overlayBounds.height <= targetControlBounds.y + + targetControlBounds.height; } else { - getShell().setVisible(overlayBounds.y >= targetControlBounds.y); + shallBeVisible = overlayBounds.y >= targetControlBounds.y; + } + Shell shell = getShell(); + if (shallBeVisible != shell.isVisible()) { + shell.setVisible(shallBeVisible); } }