Skip to content

Commit

Permalink
[win32] Use DPI dependent OS API calls
Browse files Browse the repository at this point in the history
This commit replaces the OS calls for OpenThemeData with calls to the dpi dependent equivalent OpenThemeDataForDpi. Therefor the handling of loading/unloading of theme in Display is refactored to be able to manage multiple DPI dependent variants of a theme in multi zoom environments

Contributes to #62 nd #131
  • Loading branch information
akoch-yatta committed Oct 7, 2024
1 parent 8056739 commit c1b770b
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ private int getCheckboxTextOffset(long hdc) {
SIZE size = new SIZE();

if (OS.IsAppThemed ()) {
OS.GetThemePartSize(display.hButtonTheme(), hdc, OS.BP_CHECKBOX, OS.CBS_UNCHECKEDNORMAL, null, OS.TS_TRUE, size);
OS.GetThemePartSize(display.hButtonTheme(getZoom()), hdc, OS.BP_CHECKBOX, OS.CBS_UNCHECKEDNORMAL, null, OS.TS_TRUE, size);
result += size.cx;
} else {
result += DPIUtil.scaleUp(13, nativeZoom);
Expand Down Expand Up @@ -1543,7 +1543,7 @@ LRESULT wmDrawChild (long wParam, long lParam) {
boolean pressed = ((struct.itemState & OS.ODS_SELECTED) != 0);
boolean enabled = getEnabled ();
int iStateId = getThemeStateId(style, pressed, enabled);
OS.DrawThemeBackground (display.hScrollBarThemeAuto (), struct.hDC, OS.SBP_ARROWBTN, iStateId, rect, null);
OS.DrawThemeBackground (display.hScrollBarThemeAuto (getZoom()), struct.hDC, OS.SBP_ARROWBTN, iStateId, rect, null);
} else {
int uState = OS.DFCS_SCROLLLEFT;
switch (style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ LRESULT wmNCPaint (long hwnd, long wParam, long lParam) {
rect.left = rect.top = 0;
int border = getSystemMetrics (OS.SM_CXEDGE);
OS.ExcludeClipRect (hDC, border, border, rect.right - border, rect.bottom - border);
OS.DrawThemeBackground (display.hEditTheme (), hDC, OS.EP_EDITTEXT, OS.ETS_NORMAL, rect, null);
OS.DrawThemeBackground (display.hEditTheme (getZoom()), hDC, OS.EP_EDITTEXT, OS.ETS_NORMAL, rect, null);
OS.ReleaseDC (hwnd, hDC);
return new LRESULT (code);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public class Display extends Device implements Executor {
}

/* XP Themes */
long hButtonTheme, hButtonThemeDark, hEditTheme, hExplorerBarTheme, hScrollBarTheme, hScrollBarThemeDark, hTabTheme;
private Map<Integer, ThemeData> themeDataMap = new HashMap<>();
static final char [] EXPLORER = new char [] {'E', 'X', 'P', 'L', 'O', 'R', 'E', 'R', 0};
static final char [] TREEVIEW = new char [] {'T', 'R', 'E', 'E', 'V', 'I', 'E', 'W', 0};
/* Emergency switch to be used in case of regressions. Not supposed to be changed when app is running. */
Expand Down Expand Up @@ -2665,93 +2665,55 @@ public boolean getTouchEnabled () {
return (value & (OS.NID_READY | OS.NID_MULTI_INPUT)) == (OS.NID_READY | OS.NID_MULTI_INPUT);
}

long hButtonTheme () {
if (hButtonTheme != 0) return hButtonTheme;
final char[] themeName = "BUTTON\0".toCharArray();
return hButtonTheme = OS.OpenThemeData (hwndMessage, themeName);
long hButtonTheme (int dpi) {
return getOrCreateThemeData(dpi).hButtonTheme();
}

long hButtonThemeDark () {
if (hButtonThemeDark != 0) return hButtonThemeDark;
final char[] themeName = "Darkmode_Explorer::BUTTON\0".toCharArray();
return hButtonThemeDark = OS.OpenThemeData (hwndMessage, themeName);
long hButtonThemeDark (int dpi) {
return getOrCreateThemeData(dpi).hButtonThemeDark();
}

long hButtonThemeAuto () {
long hButtonThemeAuto (int dpi) {
if (useDarkModeExplorerTheme) {
return hButtonThemeDark ();
return hButtonThemeDark (dpi);
} else {
return hButtonTheme ();
return hButtonTheme (dpi);
}
}

long hEditTheme () {
if (hEditTheme != 0) return hEditTheme;
final char[] themeName = "EDIT\0".toCharArray();
return hEditTheme = OS.OpenThemeData (hwndMessage, themeName);
long hEditTheme (int dpi) {
return getOrCreateThemeData(dpi).hEditTheme();
}

long hExplorerBarTheme () {
if (hExplorerBarTheme != 0) return hExplorerBarTheme;
final char[] themeName = "EXPLORERBAR\0".toCharArray();
return hExplorerBarTheme = OS.OpenThemeData (hwndMessage, themeName);
long hExplorerBarTheme (int dpi) {
return getOrCreateThemeData(dpi).hExplorerBarTheme();
}

long hScrollBarTheme () {
if (hScrollBarTheme != 0) return hScrollBarTheme;
final char[] themeName = "SCROLLBAR\0".toCharArray();
return hScrollBarTheme = OS.OpenThemeData (hwndMessage, themeName);
long hScrollBarTheme (int dpi) {
return getOrCreateThemeData(dpi).hScrollBarTheme();
}

long hScrollBarThemeDark () {
if (hScrollBarThemeDark != 0) return hScrollBarThemeDark;
final char[] themeName = "Darkmode_Explorer::SCROLLBAR\0".toCharArray();
return hScrollBarThemeDark = OS.OpenThemeData (hwndMessage, themeName);
long hScrollBarThemeDark (int dpi) {
return getOrCreateThemeData(dpi).hScrollBarThemeDark();
}

long hScrollBarThemeAuto () {
long hScrollBarThemeAuto (int dpi) {
if (useDarkModeExplorerTheme) {
return hScrollBarThemeDark ();
return hScrollBarThemeDark (dpi);
} else {
return hScrollBarTheme ();
return hScrollBarTheme (dpi);
}
}

long hTabTheme () {
if (hTabTheme != 0) return hTabTheme;
final char[] themeName = "TAB\0".toCharArray();
return hTabTheme = OS.OpenThemeData (hwndMessage, themeName);
long hTabTheme (int dpi) {
return getOrCreateThemeData(dpi).hTabTheme();
}

void resetThemes() {
if (hButtonTheme != 0) {
OS.CloseThemeData (hButtonTheme);
hButtonTheme = 0;
}
if (hButtonThemeDark != 0) {
OS.CloseThemeData (hButtonThemeDark);
hButtonThemeDark = 0;
}
if (hEditTheme != 0) {
OS.CloseThemeData (hEditTheme);
hEditTheme = 0;
}
if (hExplorerBarTheme != 0) {
OS.CloseThemeData (hExplorerBarTheme);
hExplorerBarTheme = 0;
}
if (hScrollBarTheme != 0) {
OS.CloseThemeData (hScrollBarTheme);
hScrollBarTheme = 0;
}
if (hScrollBarThemeDark != 0) {
OS.CloseThemeData (hScrollBarThemeDark);
hScrollBarThemeDark = 0;
}
if (hTabTheme != 0) {
OS.CloseThemeData (hTabTheme);
hTabTheme = 0;
for (ThemeData themeData : themeDataMap.values()) {
themeData.reset();
}
themeDataMap.clear();
}

/**
Expand Down Expand Up @@ -5313,6 +5275,112 @@ static boolean isActivateShellOnForceFocus() {
return "true".equals(System.getProperty("org.eclipse.swt.internal.activateShellOnForceFocus", "true")); //$NON-NLS-1$
}

private ThemeData getOrCreateThemeData(int dpi) {
if (themeDataMap.containsKey(dpi)) {
return themeDataMap.get(dpi);
}
ThemeData themeData = new ThemeData(dpi);
themeDataMap.put(dpi, themeData);
return themeData;
}

private class ThemeData {
long hButtonTheme;
long hButtonThemeDark;
long hEditTheme;
long hExplorerBarTheme;
long hScrollBarTheme;
long hScrollBarThemeDark;
long hTabTheme;

int dpi;

private ThemeData(int dpi) {
this.dpi = dpi;
}

long hButtonTheme () {
if (hButtonTheme != 0) return hButtonTheme;
final char[] themeName = "BUTTON\0".toCharArray();
return hButtonTheme = openThemeData(themeName);
}

long hButtonThemeDark () {
if (hButtonThemeDark != 0) return hButtonThemeDark;
final char[] themeName = "Darkmode_Explorer::BUTTON\0".toCharArray();
return hButtonThemeDark = openThemeData(themeName);
}

long hEditTheme () {
if (hEditTheme != 0) return hEditTheme;
final char[] themeName = "EDIT\0".toCharArray();
return hEditTheme = openThemeData(themeName);
}

long hExplorerBarTheme () {
if (hExplorerBarTheme != 0) return hExplorerBarTheme;
final char[] themeName = "EXPLORERBAR\0".toCharArray();
return hExplorerBarTheme = openThemeData(themeName);
}

long hScrollBarTheme () {
if (hScrollBarTheme != 0) return hScrollBarTheme;
final char[] themeName = "SCROLLBAR\0".toCharArray();
return hScrollBarTheme = openThemeData(themeName);
}

long hScrollBarThemeDark () {
if (hScrollBarThemeDark != 0) return hScrollBarThemeDark;
final char[] themeName = "Darkmode_Explorer::SCROLLBAR\0".toCharArray();
return hScrollBarThemeDark = openThemeData(themeName);
}

long hTabTheme () {
if (hTabTheme != 0) return hTabTheme;
final char[] themeName = "TAB\0".toCharArray();
return hTabTheme = openThemeData(themeName);
}


public void reset() {
if (hButtonTheme != 0) {
OS.CloseThemeData (hButtonTheme);
hButtonTheme = 0;
}
if (hButtonThemeDark != 0) {
OS.CloseThemeData (hButtonThemeDark);
hButtonThemeDark = 0;
}
if (hEditTheme != 0) {
OS.CloseThemeData (hEditTheme);
hEditTheme = 0;
}
if (hExplorerBarTheme != 0) {
OS.CloseThemeData (hExplorerBarTheme);
hExplorerBarTheme = 0;
}
if (hScrollBarTheme != 0) {
OS.CloseThemeData (hScrollBarTheme);
hScrollBarTheme = 0;
}
if (hScrollBarThemeDark != 0) {
OS.CloseThemeData (hScrollBarThemeDark);
hScrollBarThemeDark = 0;
}
if (hTabTheme != 0) {
OS.CloseThemeData (hTabTheme);
hTabTheme = 0;
}
}

private long openThemeData(final char[] themeName) {
if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_1809) {
return OS.OpenThemeDataForDpi(hwndMessage, themeName, dpi);
} else {
return OS.OpenThemeData(hwndMessage, themeName);
}
}
}
/**
* {@return whether rescaling of shells at runtime when the DPI scaling of a
* shell's monitor changes is activated for this device}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static int checkStyle (int style) {
long hDC = OS.GetDC (handle);
long hTheme = 0;
if (isAppThemed ()) {
hTheme = display.hExplorerBarTheme ();
hTheme = display.hExplorerBarTheme (getZoom());
}
long hCurrentFont = 0, oldFont = 0;
if (hTheme == 0) {
Expand Down Expand Up @@ -247,13 +247,13 @@ void drawThemeBackground (long hDC, long hwnd, RECT rect) {
RECT rect2 = new RECT ();
OS.GetClientRect (handle, rect2);
OS.MapWindowPoints (handle, hwnd, rect2, 2);
OS.DrawThemeBackground (display.hExplorerBarTheme (), hDC, OS.EBP_NORMALGROUPBACKGROUND, 0, rect2, null);
OS.DrawThemeBackground (display.hExplorerBarTheme (getZoom()), hDC, OS.EBP_NORMALGROUPBACKGROUND, 0, rect2, null);
}

void drawWidget (GC gc, RECT clipRect) {
long hTheme = 0;
if (isAppThemed ()) {
hTheme = display.hExplorerBarTheme ();
hTheme = display.hExplorerBarTheme (getZoom());
}
if (hTheme != 0) {
RECT rect = new RECT ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void drawThemeBackground (long hDC, long hwnd, RECT rect) {
OS.GetClientRect (handle, rect2);
OS.MapWindowPoints (handle, hwnd, rect2, 2);
if (OS.IntersectRect (new RECT (), rect2, rect)) {
OS.DrawThemeBackground (display.hTabTheme (), hDC, OS.TABP_BODY, 0, rect2, null);
OS.DrawThemeBackground (display.hTabTheme (getZoom()), hDC, OS.TABP_BODY, 0, rect2, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4263,14 +4263,14 @@ void setCheckboxImageList (int width, int height, boolean fixScroll) {
* artifacts, limit the rectangle to actual checkbox bitmap size.
*/
SIZE size = new SIZE();
OS.GetThemePartSize(display.hButtonTheme(), memDC, OS.BP_CHECKBOX, 0, null, OS.TS_TRUE, size);
OS.GetThemePartSize(display.hButtonTheme(getZoom()), memDC, OS.BP_CHECKBOX, 0, null, OS.TS_TRUE, size);
itemWidth = Math.min (size.cx, itemWidth);
itemHeight = Math.min (size.cy, itemHeight);
}
int left = (width - itemWidth) / 2, top = (height - itemHeight) / 2;
OS.SetRect (rect, left, top, left + itemWidth, top + itemHeight);
if (OS.IsAppThemed ()) {
long hTheme = display.hButtonTheme ();
long hTheme = display.hButtonTheme(getZoom());
OS.DrawThemeBackground (hTheme, memDC, OS.BP_CHECKBOX, OS.CBS_UNCHECKEDNORMAL, rect, null);
rect.left += width; rect.right += width;
OS.DrawThemeBackground (hTheme, memDC, OS.BP_CHECKBOX, OS.CBS_CHECKEDNORMAL, rect, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2751,7 +2751,7 @@ LRESULT WM_DRAWITEM (long wParam, long lParam) {
drawBackground (struct.hDC, rect, -1, pt.x, pt.y);
if (struct.CtlID == SWT.ICON_CANCEL && struct.hwndItem == hwndActiveIcon && OS.IsAppThemed()) {
int state = OS.GetKeyState (OS.VK_LBUTTON) < 0 ? OS.PBS_PRESSED : OS.PBS_HOT;
OS.DrawThemeBackground (display.hButtonThemeAuto (), struct.hDC, OS.BP_PUSHBUTTON, state, rect, null);
OS.DrawThemeBackground (display.hButtonThemeAuto (getZoom()), struct.hDC, OS.BP_PUSHBUTTON, state, rect, null);
}
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
backgroundRect = selectionRect;
}
}
long hTheme = OS.OpenThemeData (handle, Display.TREEVIEW);
long hTheme = OS.OpenThemeDataForDpi(handle, Display.TREEVIEW, getZoom());
int iStateId = selected ? OS.TREIS_SELECTED : OS.TREIS_HOT;
if (OS.GetFocus () != handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS;
OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, pRect, backgroundRect);
Expand Down Expand Up @@ -4781,14 +4781,14 @@ void setCheckboxImageList () {
* artifacts, limit the rectangle to actual checkbox bitmap size.
*/
SIZE size = new SIZE();
OS.GetThemePartSize(display.hButtonTheme(), memDC, OS.BP_CHECKBOX, 0, null, OS.TS_TRUE, size);
OS.GetThemePartSize(display.hButtonTheme(getZoom()), memDC, OS.BP_CHECKBOX, 0, null, OS.TS_TRUE, size);
itemWidth = Math.min (size.cx, itemWidth);
itemHeight = Math.min (size.cy, itemHeight);
}
int left = (width - itemWidth) / 2, top = (height - itemHeight) / 2 + 1;
OS.SetRect (rect, left + width, top, left + width + itemWidth, top + itemHeight);
if (OS.IsAppThemed ()) {
long hTheme = display.hButtonTheme ();
long hTheme = display.hButtonTheme(getZoom());
OS.DrawThemeBackground (hTheme, memDC, OS.BP_CHECKBOX, OS.CBS_UNCHECKEDNORMAL, rect, null);
rect.left += width; rect.right += width;
OS.DrawThemeBackground (hTheme, memDC, OS.BP_CHECKBOX, OS.CBS_CHECKEDNORMAL, rect, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2350,7 +2350,7 @@ LRESULT wmPrint (long hwnd, long wParam, long lParam) {
rect.left = rect.top = 0;
int border = getSystemMetrics (OS.SM_CXEDGE);
OS.ExcludeClipRect (wParam, border, border, rect.right - border, rect.bottom - border);
OS.DrawThemeBackground (display.hEditTheme (), wParam, OS.EP_EDITTEXT, OS.ETS_NORMAL, rect, null);
OS.DrawThemeBackground (display.hEditTheme (getZoom()), wParam, OS.EP_EDITTEXT, OS.ETS_NORMAL, rect, null);
return new LRESULT (code);
}
}
Expand Down

0 comments on commit c1b770b

Please sign in to comment.