Allow the application to draw while Windows is in a modal move/resize loop
If you're using the application main callbacks, your SDL_AppIterate() function will be called while Windows is moving and resizing your window. If not, then SDL will send an SDL_EVENT_WINDOW_EXPOSED event for your window and you can use an event watcher to redraw your window directly from the callback. Fixes https://github.com/libsdl-org/SDL/issues/1059 Closes https://github.com/libsdl-org/SDL/pull/4836
This commit is contained in:
@@ -80,6 +80,14 @@ static int SDLCALL SDL_MainCallbackEventWatcher(void *userdata, SDL_Event *event
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_HasMainCallbacks()
|
||||||
|
{
|
||||||
|
if (SDL_main_iteration_callback) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
|
int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
|
||||||
{
|
{
|
||||||
SDL_main_iteration_callback = appiter;
|
SDL_main_iteration_callback = appiter;
|
||||||
@@ -104,16 +112,20 @@ int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_
|
|||||||
return SDL_AtomicGet(&apprc);
|
return SDL_AtomicGet(&apprc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_IterateMainCallbacks(void)
|
int SDL_IterateMainCallbacks(SDL_bool pump_events)
|
||||||
{
|
{
|
||||||
SDL_PumpEvents();
|
if (pump_events) {
|
||||||
|
SDL_PumpEvents();
|
||||||
|
}
|
||||||
SDL_DispatchMainCallbackEvents();
|
SDL_DispatchMainCallbackEvents();
|
||||||
|
|
||||||
int rc = SDL_main_iteration_callback();
|
int rc = SDL_AtomicGet(&apprc);
|
||||||
if (!SDL_AtomicCAS(&apprc, 0, rc)) {
|
if (rc == 0) {
|
||||||
rc = SDL_AtomicGet(&apprc); // something else already set a quit result, keep that.
|
rc = SDL_main_iteration_callback();
|
||||||
|
if (!SDL_AtomicCAS(&apprc, 0, rc)) {
|
||||||
|
rc = SDL_AtomicGet(&apprc); // something else already set a quit result, keep that.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,9 @@
|
|||||||
#ifndef SDL_main_callbacks_h_
|
#ifndef SDL_main_callbacks_h_
|
||||||
#define SDL_main_callbacks_h_
|
#define SDL_main_callbacks_h_
|
||||||
|
|
||||||
int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func _appiter, SDL_AppEvent_func _appevent, SDL_AppQuit_func _appquit);
|
SDL_bool SDL_HasMainCallbacks();
|
||||||
int SDL_IterateMainCallbacks(void);
|
int SDL_InitMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func _appiter, SDL_AppEvent_func _appevent, SDL_AppQuit_func _appquit);
|
||||||
|
int SDL_IterateMainCallbacks(SDL_bool pump_events);
|
||||||
void SDL_QuitMainCallbacks(void);
|
void SDL_QuitMainCallbacks(void);
|
||||||
|
|
||||||
#endif // SDL_main_callbacks_h_
|
#endif // SDL_main_callbacks_h_
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit,
|
|||||||
|
|
||||||
Uint64 next_iteration = callback_rate_increment ? (SDL_GetTicksNS() + callback_rate_increment) : 0;
|
Uint64 next_iteration = callback_rate_increment ? (SDL_GetTicksNS() + callback_rate_increment) : 0;
|
||||||
|
|
||||||
while ((rc = SDL_IterateMainCallbacks()) == 0) {
|
while ((rc = SDL_IterateMainCallbacks(SDL_TRUE)) == 0) {
|
||||||
// !!! FIXME: this can be made more complicated if we decide to
|
// !!! FIXME: this can be made more complicated if we decide to
|
||||||
// !!! FIXME: optionally hand off callback responsibility to the
|
// !!! FIXME: optionally hand off callback responsibility to the
|
||||||
// !!! FIXME: video subsystem (for example, if Wayland has a
|
// !!! FIXME: video subsystem (for example, if Wayland has a
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
#include "../../events/SDL_touch_c.h"
|
#include "../../events/SDL_touch_c.h"
|
||||||
#include "../../events/scancodes_windows.h"
|
#include "../../events/scancodes_windows.h"
|
||||||
|
#include "../../main/SDL_main_callbacks.h"
|
||||||
|
|
||||||
/* Dropfile support */
|
/* Dropfile support */
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
@@ -106,6 +107,10 @@
|
|||||||
#define IS_SURROGATE_PAIR(h, l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l))
|
#define IS_SURROGATE_PAIR(h, l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef USER_TIMER_MINIMUM
|
||||||
|
#define USER_TIMER_MINIMUM 0x0000000A
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Used to compare Windows message timestamps */
|
/* Used to compare Windows message timestamps */
|
||||||
#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
|
#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
|
||||||
|
|
||||||
@@ -1283,6 +1288,31 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case WM_ENTERSIZEMOVE:
|
||||||
|
case WM_ENTERMENULOOP:
|
||||||
|
{
|
||||||
|
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_TIMER:
|
||||||
|
{
|
||||||
|
if (wParam == (UINT_PTR)SDL_IterateMainCallbacks) {
|
||||||
|
if (SDL_HasMainCallbacks()) {
|
||||||
|
SDL_IterateMainCallbacks(SDL_FALSE);
|
||||||
|
} else {
|
||||||
|
// Send an expose event so the application can redraw
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_EXITSIZEMOVE:
|
||||||
|
case WM_EXITMENULOOP:
|
||||||
|
{
|
||||||
|
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
|
||||||
|
} break;
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
{
|
{
|
||||||
switch (wParam) {
|
switch (wParam) {
|
||||||
|
|||||||
Reference in New Issue
Block a user