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 eclipse-platform#62 nd eclipse-platform#131
  • Loading branch information
akoch-yatta committed Oct 9, 2024
1 parent bb0f8dd commit cb31fbe
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4581,4 +4581,12 @@ public static int HRESULT_FROM_WIN32(int x) {
public static final native boolean DuplicateHandle(long hSourceProcessHandle, long hSourceHandle, long hTargetProcessHandle,
long [] lpTargetHandle, int dwDesiredAccess, boolean b, int dwOptions);


public static long OpenThemeData(long hwnd, char[] themeName, int dpi) {
if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_1809) {
return OS.OpenThemeDataForDpi(hwnd, themeName, dpi);
} else {
return OS.OpenThemeData(hwnd, themeName);
}
}
}
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,108 @@ 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 {
private long hButtonTheme;
private long hButtonThemeDark;
private long hEditTheme;
private long hExplorerBarTheme;
private long hScrollBarTheme;
private long hScrollBarThemeDark;
private long hTabTheme;

private 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) {
return OS.OpenThemeData(hwndMessage, themeName, dpi);
}
}
/**
* {@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 @@ -3566,7 +3566,7 @@ void sendEraseItemEvent (TableItem item, NMLVCUSTOMDRAW nmcd, long lParam, Event
rect.right += EXPLORER_EXTRA;
pClipRect.right += EXPLORER_EXTRA;
}
long hTheme = OS.OpenThemeData (handle, Display.TREEVIEW);
long hTheme = OS.OpenThemeData (handle, Display.TREEVIEW, getZoom());
int iStateId = selected ? OS.LISS_SELECTED : OS.LISS_HOT;
if (OS.GetFocus () != handle && selected && !drawHot) iStateId = OS.LISS_SELECTEDNOTFOCUS;
if (drawDrophilited) iStateId = OS.LISS_SELECTED;
Expand Down 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 @@ -497,7 +497,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
}
}
draw = false;
long hTheme = OS.OpenThemeData (handle, Display.TREEVIEW);
long hTheme = OS.OpenThemeData (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, pClipRect);
Expand Down 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.OpenThemeData(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 @@ -1140,7 +1140,7 @@ LRESULT CDDS_ITEMPREPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
}
pRect.left -= EXPLORER_EXTRA;
pClipRect.left -= EXPLORER_EXTRA;
long hTheme = OS.OpenThemeData (handle, Display.TREEVIEW);
long hTheme = OS.OpenThemeData (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, pClipRect);
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 cb31fbe

Please sign in to comment.