[macOS, 4.0] Fix unresponsive redraw during live resizing.

This commit is contained in:
bruvzg 2022-06-10 14:02:51 +03:00
parent dbd6fa7e33
commit d46bc8f4ac
No known key found for this signature in database
GPG Key ID: 7960FCF39844EC38
4 changed files with 56 additions and 3 deletions

View File

@ -166,6 +166,7 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context");
}
#endif
[wd.window_view updateLayerDelegate];
id = window_id_counter++;
windows[id] = wd;
}

View File

@ -45,6 +45,14 @@
#import <QuartzCore/CAMetalLayer.h>
@interface GodotContentLayerDelegate : NSObject <CALayerDelegate> {
DisplayServer::WindowID window_id;
}
- (void)setWindowID:(DisplayServer::WindowID)wid;
@end
@interface GodotContentView : RootView <NSTextInputClient> {
DisplayServer::WindowID window_id;
NSTrackingArea *tracking_area;
@ -53,12 +61,14 @@
bool mouse_down_control;
bool ignore_momentum_scroll;
bool last_pen_inverted;
id layer_delegate;
}
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy;
- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed;
- (void)setWindowID:(DisplayServer::WindowID)wid;
- (void)updateLayerDelegate;
- (void)cancelComposition;
@end

View File

@ -32,12 +32,49 @@
#include "display_server_macos.h"
#include "key_mapping_macos.h"
#include "main/main.h"
@implementation GodotContentView
@implementation GodotContentLayerDelegate
- (id)init {
self = [super init];
window_id = DisplayServer::INVALID_WINDOW_ID;
return self;
}
- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
- (void)displayLayer:(CALayer *)layer {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (OS::get_singleton()->get_main_loop() && ds->get_is_resizing()) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
Main::iteration();
}
}
}
@end
@implementation GodotContentView
- (void)setFrameSize:(NSSize)newSize {
[super setFrameSize:newSize];
[self.layer setNeedsDisplay]; // Force "drawRect" call.
}
- (void)updateLayerDelegate {
self.layer.delegate = layer_delegate;
self.layer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
self.layer.needsDisplayOnBoundsChange = YES;
}
- (id)init {
self = [super init];
layer_delegate = [[GodotContentLayerDelegate alloc] init];
window_id = DisplayServer::INVALID_WINDOW_ID;
tracking_area = nil;
ime_input_event_in_progress = false;
mouse_down_control = false;
@ -45,6 +82,9 @@
last_pen_inverted = false;
[self updateTrackingAreas];
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;
self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft;
if (@available(macOS 10.13, *)) {
[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]];
#if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM.
@ -58,6 +98,7 @@
- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
[layer_delegate setWindowID:window_id];
}
// MARK: Backing Layer

View File

@ -56,10 +56,11 @@ _FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) {
}
void OS_MacOS::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.
// Prevent main loop from sleeping and redraw window during modal popup display.
// Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates.
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) {
if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD) && !ds->get_is_resizing()) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
Main::iteration();