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

Add SDL_SetModalLoopCallback, SDL_SetModalLoopResizeCallback and SDL_SetModalLoopMoveCallback functions #4836

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 54 additions & 0 deletions include/SDL_events.h
Expand Up @@ -1151,6 +1151,60 @@ extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state);
*/
extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);

typedef void (SDLCALL * SDL_ModalLoopCallback)(void*);

/**
* Set a callback to be called during a window modal loop.
*
* This can be used to run some logic and keep the app running when it is stuck
* in a modal loop.
*
* \param callback the function to call in the window modal loop
* \param userdata a pointer that is passed to `callback`
*
* \since This function is available since SDL 2.24.0.
*
* \sa SDL_SetModalLoopResizeCallback
* \sa SDL_SetModalLoopMoveCallback
*/
extern DECLSPEC void SDLCALL SDL_SetModalLoopCallback(SDL_ModalLoopCallback callback, void* userdata);

typedef void (SDLCALL * SDL_ModalLoopResizeCallback)(SDL_Window*, int, int, void*);

/**
* Set a callback to be called when a window is resized in a modal loop.
*
* During a modal loop, you won't get any SDL events, so in order to handle
* the window resizing in this case, use this function.
*
* \param callback the function to call when the window is resized in the modal loop
* \param userdata a pointer that is passed to `callback`
*
* \since This function is available since SDL 2.24.0.
*
* \sa SDL_SetModalLoopCallback
* \sa SDL_SetModalLoopMoveCallback
*/
extern DECLSPEC void SDLCALL SDL_SetModalLoopResizeCallback(SDL_ModalLoopResizeCallback resize_callback, void* userdata);

typedef void (SDLCALL * SDL_ModalLoopMoveCallback)(SDL_Window*, int, int, void*);

/**
* Set a callback to be called when a window is moved in a modal loop.
*
* During a modal loop, you won't get any SDL events, so in order to handle
* the window move in this case, use this function.
*
* \param callback the function to call when the window is moved in the modal loop
* \param userdata a pointer that is passed to `callback`
*
* \since This function is available since SDL 2.24.0.
*
* \sa SDL_SetModalLoopCallback
* \sa SDL_SetModalLoopResizeCallback
*/
extern DECLSPEC void SDLCALL SDL_SetModalLoopMoveCallback(SDL_ModalLoopMoveCallback move_callback, void* userdata);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
Expand Down
3 changes: 3 additions & 0 deletions src/dynapi/SDL2.exports
Expand Up @@ -849,3 +849,6 @@
++'_SDL_HasLASX'.'SDL2.dll'.'SDL_HasLASX'
++'_SDL_RenderGetD3D12Device'.'SDL2.dll'.'SDL_RenderGetD3D12Device'
++'_SDL_utf8strnlen'.'SDL2.dll'.'SDL_utf8strnlen'
++'_SDL_SetModalLoopCallback'.'SDL2.dll'.'SDL_SetModalLoopCallback'
++'_SDL_SetModalLoopResizeCallback'.'SDL2.dll'.'SDL_SetModalLoopResizeCallback'
++'_SDL_SetModalLoopMoveCallback'.'SDL2.dll'.'SDL_SetModalLoopMoveCallback'
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -875,3 +875,6 @@
#define SDL_HasLASX SDL_HasLASX_REAL
#define SDL_RenderGetD3D12Device SDL_RenderGetD3D12Device_REAL
#define SDL_utf8strnlen SDL_utf8strnlen_REAL
#define SDL_SetModalLoopCallback SDL_SetModalLoopCallback_REAL
#define SDL_SetModalLoopResizeCallback SDL_SetModalLoopResizeCallback_REAL
#define SDL_SetModalLoopMoveCallback SDL_SetModalLoopMoveCallback_REAL
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -952,3 +952,6 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasLASX,(void),(),return)
SDL_DYNAPI_PROC(ID3D12Device*,SDL_RenderGetD3D12Device,(SDL_Renderer *a),(a),return)
#endif
SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_SetModalLoopCallback,(SDL_ModalLoopCallback a, void *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_SetModalLoopResizeCallback,(SDL_ModalLoopResizeCallback a, void *b),(a,b),)
RT2Code marked this conversation as resolved.
Show resolved Hide resolved
SDL_DYNAPI_PROC(void,SDL_SetModalLoopMoveCallback,(SDL_ModalLoopMoveCallback a, void *b),(a,b),)
55 changes: 55 additions & 0 deletions src/events/SDL_events.c
Expand Up @@ -1415,4 +1415,59 @@ SDL_EventsQuit(void)
#endif
}

