* added (primary-monitor only) fullscreen support for macOS
* improved settings windows a bit
* correct Program::focused() move from Video::exclusive()->fullScreen()
This commit is contained in:
byuu
2019-08-18 03:20:14 +09:00
parent ab25877af4
commit 95831d3675
11 changed files with 99 additions and 33 deletions

View File

@@ -9,6 +9,16 @@ struct VideoCGL;
}
-(id) initWith:(VideoCGL*)video pixelFormat:(NSOpenGLPixelFormat*)pixelFormat;
-(void) reshape;
-(BOOL) acceptsFirstResponder;
@end
@interface RubyWindowCGL : NSWindow <NSWindowDelegate> {
@public
VideoCGL* video;
}
-(id) initWith:(VideoCGL*)video;
-(BOOL) canBecomeKeyWindow;
-(BOOL) canBecomeMainWindow;
@end
struct VideoCGL : VideoDriver, OpenGL {
@@ -23,11 +33,16 @@ struct VideoCGL : VideoDriver, OpenGL {
auto driver() -> string override { return "OpenGL 3.2"; }
auto ready() -> bool override { return _ready; }
auto hasFullScreen() -> bool override { return true; }
auto hasContext() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasFlush() -> bool override { return true; }
auto hasShader() -> bool override { return true; }
auto setFullScreen(bool fullScreen) -> bool override {
return initialize();
}
auto setContext(uintptr context) -> bool override {
return initialize();
}
@@ -100,9 +115,16 @@ struct VideoCGL : VideoDriver, OpenGL {
private:
auto initialize() -> bool {
terminate();
if(!self.context) return false;
if(!self.fullScreen && !self.context) return false;
@autoreleasepool {
if(self.fullScreen) {
window = [[RubyWindowCGL alloc] initWith:this];
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[window toggleFullScreen:nil];
//[NSApp setPresentationOptions:NSApplicationPresentationFullScreen];
}
NSOpenGLPixelFormatAttribute attributeList[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 24,
@@ -111,7 +133,7 @@ private:
0
};
auto context = (NSView*)self.context;
auto context = self.fullScreen ? [window contentView] : (NSView*)self.context;
auto size = [context frame].size;
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
@@ -123,7 +145,7 @@ private:
[view setWantsBestResolutionOpenGLSurface:YES];
[context addSubview:view];
[openGLContext setView:view];
[[view window] makeFirstResponder:view];
[view lockFocus];
OpenGL::initialize(self.shader);
@@ -142,15 +164,26 @@ private:
_ready = false;
OpenGL::terminate();
if(!view) return;
@autoreleasepool {
[view removeFromSuperview];
[view release];
view = nil;
if(view) {
[view removeFromSuperview];
[view release];
view = nil;
}
if(window) {
//[NSApp setPresentationOptions:NSApplicationPresentationDefault];
[window toggleFullScreen:nil];
[window setCollectionBehavior:NSWindowCollectionBehaviorDefault];
[window close];
[window release];
window = nil;
}
}
}
RubyVideoCGL* view = nullptr;
RubyWindowCGL* window = nullptr;
bool _ready = false;
};
@@ -168,4 +201,39 @@ private:
video->output(0, 0);
}
-(BOOL) acceptsFirstResponder {
return YES;
}
-(void) keyDown:(NSEvent*)event {
}
-(void) keyUp:(NSEvent*)event {
}
@end
@implementation RubyWindowCGL : NSWindow
-(id) initWith:(VideoCGL*)videoPointer {
auto primaryRect = [[[NSScreen screens] objectAtIndex:0] frame];
if(self = [super initWithContentRect:primaryRect styleMask:0 backing:NSBackingStoreBuffered defer:YES]) {
video = videoPointer;
[self setDelegate:self];
[self setReleasedWhenClosed:NO];
[self setAcceptsMouseMovedEvents:YES];
[self setTitle:@""];
[self makeKeyAndOrderFront:nil];
}
return self;
}
-(BOOL) canBecomeKeyWindow {
return YES;
}
-(BOOL) canBecomeMainWindow {
return YES;
}
@end

View File

@@ -327,14 +327,14 @@ auto Video::hasMonitors() -> vector<Monitor> {
auto displayID = [screenID unsignedIntValue];
auto displayPort = CGDisplayIOServicePort(displayID);
auto dictionary = IODisplayCreateInfoDictionary(displayPort, 0);
if(auto names = CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
if(auto names = (CFDictionaryRef)CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
auto languageKeys = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
CFDictionaryApplyFunction((CFDictionaryRef)names, MonitorKeyArrayCallback, (void*)languageKeys);
CFDictionaryApplyFunction(names, MonitorKeyArrayCallback, (void*)languageKeys);
auto orderLanguageKeys = CFBundleCopyPreferredLocalizationsFromArray(languageKeys);
CFRelease(languageKeys);
if(orderLanguageKeys && CFArrayGetCount(orderLanguageKeys)) {
auto languageKey = CFArrayGetValueAtIndex(orderLanguageKeys, 0);
auto localName = CFDictionaryGetValue((CFDictionaryRef)names, languageKey);
auto localName = CFDictionaryGetValue(names, languageKey);
monitor.name = {1 + monitors.size(), ": ", [(__bridge NSString*)localName UTF8String]};
CFRelease(localName);
}