Skip to content

Commit 89fd482

Browse files
committed
Improve Wine tab/caption sizing and add diagnostic logging
Add Wine-only logging for tab bar, caption, and layout geometry to help diagnose tiny UI under Wine. Log wine: true/false and monitor DPI at startup. Use GetDpiForMonitor via DynGetDpiForMonitor (shcore.dll) so MSVC builds with WINVER=0x0601 compile. Apply GDK_SCALE/QT_SCALE_FACTOR/ELM_SCALE as a Wine DPI override when Linux desktop scaling is not reflected in Win32 DPI APIs.
1 parent 5244282 commit 89fd482

9 files changed

Lines changed: 158 additions & 25 deletions

File tree

src/SumatraPDF.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,13 @@ static void ReplaceDocumentInCurrentTab(LoadArgs* args, DocController* ctrl, Fil
16041604
}
16051605
if (args->showWin) {
16061606
ShowWindow(win->hwndFrame, showType);
1607+
if (IsRunningOnWine()) {
1608+
Rect wr = WindowRect(win->hwndFrame);
1609+
Rect cr = ClientRect(win->hwndFrame);
1610+
logf("LoadDocument: showWin windowRect=(%d,%d,%d,%d) clientRect=(%d,%d,%d,%d) captionRect=(%d,%d,%d,%d)\n",
1611+
wr.x, wr.y, wr.dx, wr.dy, cr.x, cr.y, cr.dx, cr.dy, win->captionRect.x, win->captionRect.y,
1612+
win->captionRect.dx, win->captionRect.dy);
1613+
}
16071614
}
16081615

