+fix: restore previous window position while DPI scaling changed meanwhile

This commit is contained in:
METANEOCORTEX\Kotti 2021-08-23 14:18:10 +02:00
parent eddf46a21c
commit cb96e28cce
5 changed files with 50 additions and 13 deletions

View File

@ -1637,13 +1637,14 @@ void LoadSettings()
if (!Globals.CmdLnFlag_PosParam /*|| g_bStickyWinPos*/) {
WININFO winInfo = g_IniWinInfo;
WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64];
WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64], tchDPI[64];
StringCchPrintf(tchPosX, COUNTOF(tchPosX), L"%ix%i PosX", ResX, ResY);
StringCchPrintf(tchPosY, COUNTOF(tchPosY), L"%ix%i PosY", ResX, ResY);
StringCchPrintf(tchSizeX, COUNTOF(tchSizeX), L"%ix%i SizeX", ResX, ResY);
StringCchPrintf(tchSizeY, COUNTOF(tchSizeY), L"%ix%i SizeY", ResX, ResY);
StringCchPrintf(tchMaximized, COUNTOF(tchMaximized), L"%ix%i Maximized", ResX, ResY);
StringCchPrintf(tchZoom, COUNTOF(tchZoom), L"%ix%i Zoom", ResX, ResY);
StringCchPrintf(tchDPI, COUNTOF(tchDPI), L"%ix%i DPI", ResX, ResY);
winInfo.x = IniSectionGetInt(IniSecWindow, tchPosX, g_IniWinInfo.x);
winInfo.y = IniSectionGetInt(IniSecWindow, tchPosY, g_IniWinInfo.y);
@ -1655,6 +1656,7 @@ void LoadSettings()
winInfo.zoom = (winInfo.zoom + 10) * 10;
}
winInfo.zoom = clampi(winInfo.zoom, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL);
winInfo.dpi = IniSectionGetInt(IniSecWindow, tchDPI, g_IniWinInfo.dpi);
if ((winInfo.x == CW_USEDEFAULT) || (winInfo.y == CW_USEDEFAULT) ||
(winInfo.cx == CW_USEDEFAULT) || (winInfo.cy == CW_USEDEFAULT)) {
@ -2046,13 +2048,14 @@ bool SaveWindowPositionSettings(bool bClearSettings)
int const ResX = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int const ResY = GetSystemMetrics(SM_CYVIRTUALSCREEN);
WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64];
WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64], tchDPI[64];
StringCchPrintf(tchPosX, COUNTOF(tchPosX), L"%ix%i PosX", ResX, ResY);
StringCchPrintf(tchPosY, COUNTOF(tchPosY), L"%ix%i PosY", ResX, ResY);
StringCchPrintf(tchSizeX, COUNTOF(tchSizeX), L"%ix%i SizeX", ResX, ResY);
StringCchPrintf(tchSizeY, COUNTOF(tchSizeY), L"%ix%i SizeY", ResX, ResY);
StringCchPrintf(tchMaximized, COUNTOF(tchMaximized), L"%ix%i Maximized", ResX, ResY);
StringCchPrintf(tchZoom, COUNTOF(tchMaximized), L"%ix%i Zoom", ResX, ResY);
StringCchPrintf(tchDPI, COUNTOF(tchDPI), L"%ix%i DPI", ResX, ResY);
StringCchPrintf(tchZoom, COUNTOF(tchZoom), L"%ix%i Zoom", ResX, ResY);
if (bClearSettings) {
IniSectionDelete(Constants.Window_Section, tchPosX, false);
@ -2061,6 +2064,7 @@ bool SaveWindowPositionSettings(bool bClearSettings)
IniSectionDelete(Constants.Window_Section, tchSizeY, false);
IniSectionDelete(Constants.Window_Section, tchMaximized, false);
IniSectionDelete(Constants.Window_Section, tchZoom, false);
IniSectionDelete(Constants.Window_Section, tchDPI, false);
} else {
// overwrite last saved window position
IniSectionSetInt(Constants.Window_Section, tchPosX, winInfo.x);
@ -2068,7 +2072,9 @@ bool SaveWindowPositionSettings(bool bClearSettings)
IniSectionSetInt(Constants.Window_Section, tchSizeX, winInfo.cx);
IniSectionSetInt(Constants.Window_Section, tchSizeY, winInfo.cy);
IniSectionSetBool(Constants.Window_Section, tchMaximized, winInfo.max);
IniSectionSetBool(Constants.Window_Section, tchMaximized, winInfo.max);
IniSectionSetInt(Constants.Window_Section, tchZoom, winInfo.zoom);
IniSectionSetInt(Constants.Window_Section, tchDPI, winInfo.dpi);
// set current window position as new initial window
g_IniWinInfo = winInfo;
}

