From 68997f260fda7994ae0f9772fdb66489e18e305c Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Wed, 22 Jan 2025 10:03:53 +0800 Subject: [PATCH] Fix auto-hide taskbar overlapping issue when maximized (#8118) Fix auto-hide taskbar overlapping issue when maximized (SoftFever/OrcaSlicer#8085) --- src/slic3r/GUI/MainFrame.cpp | 65 +++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 123939efb0..945e8b493e 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -66,6 +66,7 @@ #ifdef _WIN32 #include #include +#include #endif // _WIN32 #include @@ -634,8 +635,64 @@ void MainFrame::bind_diff_dialog() #ifdef __WIN32__ +// Orca: Fix maximized window overlaps taskbar when taskbar auto hide is enabled (#8085) +// Adopted from https://gist.github.com/MortenChristiansen/6463580 +static void AdjustWorkingAreaForAutoHide(const HWND hWnd, MINMAXINFO* mmi) +{ + const auto taskbarHwnd = FindWindowA("Shell_TrayWnd", nullptr); + if (!taskbarHwnd) { + return; + } + const auto monitorContainingApplication = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL); + const auto monitorWithTaskbarOnIt = MonitorFromWindow(taskbarHwnd, MONITOR_DEFAULTTONULL); + if (monitorContainingApplication != monitorWithTaskbarOnIt) { + return; + } + APPBARDATA abd; + abd.cbSize = sizeof(APPBARDATA); + abd.hWnd = taskbarHwnd; + + // Find if task bar has auto-hide enabled + const auto uState = (UINT) SHAppBarMessage(ABM_GETSTATE, &abd); + if ((uState & ABS_AUTOHIDE) != ABS_AUTOHIDE) { + return; + } + + RECT borderThickness; + SetRectEmpty(&borderThickness); + AdjustWindowRectEx(&borderThickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, 0); + + // Determine taskbar position + SHAppBarMessage(ABM_GETTASKBARPOS, &abd); + const auto& rc = abd.rc; + if (rc.top == rc.left && rc.bottom > rc.right) { + // Left + const auto offset = borderThickness.left + 2; + mmi->ptMaxPosition.x += offset; + mmi->ptMaxTrackSize.x -= offset; + mmi->ptMaxSize.x -= offset; + } else if (rc.top == rc.left && rc.bottom < rc.right) { + // Top + const auto offset = borderThickness.top + 2; + mmi->ptMaxPosition.y += offset; + mmi->ptMaxTrackSize.y -= offset; + mmi->ptMaxSize.y -= offset; + } else if (rc.top > rc.left) { + // Bottom + const auto offset = borderThickness.bottom + 2; + mmi->ptMaxSize.y -= offset; + mmi->ptMaxTrackSize.y -= offset; + } else { + // Right + const auto offset = borderThickness.right + 2; + mmi->ptMaxSize.x -= offset; + mmi->ptMaxTrackSize.x -= offset; + } +} + WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { + HWND hWnd = GetHandle(); /* When we have a custom titlebar in the window, we don't need the non-client area of a normal window * to be painted. In order to achieve this, we handle the "WM_NCCALCSIZE" which is responsible for the * size of non-client area of a window and set the return value to 0. Also we have to tell the @@ -654,7 +711,6 @@ WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam its wParam value is TRUE and the return value is 0 */ case WM_NCCALCSIZE: if (wParam) { - HWND hWnd = GetHandle(); /* Detect whether window is maximized or not. We don't need to change the resize border when win is * maximized because all resize borders are gone automatically */ WINDOWPLACEMENT wPos; @@ -677,6 +733,13 @@ WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam } } break; + + case WM_GETMINMAXINFO: { + auto mmi = (MINMAXINFO*) lParam; + HandleGetMinMaxInfo(mmi); + AdjustWorkingAreaForAutoHide(hWnd, mmi); + return 0; + } } return wxFrame::MSWWindowProc(nMsg, wParam, lParam); }