app: [macOS] synchronize rendering with Core Animation for smooth resizes

Magic incantations lifted from

https://thume.ca/2019/06/19/glitchless-metal-window-resizing/

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2023-12-19 17:24:56 -06:00
parent 93ac0b03f1
commit 35785e9c96
4 changed files with 22 additions and 3 deletions
+2 -1
View File
@@ -60,8 +60,9 @@ static void presentDrawable(CFTypeRef queueRef, CFTypeRef drawableRef) {
id<MTLDrawable> drawable = (__bridge id<MTLDrawable>)drawableRef; id<MTLDrawable> drawable = (__bridge id<MTLDrawable>)drawableRef;
id<MTLCommandQueue> queue = (__bridge id<MTLCommandQueue>)queueRef; id<MTLCommandQueue> queue = (__bridge id<MTLCommandQueue>)queueRef;
id<MTLCommandBuffer> cmdBuffer = [queue commandBuffer]; id<MTLCommandBuffer> cmdBuffer = [queue commandBuffer];
[cmdBuffer presentDrawable:drawable];
[cmdBuffer commit]; [cmdBuffer commit];
[cmdBuffer waitUntilScheduled];
[drawable present];
} }
} }
+4 -1
View File
@@ -21,7 +21,10 @@ Class gio_layerClass(void) {
static CFTypeRef getMetalLayer(CFTypeRef viewRef) { static CFTypeRef getMetalLayer(CFTypeRef viewRef) {
@autoreleasepool { @autoreleasepool {
UIView *view = (__bridge UIView *)viewRef; UIView *view = (__bridge UIView *)viewRef;
return CFBridgingRetain(view.layer); CAMetalLayer *l = (CAMetalLayer *)view.layer;
l.needsDisplayOnBoundsChange = YES;
l.presentsWithTransaction = YES;
return CFBridgingRetain(l);
} }
} }
+5 -1
View File
@@ -14,7 +14,11 @@ package app
CALayer *gio_layerFactory(void) { CALayer *gio_layerFactory(void) {
@autoreleasepool { @autoreleasepool {
return [CAMetalLayer layer]; CAMetalLayer *l = [CAMetalLayer layer];
l.autoresizingMask = kCALayerHeightSizable|kCALayerWidthSizable;
l.needsDisplayOnBoundsChange = YES;
l.presentsWithTransaction = YES;
return l;
} }
} }
+11
View File
@@ -195,6 +195,14 @@ static void setScreenFrame(CFTypeRef windowRef, CGFloat x, CGFloat y, CGFloat w,
} }
} }
static void resetLayerFrame(CFTypeRef viewRef) {
@autoreleasepool {
NSView* view = (__bridge NSView *)viewRef;
NSRect r = view.frame;
view.layer.frame = r;
}
}
static void hideWindow(CFTypeRef windowRef) { static void hideWindow(CFTypeRef windowRef) {
@autoreleasepool { @autoreleasepool {
NSWindow* window = (__bridge NSWindow *)windowRef; NSWindow* window = (__bridge NSWindow *)windowRef;
@@ -456,6 +464,9 @@ func (w *window) Configure(options []Option) {
C.setWindowStandardButtonHidden(window, C.NSWindowCloseButton, barTrans) C.setWindowStandardButtonHidden(window, C.NSWindowCloseButton, barTrans)
C.setWindowStandardButtonHidden(window, C.NSWindowMiniaturizeButton, barTrans) C.setWindowStandardButtonHidden(window, C.NSWindowMiniaturizeButton, barTrans)
C.setWindowStandardButtonHidden(window, C.NSWindowZoomButton, barTrans) C.setWindowStandardButtonHidden(window, C.NSWindowZoomButton, barTrans)
// When toggling the titlebar, the layer doesn't update its frame
// until the next resize. Force it.
C.resetLayerFrame(w.view)
} }
w.ProcessEvent(ConfigEvent{Config: w.config}) w.ProcessEvent(ConfigEvent{Config: w.config})
} }