View File

@ -4225,6 +4225,23 @@ bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus)
}
//=============================================================================
//
// RelAdjustRectForDPI()
//
//
void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI) {
float const scale = (float)newDPI / (float)(oldDPI != 0 ? oldDPI : 1);
LONG const oldWidth = (rc->right - rc->left);
LONG const oldHeight = (rc->bottom - rc->top);
LONG const newWidth = lroundf((float)oldWidth * scale);
LONG const newHeight = lroundf((float)oldHeight * scale);
rc->left -= (newWidth - oldWidth) >> 1;
rc->right = rc->left + newWidth;
rc->top -= (newHeight - oldHeight) >> 1;
rc->bottom = rc->top + newHeight;
}
//=============================================================================
//
@ -4253,7 +4270,6 @@ bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO *hMonitorInfo) {
// ----------------------------------------------------------------------------
//=============================================================================
//
// WinInfoToScreenCoord()
@ -4329,6 +4345,7 @@ void FitIntoMonitorGeometry(LPRECT pRect, WININFO *pWinInfo, SCREEN_MODE mode, b
pWinInfo->cx = (mi.rcMonitor.right - mi.rcMonitor.left);
pWinInfo->cy = (mi.rcMonitor.bottom - mi.rcMonitor.top);
pWinInfo->max = true;
//~pWinInfo->dpi = Scintilla_GetWindowDPI(hwnd); // don't change
} else {
WININFO wi = *pWinInfo;
WinInfoToScreenCoord(&wi);
@ -4369,6 +4386,7 @@ void FitIntoMonitorGeometry(LPRECT pRect, WININFO *pWinInfo, SCREEN_MODE mode, b
pWinInfo->y = wi.y - (mi.rcWork.top - mi.rcMonitor.top);
pWinInfo->cx = wi.cx;
pWinInfo->cy = wi.cy;
//~pWinInfo->dpi = Scintilla_GetWindowDPI(hwnd); // don't change
}
}
// ----------------------------------------------------------------------------
@ -4415,6 +4433,7 @@ WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int off
wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
wi.max = IsZoomed(hwnd) || (wndpl.flags & WPF_RESTORETOMAXIMIZED);
wi.zoom = SciCall_GetZoom();
wi.dpi = Scintilla_GetWindowDPI(hwnd);
if (Settings2.LaunchInstanceFullVisible) {
RECT rci;
@ -4440,6 +4459,7 @@ WINDOWPLACEMENT WindowPlacementFromInfo(HWND hwnd, const WININFO* pWinInfo, SCRE
if (pWinInfo) {
RECT rc = { 0 };
RectFromWinInfo(pWinInfo, &rc);
winfo = *pWinInfo;
FitIntoMonitorGeometry(&rc, &winfo, mode, false);
if (pWinInfo->max) {

View File

@ -61,6 +61,7 @@ bool SelectDefLineEndingDlg(HWND hwnd,LPARAM piOption);
bool WarnLineEndingDlg(HWND hwnd, EditFileIOStatus* fioStatus);
bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus);
void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI);
bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO *hMonitorInfo);
void WinInfoToScreenCoord(WININFO* pWinInfo);
WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int offset);

View File

@ -1117,8 +1117,9 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
//
WININFO GetFactoryDefaultWndPos(const int flagsPos)
{
HWND const hwnd = GetDesktopWindow();
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);
GetWindowRect(hwnd, &rc);
MONITORINFO mi;
GetMonitorInfoFromRect(&rc, &mi);
WININFO winfo = INIT_WININFO;
@ -1128,6 +1129,7 @@ WININFO GetFactoryDefaultWndPos(const int flagsPos)
winfo.x = (flagsPos == 3) ? mi.rcMonitor.left : winfo.cx;
winfo.max = 0;
winfo.zoom = 100;
winfo.dpi = Scintilla_GetWindowDPI(hwnd);
return winfo;
}
// ----------------------------------------------------------------------------
@ -1155,8 +1157,9 @@ WININFO GetWinInfoByFlag(const int flagsPos)
} else if (flagsPos == 3) {
winfo = GetFactoryDefaultWndPos(flagsPos);
} else if ((flagsPos >= 4) && (flagsPos < 256)) {
HWND const hwnd = GetDesktopWindow();
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);
GetWindowRect(hwnd, &rc);
MONITORINFO mi;
GetMonitorInfoFromRect(&rc, &mi);
@ -1198,11 +1201,13 @@ WININFO GetWinInfoByFlag(const int flagsPos)
winfo.max = true;
winfo.zoom = 100;
}
winfo.dpi = Scintilla_GetWindowDPI(hwnd);
} else { // ( > 256) restore window, move upper left corner to Work Area
MONITORINFO mi;
RECT rc = { 0 };
RectFromWinInfo(&winfo, &rc);
MONITORINFO mi;
GetMonitorInfoFromRect(&rc, &mi);
WININFO wi = winfo;
wi.cx = wi.cy = 16; // really small
@ -1424,14 +1429,12 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow)
hInstance,
NULL);
SnapToWinInfoPos(Globals.hwndMain, g_IniWinInfo, SCR_NORMAL);
if (g_IniWinInfo.max) {
nCmdShow = SW_SHOWMAXIMIZED;
}
if (Settings.AlwaysOnTop) {
SetWindowPos(Globals.hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
SetDialogIconNP3(Globals.hwndMain);
InitWindowCommon(Globals.hwndMain, true);
@ -6436,7 +6439,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
break;
case CMD_FULLSCRWINPOS: {
WININFO const wi = GetMyWindowPlacement(Globals.hwndMain, NULL, 0);
WININFO wi = GetMyWindowPlacement(Globals.hwndMain, NULL, 0);
SnapToWinInfoPos(hwnd, wi, SCR_FULL_SCREEN);
}
break;
@ -11123,6 +11126,12 @@ void SnapToWinInfoPos(HWND hwnd, const WININFO winInfo, SCREEN_MODE mode)
if (GetDoAnimateMinimize()) {
DrawAnimatedRects(hWindow, IDANI_CAPTION, &rcCurrent, &wndpl.rcNormalPosition);
}
if (hwnd) {
UINT const dpi = Scintilla_GetWindowDPI(hwnd);
if (dpi != winInfo.dpi) {
RelAdjustRectForDPI(&wndpl.rcNormalPosition, winInfo.dpi, dpi);
}
}
SetWindowPlacement(hWindow, &wndpl); // 1st set correct screen (DPI Aware)
SetWindowPlacement(hWindow, &wndpl); // 2nd resize position to correct DPI settings
}

View File

@ -84,9 +84,10 @@ typedef struct _wi
int cy;
bool max;
int zoom;
UINT dpi;
} WININFO;
#define INIT_WININFO { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, false, 100 }
#define INIT_WININFO { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, false, 100, USER_DEFAULT_SCREEN_DPI }
typedef enum { SCR_NORMAL = 0, SCR_FULL_SCREEN = 1 } SCREEN_MODE;