浏览代码

[macOS] Use pre-wait observer to keep main run loop running and redraw window during the window resize and displaying modal popups.

bruvzg 4 年之前
父节点
当前提交
73a774d8d1
共有 3 个文件被更改,包括 24 次插入9 次删除
  1. 0 8
      platform/osx/display_server_osx.mm
  2. 2 0
      platform/osx/os_osx.h
  3. 22 1
      platform/osx/os_osx.mm

+ 0 - 8
platform/osx/display_server_osx.mm

@@ -289,14 +289,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
 		Callable::CallError ce;
 		wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
 	}
-
-	if (OS_OSX::get_singleton()->get_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();
-		}
-	}
 }
 
 - (void)windowDidMove:(NSNotification *)notification {

+ 2 - 0
platform/osx/os_osx.h

@@ -57,6 +57,8 @@ class OS_OSX : public OS_Unix {
 
 	MainLoop *main_loop;
 
+	static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
+
 public:
 	String open_with_filename;
 

+ 22 - 1
platform/osx/os_osx.mm

@@ -549,14 +549,31 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen
 	}
 }
 
+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->initialize();
 
+	CFRunLoopObserverRef pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
+	CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
+
 	bool quit = false;
 	while (!force_quit && !quit) {
 		@try {
@@ -572,6 +589,10 @@ void OS_OSX::run() {
 			ERR_PRINT("NSException: " + String([exception reason].UTF8String));
 		}
 	};
+
+	CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
+	CFRelease(pre_wait_observer);
+
 	main_loop->finalize();
 }