Show mount/wait dialog on the monitor of the main window (#1865)

* Show mount/wait dialog on the monitor of the main window

* Place the wait dialog owner on the monitor chosen by MonitorFromWindow

Instead of the centre of the creator window, put the temporary owner in the
middle of the work area of the monitor returned by MonitorFromWindow
(MONITOR_DEFAULTTONEAREST). The centre point can lie on a different monitor
than most of the window when displays are offset, and Windows may make the
owner larger than the requested 1x1, so an owner close to a monitor edge
could spill onto the neighbouring monitor and take the wait dialog with it.
This commit is contained in:
amail80
2026-10-09 20:41:11 +09:00
committed by GitHub
parent 7c06e03ec3
commit f8e397cd5d
+22 -1
View File
@@ -9145,6 +9145,7 @@ void ShowWaitDialogEx(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback,
{
/* create invisible window and use it as parent */
WNDCLASSEXW winClass;
int parentX = 0, parentY = 0;
memset (&winClass, 0, sizeof (winClass));
winClass.cbSize = sizeof (WNDCLASSEX);
@@ -9153,7 +9154,27 @@ void ShowWaitDialogEx(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback,
winClass.lpszClassName = className;
RegisterClassExW (&winClass);
hParent = CreateWindowExW (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, L"VeraCrypt ShowWaitDialog Parent", 0, 0, 0, 1, 1, NULL, NULL, hInst, NULL);
/* Place the invisible parent in the middle of the work area of the monitor
that Windows associates with the creator window, so that the DS_CENTER
wait dialog is centered on that monitor instead of always appearing on
the primary one. The parent is kept well inside the monitor because
Windows may make it larger than the requested 1x1 size. Falls back to
(0, 0) when the creator window is unavailable, hidden or minimized. */
if (creatorWnd && IsWindowVisible (creatorWnd) && !IsIconic (creatorWnd))
{
HMONITOR hMonitor = MonitorFromWindow (creatorWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO monitorInfo;
memset (&monitorInfo, 0, sizeof (monitorInfo));
monitorInfo.cbSize = sizeof (monitorInfo);
if (hMonitor && GetMonitorInfoW (hMonitor, &monitorInfo))
{
parentX = monitorInfo.rcWork.left + (monitorInfo.rcWork.right - monitorInfo.rcWork.left) / 2;
parentY = monitorInfo.rcWork.top + (monitorInfo.rcWork.bottom - monitorInfo.rcWork.top) / 2;
}
}
hParent = CreateWindowExW (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, L"VeraCrypt ShowWaitDialog Parent", 0, parentX, parentY, 1, 1, NULL, NULL, hInst, NULL);
if (hParent)
{
SetLayeredWindowAttributes (hParent, 0, 1, LWA_ALPHA);