Skip to content

Commit

Permalink
Allow the application to draw while Windows is in a modal move/resize…
Browse files Browse the repository at this point in the history
… loop

SDL will send an SDL_EVENT_WINDOW_EXPOSED event for your window during the modal interaction and you can use an event watcher to redraw your window directly from the callback.

Fixes #1059
Closes #4836
  • Loading branch information
slouken committed Nov 8, 2023
1 parent 3900fca commit 509c70c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
26 changes: 26 additions & 0 deletions src/video/windows/SDL_windowsevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
#define IS_SURROGATE_PAIR(h, l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l))
#endif

#ifndef USER_TIMER_MINIMUM
#define USER_TIMER_MINIMUM 0x0000000A
#endif

static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey)
{
switch (vkey) {
Expand Down Expand Up @@ -675,6 +679,7 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static SDL_bool s_ModalMoveResizeLoop;
SDL_WindowData *data;
LRESULT returnCode = -1;

Expand Down Expand Up @@ -1253,6 +1258,27 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
} break;

case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
{
SetTimer(hwnd, (UINT_PTR)&s_ModalMoveResizeLoop, USER_TIMER_MINIMUM, NULL);
} break;

case WM_TIMER:
{
if (wParam == (UINT_PTR)&s_ModalMoveResizeLoop) {
// Send an expose event so the application can redraw
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
return 0;
}
} break;

case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
{
KillTimer(hwnd, (UINT_PTR)&s_ModalMoveResizeLoop);
} break;

case WM_SIZE:
{
switch (wParam) {
Expand Down
33 changes: 26 additions & 7 deletions test/testsprite2.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,22 +392,30 @@ void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
SDL_RenderPresent(renderer);
}

void loop()
static void MoveAllSprites()
{
Uint32 now;
int i;
SDL_Event event;

/* Check for events */
while (SDL_PollEvent(&event)) {
SDLTest_CommonEvent(state, &event, &done);
}
for (i = 0; i < state->num_windows; ++i) {
if (state->windows[i] == NULL) {
continue;
}
MoveSprites(state->renderers[i], sprites[i]);
}
}

void loop()
{
Uint32 now;
SDL_Event event;

/* Check for events */
while (SDL_PollEvent(&event)) {
SDLTest_CommonEvent(state, &event, &done);
}

MoveAllSprites();

#ifdef __EMSCRIPTEN__
if (done) {
emscripten_cancel_main_loop();
Expand All @@ -426,6 +434,14 @@ void loop()
}
}

static int SDLCALL ExposeEventWatcher(void *userdata, SDL_Event *event)
{
if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_EXPOSED) {
MoveAllSprites();
}
return 0;
}

int main(int argc, char *argv[])
{
int i;
Expand Down Expand Up @@ -568,6 +584,9 @@ int main(int argc, char *argv[])
}
}

/* Add an event watcher to redraw from within modal window resize/move loops */
SDL_AddEventWatch(ExposeEventWatcher, NULL);

/* Main render loop */
frames = 0;
next_fps_check = SDL_GetTicks() + fps_check_delay;
Expand Down

0 comments on commit 509c70c

Please sign in to comment.