From eccd76a6ac77474c793f6230537e8699fe108ef0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 23 Dec 2024 11:09:46 -0800 Subject: [PATCH] Allow rendering during the modal resize loop on macOS Fixes https://github.com/libsdl-org/SDL/issues/11508 (cherry picked from commit 9a43c08146a765fca166586e9739eb26c5309346) (cherry picked from commit 884c8b684abf280b5af825242b234e1c77470a54) --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 6 ++++++ src/video/cocoa/SDL_cocoawindow.h | 3 +++ src/video/cocoa/SDL_cocoawindow.m | 25 +++++++++++++++++++++++++ src/video/windows/SDL_windowsevents.c | 3 +-- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 344efec489..8f1906afbd 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -511,6 +511,7 @@ extern void SDL_OnWindowShown(SDL_Window *window); extern void SDL_OnWindowHidden(SDL_Window *window); extern void SDL_OnWindowMoved(SDL_Window *window); extern void SDL_OnWindowResized(SDL_Window *window); +extern void SDL_OnWindowLiveResizeUpdate(SDL_Window *window); extern void SDL_OnWindowMinimized(SDL_Window *window); extern void SDL_OnWindowRestored(SDL_Window *window); extern void SDL_OnWindowEnter(SDL_Window *window); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index a593e21cd9..c457af7c69 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3171,6 +3171,12 @@ void SDL_OnWindowMoved(SDL_Window *window) } } +void SDL_OnWindowLiveResizeUpdate(SDL_Window *window) +{ + /* Send an expose event so the application can redraw */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_EXPOSED, 0, 0); +} + void SDL_OnWindowMinimized(SDL_Window *window) { if (!DisableUnsetFullscreenOnMinimize(_this)) { diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 0cf9e9a6ee..ea1d5c1459 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -54,6 +54,7 @@ typedef enum NSInteger focusClickPending; int pendingWindowWarpX, pendingWindowWarpY; BOOL isDragAreaRunning; + NSTimer *liveResizeTimer; } -(BOOL) isTouchFromTrackpad:(NSEvent *)theEvent; @@ -77,6 +78,8 @@ typedef enum /* Window delegate functionality */ -(BOOL) windowShouldClose:(id) sender; -(void) windowDidExpose:(NSNotification *) aNotification; +-(void) windowWillStartLiveResize:(NSNotification *)aNotification; +-(void) windowDidEndLiveResize:(NSNotification *)aNotification; -(void) windowDidMove:(NSNotification *) aNotification; -(void) windowDidResize:(NSNotification *) aNotification; -(void) windowDidMiniaturize:(NSNotification *) aNotification; diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 8e22a0c17c..b9d4fe4f38 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -490,11 +490,14 @@ static NSCursor *Cocoa_GetDesiredCursor(void) isMoving = NO; isDragAreaRunning = NO; pendingWindowWarpX = pendingWindowWarpY = INT_MAX; + liveResizeTimer = nil; center = [NSNotificationCenter defaultCenter]; if ([window delegate] != nil) { [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window]; + [center addObserver:self selector:@selector(windowWillStartLiveResize:) name:NSWindowWillStartLiveResizeNotification object:window]; + [center addObserver:self selector:@selector(windowDidEndLiveResize:) name:NSWindowDidEndLiveResizeNotification object:window]; [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window]; [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window]; [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window]; @@ -628,6 +631,8 @@ static NSCursor *Cocoa_GetDesiredCursor(void) if ([window delegate] != self) { [center removeObserver:self name:NSWindowDidExposeNotification object:window]; + [center removeObserver:self name:NSWindowWillStartLiveResizeNotification object:window]; + [center removeObserver:self name:NSWindowDidEndLiveResizeNotification object:window]; [center removeObserver:self name:NSWindowDidMoveNotification object:window]; [center removeObserver:self name:NSWindowDidResizeNotification object:window]; [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window]; @@ -738,6 +743,26 @@ static NSCursor *Cocoa_GetDesiredCursor(void) SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } +- (void)windowWillStartLiveResize:(NSNotification *)aNotification +{ + // We'll try to maintain 60 FPS during live resizing + const NSTimeInterval interval = 1.0 / 60.0; + liveResizeTimer = [NSTimer scheduledTimerWithTimeInterval:interval + repeats:TRUE + block:^(NSTimer *unusedTimer) + { + SDL_OnWindowLiveResizeUpdate(_data.window); + }]; + + [[NSRunLoop currentRunLoop] addTimer:liveResizeTimer forMode:NSRunLoopCommonModes]; +} + +- (void)windowDidEndLiveResize:(NSNotification *)aNotification +{ + [liveResizeTimer invalidate]; + liveResizeTimer = nil; +} + - (void)windowWillMove:(NSNotification *)aNotification { if ([_data.nswindow isKindOfClass:[SDLWindow class]]) { diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 75feb5cbee..f30d659e0f 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1330,8 +1330,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_TIMER: { if (wParam == (UINT_PTR)&s_ModalMoveResizeLoop) { - // Send an expose event so the application can redraw - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + SDL_OnWindowLiveResizeUpdate(data->window); return 0; } } break;