Skip to content

Commit

Permalink
Scaling of Color/Font Dialog not working properly after DPI change
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ShahzaibIbrahim authored and fedejeanne committed Nov 28, 2024
1 parent beb2391 commit b2c80a4
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ public class OS extends C {
public static final short DMDUP_VERTICAL = 2;
public static final short DMDUP_HORIZONTAL = 3;
public static final int DPI_AWARENESS_CONTEXT_UNAWARE = 24592;
public static final int DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = 1073766416;
public static final int DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 24593;
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,54 +233,69 @@ public RGB open () {

display.externalEventLoop = true;
display.sendPreExternalEventDispatchEvent ();
/* Open the dialog */
boolean success = OS.ChooseColor (lpcc);
display.externalEventLoop = false;
display.sendPostExternalEventDispatchEvent ();
long currentDpiAwarenessContext = OS.GetThreadDpiAwarenessContext();
boolean success = false;
try {
/*
* Temporarily setting the thread dpi awareness to gdi scaling because window
* dialog has weird resize handling
*/
if (display.isRescalingAtRuntime()) {
currentDpiAwarenessContext = OS.SetThreadDpiAwarenessContext(OS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
}

/* Clear the temporary dialog modal parent */
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
display.setModalDialog (oldModal);
}
/* Open the dialog */
success = OS.ChooseColor(lpcc);
display.externalEventLoop = false;
display.sendPostExternalEventDispatchEvent();

/* Get the Custom Colors (if the user defined any) from the dialog */
boolean customColor = false;
OS.MoveMemory (colors, display.lpCustColors, colors.length * 4);
for (int color : colors) {
if (color != 0x00FFFFFF) {
customColor = true;
break;
/* Clear the temporary dialog modal parent */
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
display.setModalDialog(oldModal);
}
}
if (customColor) {
rgbs = new RGB [CUSTOM_COLOR_COUNT];
for (int i=0; i<colors.length; i++) {
int color = colors[i];
int red = color & 0xFF;
int green = (color >> 8) & 0xFF;
int blue = (color >> 16) & 0xFF;
rgbs[i] = new RGB (red, green, blue);
}
}

if (success) {
int red = lpcc.rgbResult & 0xFF;
int green = (lpcc.rgbResult >> 8) & 0xFF;
int blue = (lpcc.rgbResult >> 16) & 0xFF;
rgb = new RGB (red, green, blue);
}
/* Get the Custom Colors (if the user defined any) from the dialog */
boolean customColor = false;
OS.MoveMemory(colors, display.lpCustColors, colors.length * 4);
for (int color : colors) {
if (color != 0x00FFFFFF) {
customColor = true;
break;
}
}
if (customColor) {
rgbs = new RGB[CUSTOM_COLOR_COUNT];
for (int i = 0; i < colors.length; i++) {
int color = colors[i];
int red = color & 0xFF;
int green = (color >> 8) & 0xFF;
int blue = (color >> 16) & 0xFF;
rgbs[i] = new RGB(red, green, blue);
}
}

/* Free the CCHookProc */
callback.dispose ();
if (success) {
int red = lpcc.rgbResult & 0xFF;
int green = (lpcc.rgbResult >> 8) & 0xFF;
int blue = (lpcc.rgbResult >> 16) & 0xFF;
rgb = new RGB(red, green, blue);
}
} finally {
/* Reset the dpi awareness context */
if (display.isRescalingAtRuntime()) {
OS.SetThreadDpiAwarenessContext(currentDpiAwarenessContext);
}
/* Free the CCHookProc */
callback.dispose ();
/* Destroy the BIDI orientation window */
if (hwndParent != hwndOwner) {
if (enabled) OS.EnableWindow (hwndParent, true);
OS.SetActiveWindow (hwndParent);
OS.DestroyWindow (hwndOwner);
}

/* Destroy the BIDI orientation window */
if (hwndParent != hwndOwner) {
if (enabled) OS.EnableWindow (hwndParent, true);
OS.SetActiveWindow (hwndParent);
OS.DestroyWindow (hwndOwner);
if (!success) return null;
}

if (!success) return null;
return rgb;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,70 +226,85 @@ public FontData open () {

display.externalEventLoop = true;
display.sendPreExternalEventDispatchEvent ();
/* Open the dialog */
boolean success = OS.ChooseFont (lpcf);
display.externalEventLoop = false;
display.sendPostExternalEventDispatchEvent ();
long currentDpiAwarenessContext = OS.GetThreadDpiAwarenessContext();
boolean success = false;
try {
/*
* Temporarily setting the thread dpi awareness to gdi scaling because window
* dialog has weird resize handling
*/
if (display.isRescalingAtRuntime()) {
currentDpiAwarenessContext = OS.SetThreadDpiAwarenessContext(OS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
}

/* Clear the temporary dialog modal parent */
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
display.setModalDialog (oldModal);
}
/* Open the dialog */
success = OS.ChooseFont(lpcf);
display.externalEventLoop = false;
display.sendPostExternalEventDispatchEvent();

/* Compute the result */
if (success) {
LOGFONT logFont = new LOGFONT ();
OS.MoveMemory (logFont, lpLogFont, LOGFONT.sizeof);
/* Clear the temporary dialog modal parent */
if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
display.setModalDialog(oldModal);
}

/* Compute the result */
if (success) {
LOGFONT logFont = new LOGFONT();
OS.MoveMemory(logFont, lpLogFont, LOGFONT.sizeof);

/*
* This will not work on multiple screens or
* for printing. Should use DC for the proper device.
*/
long hDC = OS.GetDC(0);
int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
int pixels = 0;
if (logFont.lfHeight > 0) {
/*
* Feature in Windows. If the lfHeight of the LOGFONT structure
* is positive, the lfHeight measures the height of the entire
* cell, including internal leading, in logical units. Since the
* height of a font in points does not include the internal leading,
* we must subtract the internal leading, which requires a TEXTMETRIC,
* which in turn requires font creation.
* This will not work on multiple screens or for printing. Should use DC for the
* proper device.
*/
long hFont = OS.CreateFontIndirect(logFont);
long oldFont = OS.SelectObject(hDC, hFont);
TEXTMETRIC lptm = new TEXTMETRIC ();
OS.GetTextMetrics(hDC, lptm);
OS.SelectObject(hDC, oldFont);
OS.DeleteObject(hFont);
pixels = logFont.lfHeight - lptm.tmInternalLeading;
} else {
pixels = -logFont.lfHeight;
}
OS.ReleaseDC(0, hDC);
long hDC = OS.GetDC(0);
int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
int pixels = 0;
if (logFont.lfHeight > 0) {
/*
* Feature in Windows. If the lfHeight of the LOGFONT structure is positive, the
* lfHeight measures the height of the entire cell, including internal leading,
* in logical units. Since the height of a font in points does not include the
* internal leading, we must subtract the internal leading, which requires a
* TEXTMETRIC, which in turn requires font creation.
*/
long hFont = OS.CreateFontIndirect(logFont);
long oldFont = OS.SelectObject(hDC, hFont);
TEXTMETRIC lptm = new TEXTMETRIC();
OS.GetTextMetrics(hDC, lptm);
OS.SelectObject(hDC, oldFont);
OS.DeleteObject(hFont);
pixels = logFont.lfHeight - lptm.tmInternalLeading;
} else {
pixels = -logFont.lfHeight;
}
OS.ReleaseDC(0, hDC);

float points = pixels * 72f /logPixelsY;
fontData = FontData.win32_new (logFont, points);
if (effectsVisible) {
int red = lpcf.rgbColors & 0xFF;
int green = (lpcf.rgbColors >> 8) & 0xFF;
int blue = (lpcf.rgbColors >> 16) & 0xFF;
rgb = new RGB (red, green, blue);
float points = pixels * 72f / logPixelsY;
fontData = FontData.win32_new(logFont, points);
if (effectsVisible) {
int red = lpcf.rgbColors & 0xFF;
int green = (lpcf.rgbColors >> 8) & 0xFF;
int blue = (lpcf.rgbColors >> 16) & 0xFF;
rgb = new RGB(red, green, blue);
}
}
}

/* Free the OS memory */
if (lpLogFont != 0) OS.HeapFree (hHeap, 0, lpLogFont);
} finally {
/* Reset the dpi awareness context */
if (display.isRescalingAtRuntime()) {
OS.SetThreadDpiAwarenessContext(currentDpiAwarenessContext);
}
/* Free the OS memory */
if (lpLogFont != 0) OS.HeapFree (hHeap, 0, lpLogFont);

/* Destroy the BIDI orientation window */
if (hwndParent != hwndOwner) {
if (enabled) OS.EnableWindow (hwndParent, true);
OS.SetActiveWindow (hwndParent);
OS.DestroyWindow (hwndOwner);
/* Destroy the BIDI orientation window */
if (hwndParent != hwndOwner) {
if (enabled) OS.EnableWindow (hwndParent, true);
OS.SetActiveWindow (hwndParent);
OS.DestroyWindow (hwndOwner);
}
if (!success) return null;
}

if (!success) return null;
return fontData;
}

Expand Down

0 comments on commit b2c80a4

Please sign in to comment.