From ad235fad25ddb1e355c4843f732b9df0799db345 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 29 Jun 2024 23:17:59 +0200 Subject: [PATCH] impr: Further try to improve window resize flickering on Windows --- main/gui/CMakeLists.txt | 2 +- main/gui/source/window/win_window.cpp | 60 ++++++++++++++++++- main/gui/source/window/window.cpp | 10 ++++ .../source/content/window_decoration.cpp | 2 +- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/main/gui/CMakeLists.txt b/main/gui/CMakeLists.txt index bae7eaab7..c5a6e0362 100644 --- a/main/gui/CMakeLists.txt +++ b/main/gui/CMakeLists.txt @@ -60,7 +60,7 @@ target_compile_definitions(main PRIVATE IMHEX_PROJECT_NAME="${PROJECT_NAME}") target_link_libraries(main PRIVATE libromfs-imhex libimhex libwolv ${LIBBACKTRACE_LIBRARIES} LLVMDemangle) if (WIN32) - target_link_libraries(main PRIVATE usp10 wsock32 ws2_32 Dwmapi.lib) + target_link_libraries(main PRIVATE usp10 wsock32 ws2_32 Dwmapi.lib Winmm.lib) else () target_link_libraries(main PRIVATE pthread) endif () diff --git a/main/gui/source/window/win_window.cpp b/main/gui/source/window/win_window.cpp index c9e1cf379..81ca5e98f 100644 --- a/main/gui/source/window/win_window.cpp +++ b/main/gui/source/window/win_window.cpp @@ -5,7 +5,7 @@ #include "messaging.hpp" -#include + #include #include #include @@ -24,6 +24,7 @@ #include #include #include + #include #include @@ -160,7 +161,50 @@ namespace hex { rect = client; } - return 0; + // This code tries to avoid DWM flickering when resizing the window + // It's not perfect, but it's really the best we can do. + + LARGE_INTEGER performanceFrequency = {}; + QueryPerformanceFrequency(&performanceFrequency); + TIMECAPS tc = {}; + timeGetDevCaps(&tc, sizeof(tc)); + + const auto granularity = tc.wPeriodMin; + timeBeginPeriod(tc.wPeriodMin); + + DWM_TIMING_INFO dti = {}; + dti.cbSize = sizeof(dti); + ::DwmGetCompositionTimingInfo(nullptr, &dti); + + LARGE_INTEGER end = {}; + QueryPerformanceCounter(&end); + + const auto period = dti.qpcRefreshPeriod; + const i64 delta = dti.qpcVBlank - end.QuadPart; + + i64 sleepTicks = 0; + i64 sleepMilliSeconds = 0; + if (delta >= 0) { + sleepTicks = delta / period; + } else { + + sleepTicks = -1 + delta / period; + } + + sleepMilliSeconds = delta - (period * sleepTicks); + const double sleepTime = (1000.0 * double(sleepMilliSeconds) / double(performanceFrequency.QuadPart)); + Sleep(DWORD(std::round(sleepTime))); + timeEndPeriod(granularity); + + return WVR_REDRAW; + } + case WM_ERASEBKGND: + return 1; + case WM_WINDOWPOSCHANGING: { + // Make sure that windows discards the entire client area when resizing to avoid flickering + const auto windowPos = reinterpret_cast(lParam); + windowPos->flags |= SWP_NOCOPYBITS; + break; } case WM_NCHITTEST: { // Handle window resizing and moving @@ -562,8 +606,20 @@ namespace hex { ImHexApi::System::impl::setMainWindowSize(width, height); }); + DwmEnableMMCSS(TRUE); + + { + constexpr BOOL value = TRUE; + DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_ENABLED, &value, sizeof(value)); + } + { + constexpr DWMNCRENDERINGPOLICY value = DWMNCRP_ENABLED; + DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &value, sizeof(value)); + } + glfwSetWindowRefreshCallback(m_window, [](GLFWwindow *window) { auto win = static_cast(glfwGetWindowUserPointer(window)); + win->fullFrame(); DwmFlush(); }); diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index c93026f2a..252d21d2e 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -194,6 +194,16 @@ namespace hex { while (!glfwWindowShouldClose(m_window)) { m_lastStartFrameTime = glfwGetTime(); + { + int x = 0, y = 0; + int width = 0, height = 0; + glfwGetWindowPos(m_window, &x, &y); + glfwGetWindowSize(m_window, &width, &height); + + ImHexApi::System::impl::setMainWindowPosition(x, y); + ImHexApi::System::impl::setMainWindowSize(width, height); + } + // Determine if the application should be in long sleep mode bool shouldLongSleep = !m_unlockFrameRate; diff --git a/plugins/builtin/source/content/window_decoration.cpp b/plugins/builtin/source/content/window_decoration.cpp index cf390d900..a6ab17a1c 100644 --- a/plugins/builtin/source/content/window_decoration.cpp +++ b/plugins/builtin/source/content/window_decoration.cpp @@ -146,7 +146,7 @@ namespace hex::plugin::builtin { ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); - const auto windowSize = ImHexApi::System::getMainWindowSize(); + const auto windowSize = ImGui::GetWindowSize(); auto searchBoxSize = ImVec2(s_showSearchBar ? windowSize.x / 2.5 : ImGui::CalcTextSize(s_windowTitle.c_str()).x, titleBarHeight); auto searchBoxPos = ImVec2((windowSize / 2 - searchBoxSize / 2).x, 0); auto titleBarButtonPosY = 0.0F;