Skip to content

Commit

Permalink
impr: Further try to improve window resize flickering on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
WerWolv committed Jun 29, 2024
1 parent dffb7e9 commit ad235fa
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
2 changes: 1 addition & 1 deletion main/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
Expand Down
60 changes: 58 additions & 2 deletions main/gui/source/window/win_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "messaging.hpp"

#include <hex/helpers/utils.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>

Expand All @@ -24,6 +24,7 @@
#include <wrl/client.h>
#include <fcntl.h>
#include <shellapi.h>
#include <timeapi.h>

#include <cstdio>

Expand Down Expand Up @@ -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<LPWINDOWPOS>(lParam);
windowPos->flags |= SWP_NOCOPYBITS;
break;
}
case WM_NCHITTEST: {
// Handle window resizing and moving
Expand Down Expand Up @@ -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<Window *>(glfwGetWindowUserPointer(window));

win->fullFrame();
DwmFlush();
});
Expand Down
10 changes: 10 additions & 0 deletions main/gui/source/window/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion plugins/builtin/source/content/window_decoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit ad235fa

Please sign in to comment.