win32 video: add hint for set WS_EX_NOREDIRECTIONBITMAP#15776
Conversation
|
What's the issue with sending SDL_EVENT_WINDOW_EXPOSED in the modal loop? |
|
run the test case. resize window will cause that black bar bottom. |
|
When should send SDL_EVENT_WINDOW_EXPOSED(data1=0)?
Is it mean not send SDL_EVENT_WINDOW_EXPOSED(data1=0) during live resizing? |
|
I confirm that the reason is that SetWindowPos change window size during WM_PAINT with Direct3D flip mode. SetWindowPos trigger WM_NCPAINT cause draw origin from client area left top to window left top. (The issue not occur when WM_NCPAINT return 0;) |
|
The another way is that set WS_EX_NOREDIRECTIONBITMAP with flip mode can fix the issue. |
|
@flibitijibibo, thoughts? |
|
Nothing from me... this supposedly makes the FNA window more like XNA's but if this has an adverse effect on general windowing behavior on Windows we can make it optional or something. |
This not makes the FNA window more like XNA's. XNA only draw when WM_PAINT during live reisze. SDL draw when WM_PAINT and WM_TIMER (by SetTimer with 100Hz at WM_ENTERSIZEMOVE) during live size. When live resize window and stop mouse but no exit resize. WM_PAINT won't continue trigger until continue move mouse to resize. So during live resize in XNA. When you stop move mouse. The game screen will freeze completely. My PR not cause the game freeze. It will draw with 100Hz during live resize. |
|
I think there is a 100Hz source that trigger SDL_EVENT_WINDOW_EXPOSED during live resize. Not need send SDL_EVENT_WINDOW_EXPOSED when WM_PAINT during live resize. May affect some code that use |
|
There is another way to fix issue. Disable WIN_SetWindowSize between WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE. |
|
Acording my test. Reason may call SetWindowPos to change size ten times during modal loop. Maybe not during whole modal loop. I'm not sure. After run reproduce code with not flip mode. Run a normal flip mode app will also occur the issue. |
|
A test case that without Direct3D and SDL. Run test case and drag left border of window to x < 200. Then close test case and run any app with Direct3D flip mode. App Direct3D flip mode will black bar bottom during live resize. #include <stdio.h>
#include <windows.h>
static int windowX;
static unsigned short nSetWindowPos = 0;
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg != 0) {
WINDOWPOS* pos;
switch (msg) {
case WM_WINDOWPOSCHANGED:
pos = lParam;
printf("WM_WINDOWPOSCHANGED %d %d %d %d %X\n", pos->x, pos->y, pos->cx, pos->cy, pos->flags);
windowX = pos->x;
return 0;
case WM_ENTERSIZEMOVE:
printf("WM_ENTERSIZEMOVE\n");
return 0;
case WM_EXITSIZEMOVE:
printf("WM_EXITSIZEMOVE\n");
return 0;
case WM_PAINT:
printf("WM_PAINT %d\n", windowX);
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
if (windowX < 200) {
printf("---------------SetWindowPos Enter %d\n", nSetWindowPos);
for (int i = 0; i < 10; i++) {
SetWindowPos(hwnd, 0, 400 + i, 400 + i, 350 + i, 350 + i, SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSENDCHANGING);
}
printf("---------------SetWindowPos Leave %d\n", nSetWindowPos);
nSetWindowPos++;
}
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
//printf("WindowProc %X---%llX\n", msg, wParam);
break;
}
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
static int WINAPI _WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hbrBackground = COLOR_BACKGROUND;
RegisterClassW(&wc);
// Create the window.
HWND hwnd = CreateWindowExW(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
250, 250, 500, 500,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}
int main() {
return _WinMain(GetModuleHandle(NULL), NULL, GetCommandLine(), SW_SHOW);
} |
I think this way is a good idea. Add a flag or property for SDL_CreateWindowWithProperties to allow CreateWindowEx with ExStyle WS_EX_NOREDIRECTIONBITMAP. How do you think? @slouken |
|
WS_EX_NOREDIRECTIONBITMAP not available on Windows 7. CreateWindowEx return ERROR_INVALID_PARAMETER. It available from Windows 8. |
|
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD not available on Windows 7. CreateSwapChainForHwnd return DXGI_ERROR_INVALID_CALL. It available from Windows 8. |

Description
When modal loop, SDL_EVENT_WINDOW_EXPOSED have sent by WM_TIMER, cancel send it at WM_PAINT.
Existing Issue
fix #15773
Please ignore #15775. The branch do force push by my bad operation, so I can't commit to that PR, I create this PR.