static SDL_ModalLoopCallback SDL_modal_loop_callback = NULL;
static void* SDL_modal_loop_userdata = NULL;

void
SDL_SetModalLoopCallback(SDL_ModalLoopCallback callback, void* userdata)
{
SDL_modal_loop_callback = callback;
SDL_modal_loop_userdata = userdata;
}

void
SDL_ExecuteModalLoopCallback(void)
{
if (SDL_modal_loop_callback) {
SDL_modal_loop_callback(SDL_modal_loop_userdata);
}
}

static SDL_ModalLoopResizeCallback SDL_modal_loop_resize_callback = NULL;
static void* SDL_modal_loop_resize_userdata = NULL;

void
SDL_SetModalLoopResizeCallback(SDL_ModalLoopResizeCallback resizeCallback, void* userdata)
{
SDL_modal_loop_resize_callback = resizeCallback;
SDL_modal_loop_resize_userdata = userdata;
}

extern void
SDL_ExecuteModalLoopResizeCallback(SDL_Window* window, int w, int h)
{
if (SDL_modal_loop_resize_callback) {
SDL_modal_loop_resize_callback(window, w, h, SDL_modal_loop_resize_userdata);
}
}

static SDL_ModalLoopMoveCallback SDL_modal_loop_move_callback = NULL;
static void* SDL_modal_loop_move_userdata = NULL;

void
SDL_SetModalLoopMoveCallback(SDL_ModalLoopMoveCallback moveCallback, void* userdata)
{
SDL_modal_loop_move_callback = moveCallback;
SDL_modal_loop_move_userdata = userdata;
}

extern void
SDL_ExecuteModalLoopMoveCallback(SDL_Window* window, int x, int y)
{
if (SDL_modal_loop_move_callback) {
SDL_modal_loop_move_callback(window, x, y, SDL_modal_loop_move_userdata);
}
}


/* vi: set ts=4 sw=4 expandtab: */
4 changes: 4 additions & 0 deletions src/events/SDL_events_c.h
Expand Up @@ -58,6 +58,10 @@ extern void SDL_SendPendingSignalEvents(void);
extern int SDL_QuitInit(void);
extern void SDL_QuitQuit(void);

extern void SDL_ExecuteModalLoopCallback(void);
extern void SDL_ExecuteModalLoopResizeCallback(SDL_Window* window, int w, int h);
extern void SDL_ExecuteModalLoopMoveCallback(SDL_Window* window, int x, int y);

#endif /* SDL_events_c_h_ */

/* vi: set ts=4 sw=4 expandtab: */
42 changes: 42 additions & 0 deletions src/video/windows/SDL_windowsevents.c
Expand Up @@ -95,6 +95,9 @@
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02E4
#endif
#ifndef USER_TIMER_MINIMUM
#define USER_TIMER_MINIMUM 0x0000000A
#endif

#ifndef IS_HIGH_SURROGATE
#define IS_HIGH_SURROGATE(x) (((x) >= 0xd800) && ((x) <= 0xdbff))
Expand Down Expand Up @@ -632,6 +635,8 @@ static void WIN_CheckICMProfileChanged(SDL_Window* window)
}
}

static SDL_Window* g_ModalLoopWindow = NULL;

LRESULT CALLBACK
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Expand Down Expand Up @@ -1203,6 +1208,23 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;

case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
{
SDL_assert(!g_ModalLoopWindow);
g_ModalLoopWindow = data->window;
SetTimer(hwnd, (UINT_PTR)g_ModalLoopWindow, USER_TIMER_MINIMUM, NULL);
}
break;

case WM_TIMER:
{
if (g_ModalLoopWindow && wParam == (UINT_PTR)g_ModalLoopWindow) {
SDL_ExecuteModalLoopCallback();
}
}
break;

case WM_SIZE:
{
switch (wParam) {
Expand All @@ -1223,6 +1245,26 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
default:
break;
}
if (g_ModalLoopWindow) {
SDL_ExecuteModalLoopResizeCallback(g_ModalLoopWindow, LOWORD(lParam), HIWORD(lParam));
}
}
break;

case WM_MOVE:
{
if (g_ModalLoopWindow) {
SDL_ExecuteModalLoopMoveCallback(g_ModalLoopWindow, LOWORD(lParam), HIWORD(lParam));
}
}
break;

case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
{
SDL_assert(g_ModalLoopWindow);
KillTimer(hwnd, (UINT_PTR)g_ModalLoopWindow);
g_ModalLoopWindow = NULL;
}
break;

Expand Down