mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 02:15:34 +00:00
app/internal/wm: [macOS] use NSView+NSOpenGLContext, not NSOpenGLContextView
NSOpenGLContextView couples the window manager logic tightly with OpenGL. Use generic NSViews, and attach NSOpenGLContext just like the other platforms. This change prepares for supporting GPU contexts created by clients as well as a future Metal port. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+43
-102
@@ -9,91 +9,21 @@
|
||||
#include <OpenGL/gl3.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
|
||||
NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil];
|
||||
if (!event.hasPreciseScrollingDeltas) {
|
||||
// dx and dy are in rows and columns.
|
||||
dx *= 10;
|
||||
dy *= 10;
|
||||
}
|
||||
gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp], [event modifierFlags]);
|
||||
}
|
||||
|
||||
@interface GioView : NSOpenGLView
|
||||
@interface GioGLContext : NSOpenGLContext
|
||||
@end
|
||||
|
||||
@implementation GioView
|
||||
- (instancetype)initWithFrame:(NSRect)frameRect
|
||||
pixelFormat:(NSOpenGLPixelFormat *)format {
|
||||
return [super initWithFrame:frameRect pixelFormat:format];
|
||||
@implementation GioGLContext
|
||||
- (void) notifyUpdate:(NSNotification*)notification {
|
||||
CGLLockContext([self CGLContextObj]);
|
||||
[self update];
|
||||
CGLUnlockContext([self CGLContextObj]);
|
||||
}
|
||||
- (void)prepareOpenGL {
|
||||
[super prepareOpenGL];
|
||||
// Bind a default VBA to emulate OpenGL ES 2.
|
||||
GLuint defVBA;
|
||||
glGenVertexArrays(1, &defVBA);
|
||||
glBindVertexArray(defVBA);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
- (BOOL)isFlipped {
|
||||
return YES;
|
||||
}
|
||||
- (void)update {
|
||||
[super update];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
- (void)drawRect:(NSRect)r {
|
||||
gio_onDraw((__bridge CFTypeRef)self);
|
||||
}
|
||||
- (void)mouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)mouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)middleMouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)middletMouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)rightMouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)rightMouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)mouseMoved:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)mouseDragged:(NSEvent *)event {
|
||||
handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)scrollWheel:(NSEvent *)event {
|
||||
CGFloat dx = -event.scrollingDeltaX;
|
||||
CGFloat dy = -event.scrollingDeltaY;
|
||||
handleMouse(self, event, GIO_MOUSE_SCROLL, dx, dy);
|
||||
}
|
||||
- (void)keyDown:(NSEvent *)event {
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
gio_onKeys((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags], true);
|
||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
}
|
||||
- (void)keyUp:(NSEvent *)event {
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
gio_onKeys((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags], false);
|
||||
}
|
||||
- (void)insertText:(id)string {
|
||||
const char *utf8 = [string UTF8String];
|
||||
gio_onText((__bridge CFTypeRef)self, (char *)utf8);
|
||||
}
|
||||
- (void)doCommandBySelector:(SEL)sel {
|
||||
// Don't pass commands up the responder chain.
|
||||
// They will end up in a beep.
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
@end
|
||||
|
||||
CFTypeRef gio_createGLView(void) {
|
||||
CFTypeRef gio_createGLContext(void) {
|
||||
@autoreleasepool {
|
||||
NSOpenGLPixelFormatAttribute attr[] = {
|
||||
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||
@@ -105,43 +35,54 @@ CFTypeRef gio_createGLView(void) {
|
||||
NSOpenGLPFAAllowOfflineRenderers,
|
||||
0
|
||||
};
|
||||
id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
|
||||
NSOpenGLPixelFormat *pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
|
||||
|
||||
NSRect frame = NSMakeRect(0, 0, 0, 0);
|
||||
GioView* view = [[GioView alloc] initWithFrame:frame pixelFormat:pixFormat];
|
||||
|
||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||
[view setWantsLayer:YES]; // The default in Mojave.
|
||||
|
||||
return CFBridgingRetain(view);
|
||||
GioGLContext *ctx = [[GioGLContext alloc] initWithFormat:pixFormat shareContext: nil];
|
||||
return CFBridgingRetain(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void gio_setNeedsDisplay(CFTypeRef viewRef) {
|
||||
NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef;
|
||||
[view setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
CFTypeRef gio_contextForView(CFTypeRef viewRef) {
|
||||
NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef;
|
||||
return (__bridge CFTypeRef)view.openGLContext;
|
||||
void gio_setContextView(CFTypeRef ctxRef, CFTypeRef viewRef) {
|
||||
GioGLContext *ctx = (__bridge GioGLContext *)ctxRef;
|
||||
NSView *view = (__bridge NSView *)viewRef;
|
||||
[ctx setView:view];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:ctx
|
||||
selector:@selector(notifyUpdate:)
|
||||
name:NSViewGlobalFrameDidChangeNotification
|
||||
object:view];
|
||||
}
|
||||
|
||||
void gio_clearCurrentContext(void) {
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
@autoreleasepool {
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
}
|
||||
|
||||
void gio_makeCurrentContext(CFTypeRef ctxRef) {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
[ctx makeCurrentContext];
|
||||
@autoreleasepool {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
[ctx makeCurrentContext];
|
||||
}
|
||||
}
|
||||
|
||||
void gio_lockContext(CFTypeRef ctxRef) {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
CGLLockContext([ctx CGLContextObj]);
|
||||
@autoreleasepool {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
CGLLockContext([ctx CGLContextObj]);
|
||||
}
|
||||
}
|
||||
|
||||
void gio_unlockContext(CFTypeRef ctxRef) {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
CGLUnlockContext([ctx CGLContextObj]);
|
||||
@autoreleasepool {
|
||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||
CGLUnlockContext([ctx CGLContextObj]);
|
||||
}
|
||||
}
|
||||
|
||||
void gio_prepareContext(void) {
|
||||
// Bind a default VBA to emulate OpenGL ES 2.
|
||||
GLuint defVBA;
|
||||
glGenVertexArrays(1, &defVBA);
|
||||
glBindVertexArray(defVBA);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user