Skip to content

Commit 36fa8b7

Browse files
committed
Call the windows message hook while inside a modal message loop
Fixes libsdl-org#12029
1 parent 43b54b3 commit 36fa8b7

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;
@@ -1678,12 +1715,15 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
16781715
case WM_ENTERSIZEMOVE:
16791716
case WM_ENTERMENULOOP:
16801717
{
1681-
data->initial_size_rect.left = data->window->x;
1682-
data->initial_size_rect.right = data->window->x + data->window->w;
1683-
data->initial_size_rect.top = data->window->y;
1684-
data->initial_size_rect.bottom = data->window->y + data->window->h;
1718+
++data->in_modal_loop;
1719+
if (data->in_modal_loop == 1) {
1720+
data->initial_size_rect.left = data->window->x;
1721+
data->initial_size_rect.right = data->window->x + data->window->w;
1722+
data->initial_size_rect.top = data->window->y;
1723+
data->initial_size_rect.bottom = data->window->y + data->window->h;
16851724

1686-
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
1725+
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
1726+
}
16871727
} break;
16881728

16891729
case WM_TIMER:
@@ -1697,7 +1737,10 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
16971737
case WM_EXITSIZEMOVE:
16981738
case WM_EXITMENULOOP:
16991739
{
1700-
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
1740+
--data->in_modal_loop;
1741+
if (data->in_modal_loop == 0) {
1742+
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
1743+
}
17011744
} break;
17021745

17031746
case WM_SIZING:
@@ -2299,16 +2342,6 @@ static void WIN_UpdateMouseCapture(void)
22992342
}
23002343
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
23012344

2302-
// A message hook called before TranslateMessage()
2303-
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
2304-
static void *g_WindowsMessageHookData = NULL;
2305-
2306-
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
2307-
{
2308-
g_WindowsMessageHook = callback;
2309-
g_WindowsMessageHookData = userdata;
2310-
}
2311-
23122345
int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
23132346
{
23142347
if (g_WindowsEnableMessageLoop) {

src/video/windows/SDL_windowswindow.h

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct SDL_WindowData
8282
bool windowed_mode_was_maximized;
8383
bool in_window_deactivation;
8484
bool force_resizable;
85+
int in_modal_loop;
8586
RECT initial_size_rect;
8687
RECT cursor_clipped_rect; // last successfully committed clipping rect for this window
8788
RECT cursor_ctrlock_rect; // this is Windows-specific, but probably does not need to be per-window

0 commit comments

Comments
 (0)