From 49cfcde5a9d5d7a595bbf38f04e34d0ed555578e Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Mon, 18 Aug 2025 10:03:35 +0200 Subject: [PATCH] Use DwmGetWindowAttribute for Shell#getLocation to avoid shadow margins GetWindowRect includes invisible shadow borders on Windows 10/11, causing Shell#getLocation to return coordinates offset by ~9px from the visible frame. Replaced with DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS) to report the true window bounds in screen space, with GetWindowRect as a fallback if DWM is unavailable. --- .../Eclipse SWT PI/win32/library/os.c | 19 ++++++++++++++++--- .../Eclipse SWT PI/win32/library/os_stats.h | 4 +--- .../org/eclipse/swt/internal/win32/OS.java | 3 +++ .../win32/org/eclipse/swt/widgets/Shell.java | 9 ++++++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c index 0d075e66459..d1c86ad546c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c @@ -7,9 +7,6 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation *******************************************************************************/ /* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */ @@ -1513,6 +1510,22 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(DuplicateHandle) } #endif +#ifndef NO_DwmGetWindowAttribute +JNIEXPORT jint JNICALL OS_NATIVE(DwmGetWindowAttribute) + (JNIEnv *env, jclass that, jlong arg0, jint arg1, jobject arg2, jint arg3) +{ + RECT _arg2, *lparg2=NULL; + jint rc = 0; + OS_NATIVE_ENTER(env, that, DwmGetWindowAttribute_FUNC); + if (arg2) if ((lparg2 = getRECTFields(env, arg2, &_arg2)) == NULL) goto fail; + rc = (jint)DwmGetWindowAttribute((HWND)arg0, arg1, lparg2, arg3); +fail: + if (arg2 && lparg2) setRECTFields(env, arg2, lparg2); + OS_NATIVE_EXIT(env, that, DwmGetWindowAttribute_FUNC); + return rc; +} +#endif + #ifndef NO_DwmSetWindowAttribute JNIEXPORT jboolean JNICALL OS_NATIVE(DwmSetWindowAttribute) (JNIEnv *env, jclass that, jlong arg0, jint arg1, jintArray arg2, jint arg3) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h index bc809ece5f4..59eb8e5d74b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h @@ -7,9 +7,6 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation *******************************************************************************/ /* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */ @@ -133,6 +130,7 @@ typedef enum { DrawThemeBackground_FUNC, DrawThemeText_FUNC, DuplicateHandle_FUNC, + DwmGetWindowAttribute_FUNC, DwmSetWindowAttribute_FUNC, EMREXTCREATEFONTINDIRECTW_1sizeof_FUNC, EMR_1sizeof_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index d6abf999892..3621cef0eac 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -380,6 +380,7 @@ public class OS extends C { public static final int DTS_SHORTDATEFORMAT = 0x0000; public static final int DTS_TIMEFORMAT = 0x0009; public static final int DTS_UPDOWN = 0x0001; + public static final int DWMWA_EXTENDED_FRAME_BOUNDS = 9; public static final int E_POINTER = 0x80004003; public static final int EBP_NORMALGROUPBACKGROUND = 5; public static final int EBP_NORMALGROUPCOLLAPSE = 6; @@ -3022,6 +3023,8 @@ public static int HRESULT_FROM_WIN32(int x) { public static final native boolean GetWindowPlacement (long hWnd, WINDOWPLACEMENT lpwndpl); /** @param hWnd cast=(HWND) */ public static final native boolean GetWindowRect (long hWnd, RECT lpRect); +/** @param hwnd cast=(HWND) */ +public static final native int DwmGetWindowAttribute (long hwnd, int dwAttribute, RECT pvAttribute, int cbAttribute); /** * @param hWnd cast=(HWND) * @param hRgn cast=(HRGN) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java index da1e195fa23..6d353552955 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java @@ -1015,9 +1015,12 @@ public int getImeInputMode () { @Override Point getLocationInPixels () { if (OS.IsIconic (handle)) return super.getLocationInPixels (); - RECT rect = new RECT (); - OS.GetWindowRect (handle, rect); - return new Point (rect.left, rect.top); + RECT rect = new RECT(); + int hr = OS.DwmGetWindowAttribute(handle, OS.DWMWA_EXTENDED_FRAME_BOUNDS, rect, RECT.sizeof); + if (hr != 0) { + OS.GetWindowRect(handle, rect); + } + return new Point(rect.left, rect.top); } @Override