Skip to content

Commit b476695

Browse files
committed
Call the windows message hook while inside a modal message loop
Fixes #12029
1 parent b6d0bc0 commit b476695

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

src/video/windows/SDL_windowsevents.c

+49-16
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,16 @@ static Uint64 WIN_GetEventTimestamp(void)
174174
return timestamp;
175175
}
176176

177+
// A message hook called before TranslateMessage()
178+
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
179+
static void *g_WindowsMessageHookData = NULL;
180+
181+
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
182+
{
183+
g_WindowsMessageHook = callback;
184+
g_WindowsMessageHookData = userdata;
185+
}
186+
177187
static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam, Uint16 *rawcode, bool *virtual_key)
178188
{
179189
SDL_Scancode code;
@@ -1042,6 +1052,25 @@ static bool SkipAltGrLeftControl(WPARAM wParam, LPARAM lParam)
10421052
return false;
10431053
}
10441054

1055+
static bool DispatchModalLoopMessageHook(HWND *hwnd, UINT *msg, WPARAM *wParam, LPARAM *lParam)
1056+
{
1057+
MSG dummy;
1058+
1059+
SDL_zero(dummy);
1060+
dummy.hwnd = *hwnd;
1061+
dummy.message = *msg;
1062+
dummy.wParam = *wParam;
1063+
dummy.lParam = *lParam;
1064+
if (g_WindowsMessageHook(g_WindowsMessageHookData, &dummy)) {
1065+
// Can't modify the hwnd, but everything else is fair game
1066+
*msg = dummy.message;
1067+
*wParam = dummy.wParam;
1068+
*lParam = dummy.lParam;
1069+
return true;
1070+
}
1071+
return false;
1072+
}
1073+
10451074
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
10461075
{
10471076
SDL_WindowData *data;
@@ -1071,6 +1100,14 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
10711100
}
10721101
#endif // WMMSG_DEBUG
10731102

1103+
1104+
if (g_WindowsMessageHook && data->in_modal_loop) {
1105+
// Synthesize a message for window hooks so they can modify the message if desired
1106+
if (!DispatchModalLoopMessageHook(&hwnd, &msg, &wParam, &lParam)) {
1107+
return 0;
1108+
}
1109+
}
1110+
10741111
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
10751112
if (WIN_HandleIMEMessage(hwnd, msg, wParam, &lParam, data->videodata)) {
10761113
return 0;
@@ -1684,12 +1721,15 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
16841721
case WM_ENTERSIZEMOVE:
16851722
case WM_ENTERMENULOOP:
16861723
{
1687-
data->initial_size_rect.left = data->window->x;
1688-
data->initial_size_rect.right = data->window->x + data->window->w;
1689-
data->initial_size_rect.top = data->window->y;
1690-
data->initial_size_rect.bottom = data->window->y + data->window->h;
1724+
++data->in_modal_loop;
1725+
if (data->in_modal_loop == 1) {
1726+
data->initial_size_rect.left = data->window->x;
1727+
data->initial_size_rect.right = data->window->x + data->window->w;
1728+
data->initial_size_rect.top = data->window->y;
1729+
data->initial_size_rect.bottom = data->window->y + data->window->h;
16911730

1692-
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
1731+
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
1732+
}
16931733
} break;
16941734

16951735
case WM_TIMER:
@@ -1703,7 +1743,10 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
17031743
case WM_EXITSIZEMOVE:
17041744
case WM_EXITMENULOOP:
17051745
{
1706-
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
1746+
--data->in_modal_loop;
1747+
if (data->in_modal_loop == 0) {
1748+
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
1749+
}
17071750
} break;
17081751

17091752
case WM_SIZING:
@@ -2305,16 +2348,6 @@ static void WIN_UpdateMouseCapture(void)
23052348
}
23062349
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
23072350

2308-
// A message hook called before TranslateMessage()
2309-
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
2310-
static void *g_WindowsMessageHookData = NULL;
2311-
2312-
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
2313-
{
2314-
g_WindowsMessageHook = callback;
2315-
g_WindowsMessageHookData = userdata;
2316-
}
2317-
23182351
int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
23192352
{
23202353
if (g_WindowsEnableMessageLoop) {

src/video/windows/SDL_windowswindow.h

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct SDL_WindowData
8383
bool in_window_deactivation;
8484
bool force_ws_maximizebox;
8585
bool disable_move_size_events;
86+
int in_modal_loop;
8687
RECT initial_size_rect;
8788
RECT cursor_clipped_rect; // last successfully committed clipping rect for this window
8889
RECT cursor_ctrlock_rect; // this is Windows-specific, but probably does not need to be per-window

0 commit comments

Comments
 (0)