16091616
#if 0
@@ -2007,6 +2014,14 @@ void ShowMainWindow(MainWindow* win, int windowState) {
20072014
UpdateToolbarFindText(win);
20082015
HwndEnsureVisible(win->hwndFrame);
20092016

2017+
if (IsRunningOnWine()) {
2018+
Rect wr = WindowRect(win->hwndFrame);
2019+
Rect cr = ClientRect(win->hwndFrame);
2020+
logf("ShowMainWindow: windowRect=(%d,%d,%d,%d) clientRect=(%d,%d,%d,%d) captionRect=(%d,%d,%d,%d)\n", wr.x,
2021+
wr.y, wr.dx, wr.dy, cr.x, cr.y, cr.dx, cr.dy, win->captionRect.x, win->captionRect.y, win->captionRect.dx,
2022+
win->captionRect.dy);
2023+
}
2024+
20102025
if (gWindows.Size() == 1 && (true || IsDebuggerPresent())) {
20112026
HwndToForeground(win->hwndFrame);
20122027
}
@@ -4410,13 +4425,22 @@ static void RelayoutFrame(MainWindow* win, bool updateToolbars, int sidebarDx) {
44104425
captionHeight = menuBarDy + (hasFileTabs ? tabHeight : 0);
44114426
}
44124427
win->captionRect = {rc.x, rc.y, rc.dx, captionHeight};
4428+
if (IsRunningOnWine()) {
4429+
logf("RelayoutFrame: tabsInTitlebar tabHeight=%d captionHeight=%d captionRect=(%d,%d,%d,%d) "
4430+
"showingMenuBar=%d\n",
4431+
tabHeight, captionHeight, win->captionRect.x, win->captionRect.y, win->captionRect.dx,
4432+
win->captionRect.dy, (int)showingMenuBar);
4433+
}
44134434
if (updateToolbars) {
44144435
RelayoutCaption(win);
44154436
}
44164437
rc.y += captionHeight;
44174438
rc.dy -= captionHeight;
44184439
} else if (win->tabsVisible) {
44194440
int tabHeight = GetTabbarHeight(win->hwndFrame);
4441+
if (IsRunningOnWine()) {
4442+
logf("RelayoutFrame: tabsVisible tabHeight=%d\n", tabHeight);
4443+
}
44204444
if (updateToolbars) {
44214445
int tabX = MapChildXForRtlParent(win->hwndFrame, rc.x, rc.dx);
44224446
dh.SetWindowPos(win->tabsCtrl->hwnd, nullptr, tabX, rc.y, rc.dx, tabHeight, SWP_NOZORDER);
@@ -8049,6 +8073,10 @@ void RelayoutCaption(MainWindow* win) {
80498073
bool showingMenuBar = IsShowingMenuBarRebar(win);
80508074
int tabHeight = GetTabbarHeight(win->hwndFrame);
80518075
bool isRtl = IsUIRtl();
8076+
if (IsRunningOnWine()) {
8077+
logf("RelayoutCaption: captionRect=(%d,%d,%d,%d) tabHeight=%d showingMenuBar=%d maximized=%d\n", rc.x, rc.y,
8078+
rc.dx, rc.dy, tabHeight, (int)showingMenuBar, (int)maximized);
8079+
}
80528080

80538081
if (showingMenuBar) {
80548082
// Two-row layout:
@@ -8249,6 +8277,9 @@ void RelayoutCaption(MainWindow* win) {
82498277
int tabBarX = MapChildXForRtlParent(win->hwndFrame, tabsX, tabsDx);
82508278
dh.SetWindowPos(win->tabsCtrl->hwnd, nullptr, tabBarX, tabY, tabsDx, tabDy, SWP_NOZORDER);
82518279
dh.End();
8280+
if (IsRunningOnWine()) {
8281+
logf("RelayoutCaption: singleRow btnDy=%d tabY=%d tabDy=%d tabsDx=%d\n", btnDy, tabY, tabDy, tabsDx);
8282+
}
82528283
}
82538284

82548285
UpdateTabWidth(win);
@@ -8510,6 +8541,10 @@ static LRESULT CustomCaptionFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
85108541

85118542
case WM_NCCALCSIZE: {
85128543
RECT* r = wp == TRUE ? &((NCCALCSIZE_PARAMS*)lp)->rgrc[0] : (RECT*)lp;
8544+
if (IsRunningOnWine()) {
8545+
logf("WM_NCCALCSIZE: before=(%ld,%ld,%ld,%ld) zoomed=%d\n", r->left, r->top, r->right, r->bottom,
8546+
(int)IsZoomed(hwnd));
8547+
}
85138548
bool isFullScreen = win->isFullScreen || win->presentation;
85148549
if (IsZoomed(hwnd) && !isFullScreen) {
85158550
int frameX = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
@@ -8524,6 +8559,11 @@ static LRESULT CustomCaptionFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
85248559
// during resize (returning 0 makes DWM clear the surface)
85258560
r->top += 1;
85268561
}
8562+
if (IsRunningOnWine()) {
8563+
logf("WM_NCCALCSIZE: after=(%ld,%ld,%ld,%ld) clientDy=%ld cyFrame=%d cyCaption=%d\n", r->left, r->top,
8564+
r->right, r->bottom, r->bottom - r->top, GetSystemMetrics(SM_CYFRAME),
8565+
GetSystemMetrics(SM_CYCAPTION));
8566+
}
85278567
*callDef = false;
85288568
return 0;
85298569
}

src/SumatraStartup.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,52 @@ static bool IsNoAdminToAdmin(HWND hPrevWnd) {
12111211
return false;
12121212
}
12131213

1214+
static int WineDpiFromEnv() {
1215+
static const char* scaleVars[] = {"GDK_SCALE", "QT_SCALE_FACTOR", "ELM_SCALE"};
1216+
int bestDpi = 0;
1217+
for (const char* var : scaleVars) {
1218+
const char* val = getenv(var);
1219+
if (!val || !*val) {
1220+
continue;
1221+
}
1222+
float scale = (float)atof(val);
1223+
if (scale < 1.f) {
1224+
continue;
1225+
}
1226+
int dpi = (int)(96.f * scale + 0.5f);
1227+
if (dpi > bestDpi) {
1228+
bestDpi = dpi;
1229+
}
1230+
}
1231+
return bestDpi;
1232+
}
1233+
1234+
static void LogWineDpiInfo() {
1235+
if (!IsRunningOnWine()) {
1236+
return;
1237+
}
1238+
HDC screenDC = GetDC(nullptr);
1239+
int screenDpi = screenDC ? GetDeviceCaps(screenDC, LOGPIXELSX) : 0;
1240+
if (screenDC) {
1241+
ReleaseDC(nullptr, screenDC);
1242+
}
1243+
uint monitorDpiX = 0, monitorDpiY = 0;
1244+
HMONITOR mon = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
1245+
HRESULT hr = E_FAIL;
1246+
if (mon && DynGetDpiForMonitor) {
1247+
hr = DynGetDpiForMonitor(mon, 0, &monitorDpiX, &monitorDpiY);
1248+
}
1249+
int envDpi = WineDpiFromEnv();
1250+
if (envDpi > 0) {
1251+
DpiSetWineOverride(envDpi);
1252+
}
1253+
logf("WineDpi: screenDpi=%d monitorDpi=(%u,%u) GetDpiForMonitor hr=0x%lx envDpi=%d overrideDpi=%d "
1254+
"SM_CYCAPTION=%d SM_CYFRAME=%d SM_CXPADDEDBORDER=%d screen=(%d,%d)\n",
1255+
screenDpi, monitorDpiX, monitorDpiY, (unsigned long)hr, envDpi, DpiGet(HWND_DESKTOP),
1256+
GetSystemMetrics(SM_CYCAPTION), GetSystemMetrics(SM_CYFRAME), GetSystemMetrics(SM_CXPADDEDBORDER),
1257+
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
1258+
}
1259+
12141260
#if 0
12151261
static void LogDpiAwareness() {
12161262
if (!DynGetThreadDpiAwarenessContext) {
@@ -1604,6 +1650,8 @@ int APIENTRY WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE, _In_ LPST
16041650
// TODO: only if AttachConsole() succeeds?
16051651
gLogToConsole = true;
16061652
}
1653+
logf("wine: %s\n", IsRunningOnWine() ? "true" : "false");
1654+
LogWineDpiInfo();
16071655

16081656
Flags flags;
16091657
if (ExeHasNameOfStoreInstaller()) {
@@ -1670,6 +1718,7 @@ int APIENTRY WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE, _In_ LPST
16701718
if (logFilePath) {
16711719
StartLogToFile(logFilePath, true);
16721720
LogCommandLine();
1721+
logf("wine: %s\n", IsRunningOnWine() ? "true" : "false");
16731722
}
16741723
// gRedrawLog = true;
16751724
}

src/Tabs.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,15 @@ int GetTabbarHeight(HWND hwnd, float factor) {
7070
if (tabDy < minDy) {
7171
tabDy = minDy;
7272
}
73-
return (int)((float)tabDy * factor);
73+
int res = (int)((float)tabDy * factor);
74+
if (IsRunningOnWine()) {
75+
int dpi = DpiGet(hwnd);
76+
int desktopDpi = DpiGet(HWND_DESKTOP);
77+
logf("GetTabbarHeight: hwnd=%p factor=%g dpi=%d desktopDpi=%d tabDyScaled=%d fontDy=%d "
78+
"minDy=%d result=%d\n",
79+
hwnd, factor, dpi, desktopDpi, DpiScale(hwnd, kTabBarDy), fontDyWithPadding, minDy, res);
80+
}
81+
return res;
7482
}
7583

7684
#if 0

src/Toolbar.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,9 +1366,17 @@ int GetMenuBarRebarHeight(MainWindow* win) {
13661366
// RB_GETBARHEIGHT underreports by 1px without WS_BORDER
13671367
int dy = (int)SendMessageW(win->hwndMenuReBar, RB_GETBARHEIGHT, 0, 0) + 1;
13681368
if (dy > 1) {
1369+
if (IsRunningOnWine()) {
1370+
logf("GetMenuBarRebarHeight: rebar=%p RB_GETBARHEIGHT=%d\n", win->hwndMenuReBar, dy);
1371+
}
13691372
return dy;
13701373
}
1371-
return MenuBarToolbarIdealDy(win);
1374+
int ideal = MenuBarToolbarIdealDy(win);
1375+
if (IsRunningOnWine()) {
1376+
logf("GetMenuBarRebarHeight: rebar=%p RB_GETBARHEIGHT=%d fallbackIdeal=%d\n", win->hwndMenuReBar, dy,
1377+
ideal);
1378+
}
1379+
return ideal;
13721380
}
13731381

13741382
// --- Menu bar as rebar control (used when tabs are in titlebar) ---

src/utils/Dpi.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,46 @@ Per-Monitor DPI Aware:
2020
(as indicated by the WM_DPICHANGED window message).
2121
*/
2222

23-
#include <shellscalingapi.h>
23+
constexpr int kMdtEffectiveDpi = 0;
24+
25+
static int gWineDpiOverride = 0;
26+
27+
void DpiSetWineOverride(int dpi) {
28+
gWineDpiOverride = dpi;
29+
}
30+
31+
static int DpiApplyWineOverride(int dpi) {
32+
if (gWineDpiOverride > dpi) {
33+
return gWineDpiOverride;
34+
}
35+
return dpi;
36+
}
2437

2538
// get uncached dpi
2639
int DpiGetForHwnd(HWND hwnd) {
2740
// GetDpiForWindow() returns defult 96 DPI for desktop window
2841
// (most likely desktop has DPI_AWARENESS set to UNAWARE)
29-
if (!hwnd || (hwnd == HWND_DESKTOP) || (hwnd == GetDesktopWindow())) {
30-
goto GetGlobalDpi;
31-
}
32-
33-
if (DynGetDpiForWindow) {
34-
uint dpi = DynGetDpiForWindow(hwnd);
35-
// returns 0 for HWND_DESKTOP
36-
if (dpi >= 72) {
37-
return (int)dpi;
42+
if (hwnd && hwnd != HWND_DESKTOP && hwnd != GetDesktopWindow()) {
43+
if (DynGetDpiForWindow) {
44+
uint dpiWin = DynGetDpiForWindow(hwnd);
45+
// returns 0 for HWND_DESKTOP
46+
if (dpiWin >= 72) {
47+
return DpiApplyWineOverride((int)dpiWin);
48+
}
3849
}
39-
}
4050

41-
#if 0
42-
// TODO: only available in 8.1
43-
uint dpiX = 96, dpiY = 96;
44-
HMONITOR h = MonitorFromWindow(hwnd, 0);
45-
if (h != nullptr) {
46-
HRESULT hr = GetDpiForMonitor(h, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
47-
if (hr == S_OK) {
48-
return (int)dpiX;
51+
if (DynGetDpiForMonitor) {
52+
uint dpiX = 96, dpiY = 96;
53+
HMONITOR h = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
54+
if (h != nullptr) {
55+
HRESULT hr = DynGetDpiForMonitor(h, kMdtEffectiveDpi, &dpiX, &dpiY);
56+
if (hr == S_OK && dpiX >= 72) {
57+
return DpiApplyWineOverride((int)dpiX);
58+
}
59+
}
4960
}
5061
}
51-
#endif
52-
GetGlobalDpi:
62+
5363
ScopedGetDC dc(hwnd);
5464
int dpi = GetDeviceCaps(dc, LOGPIXELSX);
5565
if (dpi < 72) {
@@ -65,7 +75,7 @@ int DpiGetForHwnd(HWND hwnd) {
6575
if (dpi < 72) {
6676
dpi = 96;
6777
}
68-
return dpi;
78+
return DpiApplyWineOverride(dpi);
6979
}
7080

7181
int DpiGet(HWND hwnd) {

src/utils/Dpi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
int DpiGetForHwnd(HWND);
55
int DpiGet(HWND);
6+
void DpiSetWineOverride(int dpi);
67
int DpiScale(HWND, int);
78
void DpiScale(HWND, int&, int&);
89

src/utils/WinDynCalls.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Sig_GetDpiForWindow DynGetDpiForWindow = nullptr;
2525
Sig_GetThreadDpiAwarenessContext DynGetThreadDpiAwarenessContext = nullptr;
2626
Sig_GetAwarenessFromDpiAwarenessContext DynGetAwarenessFromDpiAwarenessContext = nullptr;
2727
Sig_SetThreadDpiAwarenessContext DynSetThreadDpiAwarenessContext = nullptr;
28+
Sig_GetDpiForMonitor DynGetDpiForMonitor = nullptr;
2829

2930
#define API_LOAD(name) Dyn##name = (Sig_##name)GetProcAddress(h, #name);
3031

@@ -65,6 +66,11 @@ void InitDynCalls() {
6566
DynSetThreadDpiAwarenessContext =
6667
(Sig_SetThreadDpiAwarenessContext)GetProcAddress(h, "SetThreadDpiAwarenessContext");
6768

69+
h = SafeLoadLibrary("shcore.dll");
70+
if (h) {
71+
DynGetDpiForMonitor = (Sig_GetDpiForMonitor)GetProcAddress(h, "GetDpiForMonitor");
72+
}
73+
6874
h = SafeLoadLibrary("uxtheme.dll");
6975
if (h) {
7076
UXTHEME_API_LIST(API_LOAD);

src/utils/WinDynCalls.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ extern Sig_GetThreadDpiAwarenessContext DynGetThreadDpiAwarenessContext;
100100
extern Sig_GetAwarenessFromDpiAwarenessContext DynGetAwarenessFromDpiAwarenessContext;
101101
extern Sig_SetThreadDpiAwarenessContext DynSetThreadDpiAwarenessContext;
102102

103+
// shcore.dll
104+
typedef HRESULT(WINAPI* Sig_GetDpiForMonitor)(HMONITOR, int, UINT*, UINT*);
105+
extern Sig_GetDpiForMonitor DynGetDpiForMonitor;
106+
103107
// uxtheme.dll
104108
#define UXTHEME_API_LIST(V) \
105109
V(IsAppThemed) \

src/wingui/TabsCtrl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ void TabsCtrl::LayoutTabs() {
8484
dx = std::min(tabDefaultDx, maxDx);
8585
}
8686
tabSize = {dx, dy};
87-
// logfa("TabsCtrl::Layout size: (%d, %d), tab size: (%d, %d)\n", rect.dx, rect.dy, tabSize.dx, tabSize.dy);
87+
if (IsRunningOnWine()) {
88+
logf("TabsCtrl::LayoutTabs: hwnd=%p client=(%d,%d) tabSize=(%d,%d) nTabs=%d\n", hwnd, rect.dx, rect.dy,
89+
tabSize.dx, tabSize.dy, nTabs);
90+
}
8891

8992
int closeDy = DpiScale(hwnd, 16);
9093
int closeDx = closeDy;
@@ -112,6 +115,10 @@ void TabsCtrl::LayoutTabs() {
112115
ti->rCloseHit = {xEnd - closeDx - 2 * closePad, 0, closeDx + 2 * closePad, dy};
113116
}
114117
ti->titleSize = HwndMeasureText(hwnd, ti->text, hfont);
118+
if (IsRunningOnWine() && i == 0) {
119+
logf("TabsCtrl::LayoutTabs: titleSize=(%d,%d) fontDyPx=%d\n", ti->titleSize.dx, ti->titleSize.dy,
120+
FontDyPx(hwnd, hfont));
121+
}
115122
int y = (dy - ti->titleSize.dy) / 2;
116123
// logfa(" ti->titleSize.dy: %d\n", ti->titleSize.dy);
117124
if (y < 0) {

0 commit comments

Comments
 (0)