Skip to content

Commit fa71076

Browse files
ShahzaibIbrahimfedejeanne
authored andcommitted
Scaling of Color/Font Dialog not working properly after DPI change
Creating a separate UI thread to set the DPI Awareness context to use UNAWARE GDI scale before opening the either dialogs since windows has issues with dialog scaling in AWARE context
1 parent beb2391 commit fa71076

File tree

3 files changed

+126
-95
lines changed

3 files changed

+126
-95
lines changed

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ public class OS extends C {
370370
public static final short DMDUP_VERTICAL = 2;
371371
public static final short DMDUP_HORIZONTAL = 3;
372372
public static final int DPI_AWARENESS_CONTEXT_UNAWARE = 24592;
373+
public static final int DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = 1073766416;
373374
public static final int DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 24593;
374375
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;
375376
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34;

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ColorDialog.java

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -233,54 +233,69 @@ public RGB open () {
233233

234234
display.externalEventLoop = true;
235235
display.sendPreExternalEventDispatchEvent ();
236-
/* Open the dialog */
237-
boolean success = OS.ChooseColor (lpcc);
238-
display.externalEventLoop = false;
239-
display.sendPostExternalEventDispatchEvent ();
236+
long currentDpiAwarenessContext = OS.GetThreadDpiAwarenessContext();
237+
boolean success = false;
238+
try {
239+
/*
240+
* Temporarily setting the thread dpi awareness to gdi scaling because window
241+
* dialog has weird resize handling
242+
*/
243+
if (display.isRescalingAtRuntime()) {
244+
currentDpiAwarenessContext = OS.SetThreadDpiAwarenessContext(OS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
245+
}
240246

241-
/* Clear the temporary dialog modal parent */
242-
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
243-
display.setModalDialog (oldModal);
244-
}
247+
/* Open the dialog */
248+
success = OS.ChooseColor(lpcc);
249+
display.externalEventLoop = false;
250+
display.sendPostExternalEventDispatchEvent();
245251

246-
/* Get the Custom Colors (if the user defined any) from the dialog */
247-
boolean customColor = false;
248-
OS.MoveMemory (colors, display.lpCustColors, colors.length * 4);
249-
for (int color : colors) {
250-
if (color != 0x00FFFFFF) {
251-
customColor = true;
252-
break;
252+
/* Clear the temporary dialog modal parent */
253+
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
254+
display.setModalDialog(oldModal);
253255
}
254-
}
255-
if (customColor) {
256-
rgbs = new RGB [CUSTOM_COLOR_COUNT];
257-
for (int i=0; i<colors.length; i++) {
258-
int color = colors[i];
259-
int red = color & 0xFF;
260-
int green = (color >> 8) & 0xFF;
261-
int blue = (color >> 16) & 0xFF;
262-
rgbs[i] = new RGB (red, green, blue);
263-
}
264-
}
265256

266-
if (success) {
267-
int red = lpcc.rgbResult & 0xFF;
268-
int green = (lpcc.rgbResult >> 8) & 0xFF;
269-
int blue = (lpcc.rgbResult >> 16) & 0xFF;
270-
rgb = new RGB (red, green, blue);
271-
}
257+
/* Get the Custom Colors (if the user defined any) from the dialog */
258+
boolean customColor = false;
259+
OS.MoveMemory(colors, display.lpCustColors, colors.length * 4);
260+
for (int color : colors) {
261+
if (color != 0x00FFFFFF) {
262+
customColor = true;
263+
break;
264+
}
265+
}
266+
if (customColor) {
267+
rgbs = new RGB[CUSTOM_COLOR_COUNT];
268+
for (int i = 0; i < colors.length; i++) {
269+
int color = colors[i];
270+
int red = color & 0xFF;
271+
int green = (color >> 8) & 0xFF;
272+
int blue = (color >> 16) & 0xFF;
273+
rgbs[i] = new RGB(red, green, blue);
274+
}
275+
}
272276

273-
/* Free the CCHookProc */
274-
callback.dispose ();
277+
if (success) {
278+
int red = lpcc.rgbResult & 0xFF;
279+
int green = (lpcc.rgbResult >> 8) & 0xFF;
280+
int blue = (lpcc.rgbResult >> 16) & 0xFF;
281+
rgb = new RGB(red, green, blue);
282+
}
283+
} finally {
284+
/* Reset the dpi awareness context */
285+
if (display.isRescalingAtRuntime()) {
286+
OS.SetThreadDpiAwarenessContext(currentDpiAwarenessContext);
287+
}
288+
/* Free the CCHookProc */
289+
callback.dispose ();
290+
/* Destroy the BIDI orientation window */
291+
if (hwndParent != hwndOwner) {
292+
if (enabled) OS.EnableWindow (hwndParent, true);
293+
OS.SetActiveWindow (hwndParent);
294+
OS.DestroyWindow (hwndOwner);
295+
}
275296

276-
/* Destroy the BIDI orientation window */
277-
if (hwndParent != hwndOwner) {
278-
if (enabled) OS.EnableWindow (hwndParent, true);
279-
OS.SetActiveWindow (hwndParent);
280-
OS.DestroyWindow (hwndOwner);
297+
if (!success) return null;
281298
}
282-
283-
if (!success) return null;
284299
return rgb;
285300
}
286301

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/FontDialog.java

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -226,70 +226,85 @@ public FontData open () {
226226

227227
display.externalEventLoop = true;
228228
display.sendPreExternalEventDispatchEvent ();
229-
/* Open the dialog */
230-
boolean success = OS.ChooseFont (lpcf);
231-
display.externalEventLoop = false;
232-
display.sendPostExternalEventDispatchEvent ();
229+
long currentDpiAwarenessContext = OS.GetThreadDpiAwarenessContext();
230+
boolean success = false;
231+
try {
232+
/*
233+
* Temporarily setting the thread dpi awareness to gdi scaling because window
234+
* dialog has weird resize handling
235+
*/
236+
if (display.isRescalingAtRuntime()) {
237+
currentDpiAwarenessContext = OS.SetThreadDpiAwarenessContext(OS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
238+
}
233239

234-
/* Clear the temporary dialog modal parent */
235-
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
236-
display.setModalDialog (oldModal);
237-
}
240+
/* Open the dialog */
241+
success = OS.ChooseFont(lpcf);
242+
display.externalEventLoop = false;
243+
display.sendPostExternalEventDispatchEvent();
238244

239-
/* Compute the result */
240-
if (success) {
241-
LOGFONT logFont = new LOGFONT ();
242-
OS.MoveMemory (logFont, lpLogFont, LOGFONT.sizeof);
245+
/* Clear the temporary dialog modal parent */
246+
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
247+
display.setModalDialog(oldModal);
248+
}
249+
250+
/* Compute the result */
251+
if (success) {
252+
LOGFONT logFont = new LOGFONT();
253+
OS.MoveMemory(logFont, lpLogFont, LOGFONT.sizeof);
243254

244-
/*
245-
* This will not work on multiple screens or
246-
* for printing. Should use DC for the proper device.
247-
*/
248-
long hDC = OS.GetDC(0);
249-
int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
250-
int pixels = 0;
251-
if (logFont.lfHeight > 0) {
252255
/*
253-
* Feature in Windows. If the lfHeight of the LOGFONT structure
254-
* is positive, the lfHeight measures the height of the entire
255-
* cell, including internal leading, in logical units. Since the
256-
* height of a font in points does not include the internal leading,
257-
* we must subtract the internal leading, which requires a TEXTMETRIC,
258-
* which in turn requires font creation.
256+
* This will not work on multiple screens or for printing. Should use DC for the
257+
* proper device.
259258
*/
260-
long hFont = OS.CreateFontIndirect(logFont);
261-
long oldFont = OS.SelectObject(hDC, hFont);
262-
TEXTMETRIC lptm = new TEXTMETRIC ();
263-
OS.GetTextMetrics(hDC, lptm);
264-
OS.SelectObject(hDC, oldFont);
265-
OS.DeleteObject(hFont);
266-
pixels = logFont.lfHeight - lptm.tmInternalLeading;
267-
} else {
268-
pixels = -logFont.lfHeight;
269-
}
270-
OS.ReleaseDC(0, hDC);
259+
long hDC = OS.GetDC(0);
260+
int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
261+
int pixels = 0;
262+
if (logFont.lfHeight > 0) {
263+
/*
264+
* Feature in Windows. If the lfHeight of the LOGFONT structure is positive, the
265+
* lfHeight measures the height of the entire cell, including internal leading,
266+
* in logical units. Since the height of a font in points does not include the
267+
* internal leading, we must subtract the internal leading, which requires a
268+
* TEXTMETRIC, which in turn requires font creation.
269+
*/
270+
long hFont = OS.CreateFontIndirect(logFont);
271+
long oldFont = OS.SelectObject(hDC, hFont);
272+
TEXTMETRIC lptm = new TEXTMETRIC();
273+
OS.GetTextMetrics(hDC, lptm);
274+
OS.SelectObject(hDC, oldFont);
275+
OS.DeleteObject(hFont);
276+
pixels = logFont.lfHeight - lptm.tmInternalLeading;
277+
} else {
278+
pixels = -logFont.lfHeight;
279+
}
280+
OS.ReleaseDC(0, hDC);
271281

272-
float points = pixels * 72f /logPixelsY;
273-
fontData = FontData.win32_new (logFont, points);
274-
if (effectsVisible) {
275-
int red = lpcf.rgbColors & 0xFF;
276-
int green = (lpcf.rgbColors >> 8) & 0xFF;
277-
int blue = (lpcf.rgbColors >> 16) & 0xFF;
278-
rgb = new RGB (red, green, blue);
282+
float points = pixels * 72f / logPixelsY;
283+
fontData = FontData.win32_new(logFont, points);
284+
if (effectsVisible) {
285+
int red = lpcf.rgbColors & 0xFF;
286+
int green = (lpcf.rgbColors >> 8) & 0xFF;
287+
int blue = (lpcf.rgbColors >> 16) & 0xFF;
288+
rgb = new RGB(red, green, blue);
289+
}
279290
}
280-
}
281-
282-
/* Free the OS memory */
283-
if (lpLogFont != 0) OS.HeapFree (hHeap, 0, lpLogFont);
291+
} finally {
292+
/* Reset the dpi awareness context */
293+
if (display.isRescalingAtRuntime()) {
294+
OS.SetThreadDpiAwarenessContext(currentDpiAwarenessContext);
295+
}
296+
/* Free the OS memory */
297+
if (lpLogFont != 0) OS.HeapFree (hHeap, 0, lpLogFont);
284298

285-
/* Destroy the BIDI orientation window */
286-
if (hwndParent != hwndOwner) {
287-
if (enabled) OS.EnableWindow (hwndParent, true);
288-
OS.SetActiveWindow (hwndParent);
289-
OS.DestroyWindow (hwndOwner);
299+
/* Destroy the BIDI orientation window */
300+
if (hwndParent != hwndOwner) {
301+
if (enabled) OS.EnableWindow (hwndParent, true);
302+
OS.SetActiveWindow (hwndParent);
303+
OS.DestroyWindow (hwndOwner);
304+
}
305+
if (!success) return null;
290306
}
291307

292-
if (!success) return null;
293308
return fontData;
294309
}
295310

0 commit comments

Comments
 (0)