From f997a5f8f6e51db47ca6ecfc11923847ed464094 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Mon, 8 Nov 2021 12:34:14 +0200 Subject: [PATCH] [macOS] Use pre-wait observer to keep main run loop running and redraw window during the window resize and displaying modal popups. --- platform/osx/os_osx.h | 2 ++ platform/osx/os_osx.mm | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index fd317b6df604..51f24af25840 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -175,6 +175,8 @@ class OS_OSX : public OS_Unix { void _update_global_menu(); + static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context); + protected: virtual void initialize_core(); virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 6517549283ae..27baebee8b09 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -389,14 +389,6 @@ - (void)windowDidResize:(NSNotification *)notification { CGLEnable((CGLContextObj)[OS_OSX::singleton->context CGLContextObj], kCGLCESurfaceBackingSize); } - if (OS_OSX::singleton->main_loop) { - Main::force_redraw(); - //Event retrieval blocks until resize is over. Call Main::iteration() directly. - if (!Main::is_iterating()) { //avoid cyclic loop - Main::iteration(); - } - } - /* _GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); _GodotInputWindowSize(window, contentRect.size.width, contentRect.size.height); @@ -3295,11 +3287,25 @@ void _update_keyboard_layouts() { joypad_osx->process_joypads(); } +void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { + // Prevent main loop from sleeping and redraw window during resize / modal popups. + + if (get_singleton()->get_main_loop()) { + Main::force_redraw(); + if (!Main::is_iterating()) { // Avoid cyclic loop. + Main::iteration(); + } + } + + CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping. +} + void OS_OSX::run() { force_quit = false; - if (!main_loop) + if (!main_loop) { return; + } main_loop->init(); @@ -3308,10 +3314,8 @@ void _update_keyboard_layouts() { set_window_fullscreen(true); } - //uint64_t last_ticks=get_ticks_usec(); - - //int frames=0; - //uint64_t frame=0; + CFRunLoopObserverRef pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr); + CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); bool quit = false; @@ -3328,6 +3332,9 @@ void _update_keyboard_layouts() { } }; + CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); + CFRelease(pre_wait_observer); + main_loop->finish(); }