Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDL3.2.8] [Win32] Moving or resizing window is stuttery #12528

Open
michalev-k opened this issue Mar 12, 2025 · 2 comments
Open

[SDL3.2.8] [Win32] Moving or resizing window is stuttery #12528

michalev-k opened this issue Mar 12, 2025 · 2 comments

Comments

@michalev-k
Copy link

On my machine, moving the window by dragging the titlebar is very stuttery.
The resizing behaviour of windows is also suboptimal.
While resizing, more background is showing through then I would like to (The kind that is set with IDXGISwapChain1::SetBackgroundColor).

I have encounter this behaviour in another framework and my own code before.
I dont know the complete reason, but from what I remember this is some faulty behaviour of the nvidia graphics driver.

using SDL 3.2.8 with sdl_gpu using DX12,
On Windows 10.0.19045 Build 19045
with a nvidia 4090 and latest drivers

Calling DwmFlush on WM_MOVING and WM_TIMER events fixes it for me.
DwmFlush on WM_MOVING fixes the stuttery dragging of windows.
DwmFlush on WM_TIMER improves the resizing behaviour.

The code below works well for DX12 but is not perfect for vulkan.
With the latter, dragging the left corner will cause some wonky behaviour.
I assume its because both WM_MOVING and WM_TIMER both fire and cause two flushes.
Maybe one would need to detect if the window is dragged or moved for best behaviour.

LRESULT CALLBACK CustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	WNDPROC ogProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
	LRESULT res = CallWindowProc(ogProc, hwnd, msg, wParam, lParam);

    switch(msg) {
		case WM_MOVING:
		case WM_TIMER: {
			DwmFlush();
		}
    }

	return res;
}

void SDL_FlushOnResizeAndMove(SDL_Window* window) {
	HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
    if (hwnd) {
	WNDPROC ogProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)CustomWndProc);
	SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)(ogProc));
    }
}
@michalev-k
Copy link
Author

After some testing, the opengl backend has the same behaviour and is also fixed by the above code.

@michalev-k
Copy link
Author

After some testing, the opengl backend has the same behaviour and is also fixed by the above code.

Actually scratch that, the opengl backend works fine, it was the dx11 backend that did not work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant