defer clipcursor refresh unto pump finish

This commit is contained in:
expikr
2025-04-16 02:50:00 +08:00
committed by Sam Lantinga
parent c84c2aa2c4
commit dd625a6763
3 changed files with 27 additions and 13 deletions

View File

@@ -1240,11 +1240,8 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
case WM_NCACTIVATE: case WM_NCACTIVATE:
{ {
// Don't immediately clip the cursor in case we're clicking minimize/maximize buttons // Don't immediately clip the cursor in case we're clicking minimize/maximize buttons
// This is the only place that this flag is set. This causes all subsequent calls to data->postpone_clipcursor = true;
// WIN_UpdateClipCursor for this window to be no-ops in this frame's message-pumping. data->clipcursor_queued = true;
// This flag is unset at the end of message pumping each frame for every window, and
// should never be carried over between frames.
data->skip_update_clipcursor = true;
/* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without
actually being the foreground window, but this appears to get called in all cases where actually being the foreground window, but this appears to get called in all cases where
@@ -1413,9 +1410,8 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
window->flags & (SDL_WINDOW_MOUSE_RELATIVE_MODE | SDL_WINDOW_MOUSE_GRABBED) || window->flags & (SDL_WINDOW_MOUSE_RELATIVE_MODE | SDL_WINDOW_MOUSE_GRABBED) ||
(window->mouse_rect.w > 0 && window->mouse_rect.h > 0) (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)
); );
if (wish_clip_cursor) { if (wish_clip_cursor) { // queue clipcursor refresh on pump finish
data->skip_update_clipcursor = false; data->clipcursor_queued = true;
WIN_UpdateClipCursor(window);
} }
} }
@@ -1440,6 +1436,9 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, SDL_GLOBAL_MOUSE_ID, false, (float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam)); SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, SDL_GLOBAL_MOUSE_ID, false, (float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam));
} }
} }
return 0;
} break; } break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
@@ -2602,13 +2601,27 @@ void WIN_PumpEvents(SDL_VideoDevice *_this)
} }
} }
// Update the clipping rect in case someone else has stolen it // fire queued clipcursor refreshes
if (_this) { if (_this) {
SDL_Window *window = _this->windows; SDL_Window *window = _this->windows;
while (window) { while (window) {
bool refresh_clipcursor = false;
SDL_WindowData *data = window->internal; SDL_WindowData *data = window->internal;
if (data && data->skip_update_clipcursor) { if (data) {
data->skip_update_clipcursor = false; refresh_clipcursor = data->clipcursor_queued;
data->clipcursor_queued = false; // Must be cleared unconditionally.
data->postpone_clipcursor = false; // Must be cleared unconditionally.
// Must happen before UpdateClipCursor.
// Although its occurrence currently
// always coincides with the queuing of
// clipcursor, it is logically distinct
// and this coincidence might no longer
// be true in the future.
// Ergo this placement concordantly
// conveys its unconditionality
// vis-a-vis the queuing of clipcursor.
}
if (refresh_clipcursor) {
WIN_UpdateClipCursor(window); WIN_UpdateClipCursor(window);
} }
window = window->next; window = window->next;

View File

@@ -1627,7 +1627,7 @@ void WIN_UnclipCursorForWindow(SDL_Window *window) {
void WIN_UpdateClipCursor(SDL_Window *window) void WIN_UpdateClipCursor(SDL_Window *window)
{ {
SDL_WindowData *data = window->internal; SDL_WindowData *data = window->internal;
if (data->in_title_click || data->focus_click_pending || data->skip_update_clipcursor) { if (data->in_title_click || data->focus_click_pending || data->postpone_clipcursor) {
return; return;
} }

View File

@@ -78,7 +78,8 @@ struct SDL_WindowData
bool in_border_change; bool in_border_change;
bool in_title_click; bool in_title_click;
Uint8 focus_click_pending; Uint8 focus_click_pending;
bool skip_update_clipcursor; bool postpone_clipcursor;
bool clipcursor_queued;
bool windowed_mode_was_maximized; bool windowed_mode_was_maximized;
bool in_window_deactivation; bool in_window_deactivation;
bool force_ws_maximizebox; bool force_ws_maximizebox;