From 2c1ee18635dc794802d95133f737e6bf635b0fde Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Sat, 25 Jul 2026 01:04:19 +0200 Subject: [PATCH] Try to stabilize relative location calculation of Swing components #1524 The way a Swing component is moved on Linux is via a request to the window manager, which is then processed asynchronously. Because of this, it might happen that the relative location of two widgets is calculated while one is being moved, leading to wildly inaccurate results. To reduce the likelihood of this happening, we wait until the offset remains the same two times in a row, which makes it very likely that the move as completed. Closes https://github.com/eclipse-windowbuilder/windowbuilder/issues/1524 --- .../wb/internal/swing/utils/SwingUtils.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/org.eclipse.wb.swing/src/org/eclipse/wb/internal/swing/utils/SwingUtils.java b/org.eclipse.wb.swing/src/org/eclipse/wb/internal/swing/utils/SwingUtils.java index c9a1247c8..1b2b5643f 100644 --- a/org.eclipse.wb.swing/src/org/eclipse/wb/internal/swing/utils/SwingUtils.java +++ b/org.eclipse.wb.swing/src/org/eclipse/wb/internal/swing/utils/SwingUtils.java @@ -281,8 +281,29 @@ public static Point getScreenLocation(final Component component) throws Exceptio */ public static Point getRelativeLocation(final Component parentComponent, final Component childComponent) throws Exception { - return runObjectLaterAndWait(() -> SwingUtilities.convertPoint(childComponent.getParent(), - childComponent.getLocation(), parentComponent)); + if (EnvironmentUtils.IS_LINUX) { + return internalGetRelativeLocationLinux(parentComponent, childComponent); + } + return internalGetRelativeLocation(parentComponent, childComponent); + } + + private static Point internalGetRelativeLocationLinux(final Component parentComponent, final Component childComponent) throws Exception { + long end = System.currentTimeMillis() + 1000; + Point p; + do { + p = internalGetRelativeLocation(parentComponent, childComponent); + // The Swing component is moved asynchronously by the window manager. Wait until we get a consistent result + Point p1 = internalGetRelativeLocation(parentComponent, childComponent); + if (p.equals(p1)) { + break; + } + } while (System.currentTimeMillis() < end); + return p; + + } + + private static Point internalGetRelativeLocation(final Component parentComponent, final Component childComponent) throws Exception { + return runObjectLaterAndWait(() -> SwingUtilities.convertPoint(childComponent.getParent(), childComponent.getLocation(), parentComponent)); } /**