Call the windows message hook while inside a modal message loop
Fixes https://github.com/libsdl-org/SDL/issues/12029
This commit is contained in:
parent
b6d0bc0431
commit
b476695e67
2 changed files with 50 additions and 16 deletions
|
@ -174,6 +174,16 @@ static Uint64 WIN_GetEventTimestamp(void)
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A message hook called before TranslateMessage()
|
||||||
|
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
|
||||||
|
static void *g_WindowsMessageHookData = NULL;
|
||||||
|
|
||||||
|
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
|
||||||
|
{
|
||||||
|
g_WindowsMessageHook = callback;
|
||||||
|
g_WindowsMessageHookData = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam, Uint16 *rawcode, bool *virtual_key)
|
static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam, Uint16 *rawcode, bool *virtual_key)
|
||||||
{
|
{
|
||||||
SDL_Scancode code;
|
SDL_Scancode code;
|
||||||
|
@ -1042,6 +1052,25 @@ static bool SkipAltGrLeftControl(WPARAM wParam, LPARAM lParam)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool DispatchModalLoopMessageHook(HWND *hwnd, UINT *msg, WPARAM *wParam, LPARAM *lParam)
|
||||||
|
{
|
||||||
|
MSG dummy;
|
||||||
|
|
||||||
|
SDL_zero(dummy);
|
||||||
|
dummy.hwnd = *hwnd;
|
||||||
|
dummy.message = *msg;
|
||||||
|
dummy.wParam = *wParam;
|
||||||
|
dummy.lParam = *lParam;
|
||||||
|
if (g_WindowsMessageHook(g_WindowsMessageHookData, &dummy)) {
|
||||||
|
// Can't modify the hwnd, but everything else is fair game
|
||||||
|
*msg = dummy.message;
|
||||||
|
*wParam = dummy.wParam;
|
||||||
|
*lParam = dummy.lParam;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data;
|
SDL_WindowData *data;
|
||||||
|
@ -1071,6 +1100,14 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||||
}
|
}
|
||||||
#endif // WMMSG_DEBUG
|
#endif // WMMSG_DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
if (g_WindowsMessageHook && data->in_modal_loop) {
|
||||||
|
// Synthesize a message for window hooks so they can modify the message if desired
|
||||||
|
if (!DispatchModalLoopMessageHook(&hwnd, &msg, &wParam, &lParam)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||||
if (WIN_HandleIMEMessage(hwnd, msg, wParam, &lParam, data->videodata)) {
|
if (WIN_HandleIMEMessage(hwnd, msg, wParam, &lParam, data->videodata)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1684,12 +1721,15 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_ENTERMENULOOP:
|
case WM_ENTERMENULOOP:
|
||||||
{
|
{
|
||||||
data->initial_size_rect.left = data->window->x;
|
++data->in_modal_loop;
|
||||||
data->initial_size_rect.right = data->window->x + data->window->w;
|
if (data->in_modal_loop == 1) {
|
||||||
data->initial_size_rect.top = data->window->y;
|
data->initial_size_rect.left = data->window->x;
|
||||||
data->initial_size_rect.bottom = data->window->y + data->window->h;
|
data->initial_size_rect.right = data->window->x + data->window->w;
|
||||||
|
data->initial_size_rect.top = data->window->y;
|
||||||
|
data->initial_size_rect.bottom = data->window->y + data->window->h;
|
||||||
|
|
||||||
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
|
SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
|
@ -1703,7 +1743,10 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
case WM_EXITMENULOOP:
|
case WM_EXITMENULOOP:
|
||||||
{
|
{
|
||||||
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
|
--data->in_modal_loop;
|
||||||
|
if (data->in_modal_loop == 0) {
|
||||||
|
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case WM_SIZING:
|
case WM_SIZING:
|
||||||
|
@ -2305,16 +2348,6 @@ static void WIN_UpdateMouseCapture(void)
|
||||||
}
|
}
|
||||||
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||||
|
|
||||||
// A message hook called before TranslateMessage()
|
|
||||||
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
|
|
||||||
static void *g_WindowsMessageHookData = NULL;
|
|
||||||
|
|
||||||
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
|
|
||||||
{
|
|
||||||
g_WindowsMessageHook = callback;
|
|
||||||
g_WindowsMessageHookData = userdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
|
int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
|
||||||
{
|
{
|
||||||
if (g_WindowsEnableMessageLoop) {
|
if (g_WindowsEnableMessageLoop) {
|
||||||
|
|
|
@ -83,6 +83,7 @@ struct SDL_WindowData
|
||||||
bool in_window_deactivation;
|
bool in_window_deactivation;
|
||||||
bool force_ws_maximizebox;
|
bool force_ws_maximizebox;
|
||||||
bool disable_move_size_events;
|
bool disable_move_size_events;
|
||||||
|
int in_modal_loop;
|
||||||
RECT initial_size_rect;
|
RECT initial_size_rect;
|
||||||
RECT cursor_clipped_rect; // last successfully committed clipping rect for this window
|
RECT cursor_clipped_rect; // last successfully committed clipping rect for this window
|
||||||
RECT cursor_ctrlock_rect; // this is Windows-specific, but probably does not need to be per-window
|
RECT cursor_ctrlock_rect; // this is Windows-specific, but probably does not need to be per-window
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue