From 9f9ff269fef8ca4869cafab81ab9f53f449e464a Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 26 Dec 2015 18:20:07 -1000 Subject: [PATCH] More TextInput implementation --- CMakeLists.txt | 4 + lib/graphicsdev/Metal.mm | 40 +++++---- lib/mac/ApplicationCocoa.mm | 33 ++++---- lib/mac/CocoaCommon.hpp | 28 ++++-- lib/mac/WindowCocoa.mm | 165 ++++++++++++++++++++---------------- 5 files changed, 160 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 534f90c..514b1e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,10 @@ elseif(APPLE) lib/inputdev/HIDListenerIOKit.cpp lib/inputdev/HIDDeviceIOKit.cpp lib/graphicsdev/Metal.mm) +set_source_files_properties(lib/mac/ApplicationCocoa.mm + lib/mac/WindowCocoa.mm + lib/graphicsdev/Metal.mm + PROPERTIES COMPILE_FLAGS -fobjc-arc) list(APPEND PLAT_HDRS include/boo/graphicsdev/Metal.hpp) diff --git a/lib/graphicsdev/Metal.mm b/lib/graphicsdev/Metal.mm index cb2df07..7a0efac 100644 --- a/lib/graphicsdev/Metal.mm +++ b/lib/graphicsdev/Metal.mm @@ -5,6 +5,10 @@ #include "boo/IGraphicsContext.hpp" #include +#if !__has_feature(objc_arc) +#error ARC Required +#endif + #define MAX_UNIFORM_COUNT 8 #define MAX_TEXTURE_COUNT 8 @@ -94,9 +98,9 @@ class MetalTextureS : public ITextureS NSPtr desc; @autoreleasepool { - desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pfmt - width:width height:height - mipmapped:(mips>1)?YES:NO] retain]; + desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pfmt + width:width height:height + mipmapped:(mips>1)?YES:NO]; } desc.get().usage = MTLTextureUsageShaderRead; desc.get().mipmapLevelCount = mips; @@ -138,9 +142,9 @@ class MetalTextureSA : public ITextureSA NSPtr desc; @autoreleasepool { - desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pfmt - width:width height:height - mipmapped:NO] retain]; + desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pfmt + width:width height:height + mipmapped:NO]; } desc.get().textureType = MTLTextureType2DArray; desc.get().arrayLength = layers; @@ -198,9 +202,9 @@ class MetalTextureD : public ITextureD NSPtr desc; @autoreleasepool { - desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format - width:width height:height - mipmapped:NO] retain]; + desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format + width:width height:height + mipmapped:NO]; } desc.get().usage = MTLTextureUsageShaderRead; m_texs[0] = [ctx->m_dev.get() newTextureWithDescriptor:desc.get()]; @@ -229,10 +233,10 @@ class MetalTextureR : public ITextureR NSPtr desc; @autoreleasepool { - desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm - width:width height:height - mipmapped:NO] retain]; - m_passDesc = [[MTLRenderPassDescriptor renderPassDescriptor] retain]; + desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm + width:width height:height + mipmapped:NO]; + m_passDesc = [MTLRenderPassDescriptor renderPassDescriptor]; } desc.get().usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; desc.get().storageMode = MTLStorageModePrivate; @@ -555,7 +559,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue { @autoreleasepool { - m_cmdBuf = [[ctx->m_q.get() commandBuffer] retain]; + m_cmdBuf = [ctx->m_q.get() commandBuffer]; } } @@ -586,7 +590,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue [m_enc.get() endEncoding]; @autoreleasepool { - m_enc = [[m_cmdBuf.get() renderCommandEncoderWithDescriptor:ctarget->m_passDesc.get()] retain]; + m_enc = [m_cmdBuf.get() renderCommandEncoderWithDescriptor:ctarget->m_passDesc.get()]; } m_boundTarget = ctarget; } @@ -738,7 +742,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue /* Abandon if in progress (renderer too slow) */ if (m_inProgress) { - m_cmdBuf = [[m_ctx->m_q.get() commandBuffer] retain]; + m_cmdBuf = [m_ctx->m_q.get() commandBuffer]; return; } @@ -748,7 +752,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue for (const auto& resize : m_texResizes) resize.first->resize(m_ctx, resize.second.first, resize.second.second); m_texResizes.clear(); - m_cmdBuf = [[m_ctx->m_q.get() commandBuffer] retain]; + m_cmdBuf = [m_ctx->m_q.get() commandBuffer]; return; } @@ -758,7 +762,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue [m_cmdBuf.get() addCompletedHandler:^(id buf) {m_inProgress = false;}]; m_inProgress = true; [m_cmdBuf.get() commit]; - m_cmdBuf = [[m_ctx->m_q.get() commandBuffer] retain]; + m_cmdBuf = [m_ctx->m_q.get() commandBuffer]; } } }; diff --git a/lib/mac/ApplicationCocoa.mm b/lib/mac/ApplicationCocoa.mm index 9e71041..4dafbed 100644 --- a/lib/mac/ApplicationCocoa.mm +++ b/lib/mac/ApplicationCocoa.mm @@ -7,6 +7,10 @@ #include +#if !__has_feature(objc_arc) +#error ARC Required +#endif + namespace boo {class ApplicationCocoa;} @interface AppDelegate : NSObject { @@ -26,8 +30,8 @@ IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, class ApplicationCocoa : public IApplication { public: - NSApplication* m_app = nullptr; IApplicationCallback& m_callback; + AppDelegate* m_appDelegate; private: const SystemString m_uniqueName; const SystemString m_friendlyName; @@ -37,13 +41,13 @@ private: NSPanel* aboutPanel; /* All windows */ - std::unordered_map m_windows; + std::unordered_map m_windows; MetalContext m_metalCtx; void _deletedWindow(IWindow* window) { - m_windows.erase((NSWindow*)window->getPlatformHandle()); + m_windows.erase(window->getPlatformHandle()); } public: @@ -58,17 +62,16 @@ public: m_pname(pname), m_args(args) { - m_app = [NSApplication sharedApplication]; - [m_app setActivationPolicy:NSApplicationActivationPolicyRegular]; + [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular]; /* Delegate (OS X callbacks) */ - AppDelegate* appDelegate = [[AppDelegate alloc] initWithApp:this]; - [m_app setDelegate:appDelegate]; + m_appDelegate = [[AppDelegate alloc] initWithApp:this]; + [[NSApplication sharedApplication] setDelegate:m_appDelegate]; /* App menu */ NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"main"]; - NSMenu* rwkMenu = [[NSMenu alloc] initWithTitle:[[NSString stringWithUTF8String:m_friendlyName.c_str()] autorelease]]; - [rwkMenu addItemWithTitle:[[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] autorelease] + NSMenu* rwkMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()]]; + [rwkMenu addItemWithTitle:[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] action:@selector(aboutApp:) keyEquivalent:@""]; NSMenuItem* fsItem = [rwkMenu addItemWithTitle:@"Toggle Full Screen" @@ -76,11 +79,11 @@ public: keyEquivalent:@"f"]; [fsItem setKeyEquivalentModifierMask:NSCommandKeyMask]; [rwkMenu addItem:[NSMenuItem separatorItem]]; - NSMenuItem* quit_item = [rwkMenu addItemWithTitle:[[NSString stringWithFormat:@"Quit %s", m_friendlyName.c_str()] autorelease] + NSMenuItem* quit_item = [rwkMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %s", m_friendlyName.c_str()] action:@selector(quitApp:) keyEquivalent:@"q"]; [quit_item setKeyEquivalentModifierMask:NSCommandKeyMask]; - [[appMenu addItemWithTitle:[[NSString stringWithUTF8String:m_friendlyName.c_str()] autorelease] + [[appMenu addItemWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()] action:nil keyEquivalent:@""] setSubmenu:rwkMenu]; [[NSApplication sharedApplication] setMainMenu:appMenu]; @@ -89,13 +92,13 @@ public: aboutPanel = [[NSPanel alloc] initWithContentRect:aboutCr styleMask:NSUtilityWindowMask|NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:YES]; - [aboutPanel setTitle:[[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] autorelease]]; + [aboutPanel setTitle:[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()]]; NSText* aboutText = [[NSText alloc] initWithFrame:aboutCr]; [aboutText setEditable:NO]; [aboutText setAlignment:NSCenterTextAlignment]; [aboutText setString:@"\nBoo Authors\n\nJackoalan\nAntidote\n"]; [aboutPanel setContentView:aboutText]; - appDelegate->aboutPanel = aboutPanel; + m_appDelegate->aboutPanel = aboutPanel; /* Determine which graphics API to use */ #if BOO_HAS_METAL @@ -166,7 +169,7 @@ public: IWindow* newWindow(const std::string& title) { IWindow* newWindow = _WindowCocoaNew(title, m_lastGLCtx, &m_metalCtx); - m_windows[(NSWindow*)newWindow->getPlatformHandle()] = newWindow; + m_windows[newWindow->getPlatformHandle()] = newWindow; return newWindow; } @@ -197,7 +200,7 @@ int ApplicationRun(IApplication::EPlatformType platform, return 1; APP = new ApplicationCocoa(cb, uniqueName, friendlyName, pname, args); } - [static_cast(APP)->m_app run]; + [[NSApplication sharedApplication] run]; return static_cast(APP)->m_clientReturn; } } diff --git a/lib/mac/CocoaCommon.hpp b/lib/mac/CocoaCommon.hpp index 8d2c8b4..a8ced47 100644 --- a/lib/mac/CocoaCommon.hpp +++ b/lib/mac/CocoaCommon.hpp @@ -3,23 +3,39 @@ #if __APPLE__ #include +#include template class NSPtr { - T m_ptr = 0; + void* m_ptr = nullptr; public: NSPtr() = default; - ~NSPtr() {[m_ptr release];} - NSPtr(T&& recv) : m_ptr(recv) {} - NSPtr& operator=(T&& recv) {[m_ptr release]; m_ptr = recv; return *this;} + ~NSPtr() + { + T ptr = (__bridge_transfer T)m_ptr; + (void)ptr; + } + NSPtr(T&& recv) {*this = std::move(recv);} + NSPtr& operator=(T&& recv) + { + T old = (__bridge_transfer T)m_ptr; + (void)old; + m_ptr = (__bridge_retained void*)recv; + return *this; + } NSPtr(const NSPtr& other) = delete; NSPtr(NSPtr&& other) = default; NSPtr& operator=(const NSPtr& other) = delete; NSPtr& operator=(NSPtr&& other) = default; operator bool() const {return m_ptr != 0;} - T get() const {return m_ptr;} - void reset() {[m_ptr release]; m_ptr = 0;} + T get() const {return (__bridge T)m_ptr;} + void reset() + { + T old = (__bridge_transfer T)m_ptr; + (void)old; + m_ptr = nullptr; + } }; #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 diff --git a/lib/mac/WindowCocoa.mm b/lib/mac/WindowCocoa.mm index 1809f47..2784ace 100644 --- a/lib/mac/WindowCocoa.mm +++ b/lib/mac/WindowCocoa.mm @@ -10,7 +10,11 @@ #include -namespace boo {class WindowCocoa;} +#if !__has_feature(objc_arc) +#error ARC Required +#endif + +namespace boo {class WindowCocoa; class GraphicsContextCocoa;} @interface WindowCocoaInternal : NSWindow { boo::WindowCocoa* booWindow; @@ -75,8 +79,20 @@ static const NSOpenGLPixelFormatAttribute* PF_TABLE[] = PF_RGBAF32_Z24_ATTRS }; +@interface BooCocoaResponder : NSResponder +{ +@public + NSUInteger lastModifiers; + boo::GraphicsContextCocoa* booContext; + NSView* parentView; + NSTextInputContext* textContext; +} +- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view; +@end + namespace boo { + class GraphicsContextCocoa : public IGraphicsContext { protected: @@ -102,6 +118,7 @@ protected: return kCVReturnSuccess; } +public: ~GraphicsContextCocoa() { if (m_dispLink) @@ -111,31 +128,21 @@ protected: } } -public: IWindowCallback* m_callback = nullptr; void waitForRetrace() { std::unique_lock lk(m_dlmt); m_dlcv.wait(lk); } + virtual BooCocoaResponder* responder() const=0; }; class GraphicsContextCocoaGL; class GraphicsContextCocoaMetal; } -@interface BooCocoaResponder : NSResponder -{ - @public - NSUInteger lastModifiers; - boo::GraphicsContextCocoa* booContext; - NSView* parentView; - NSTextInputContext* textContext; -} -- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view; -@end - @interface GraphicsContextCocoaGLInternal : NSOpenGLView { +@public BooCocoaResponder* resp; } - (id)initWithBooContext:(boo::GraphicsContextCocoaGL*)bctx; @@ -143,6 +150,7 @@ class GraphicsContextCocoaMetal; @interface GraphicsContextCocoaMetalInternal : NSView { +@public BooCocoaResponder* resp; boo::MetalContext* m_ctx; boo::IWindow* m_window; @@ -158,7 +166,7 @@ IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent); IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow, IGraphicsContext* parent); void _CocoaUpdateLastGLCtx(NSOpenGLContext* lastGLCtx); - + class GraphicsContextCocoaGL : public GraphicsContextCocoa { GraphicsContextCocoaGLInternal* m_nsContext = nullptr; @@ -182,8 +190,6 @@ public: { delete m_dataFactory; delete m_commandQueue; - [m_nsContext release]; - [m_loadCtx release]; } void _setCallback(IWindowCallback* cb) @@ -213,7 +219,7 @@ public: m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this]; if (!m_nsContext) Log.report(LogVisor::FatalError, "unable to make new NSOpenGLView"); - [(NSWindow*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext]; + [(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext]; CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink); CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this); CVDisplayLinkStart(m_dispLink); @@ -245,7 +251,6 @@ public: { NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]]; m_mainCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]]; - [nspf release]; if (!m_mainCtx) Log.report(LogVisor::FatalError, "unable to make main NSOpenGLContext"); } @@ -259,7 +264,6 @@ public: { NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[int(m_pf)]]; m_loadCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:[m_nsContext openGLContext]]; - [nspf release]; if (!m_loadCtx) Log.report(LogVisor::FatalError, "unable to make load NSOpenGLContext"); } @@ -272,6 +276,13 @@ public: [[m_nsContext openGLContext] flushBuffer]; } + BooCocoaResponder* responder() const + { + if (!m_nsContext) + return nullptr; + return m_nsContext->resp; + } + }; IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api, @@ -285,7 +296,6 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api, if (!nspf) return NULL; NSOpenGLContext* nsctx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:nil]; - [nspf release]; if (!nsctx) return NULL; [nsctx makeCurrentContext]; @@ -298,7 +308,6 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api, minor = glVersion[2] - '0'; } [NSOpenGLContext clearCurrentContext]; - [nsctx release]; if (!glVersion) return NULL; @@ -335,7 +344,6 @@ public: { delete m_dataFactory; delete m_commandQueue; - [m_nsContext release]; m_metalCtx->m_windows.erase(m_parentWindow); } @@ -368,7 +376,7 @@ public: if (!m_nsContext) Log.report(LogVisor::FatalError, "unable to make new NSView for Metal"); w.m_metalLayer = (CAMetalLayer*)m_nsContext.layer; - [(NSWindow*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext]; + [(__bridge NSWindow*)(void*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext]; CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink); CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this); CVDisplayLinkStart(m_dispLink); @@ -407,6 +415,13 @@ public: { } + BooCocoaResponder* responder() const + { + if (!m_nsContext) + return nullptr; + return m_nsContext->resp; + } + }; IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI api, @@ -433,6 +448,7 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (BOOL)hasMarkedText { + NSLog(@"hasMarkedText"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -444,6 +460,7 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (NSRange)markedRange { + NSLog(@"markedRange"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -458,6 +475,7 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (NSRange)selectedRange { + NSLog(@"selectedRange"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -472,29 +490,28 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { + NSLog(@"setMarkedText %@ [%lu,%lu] [%lu,%lu]", aString, + selectedRange.location, selectedRange.length, + replacementRange.location, replacementRange.length); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); if (textCb) { - NSString* plainStr; + NSString* plainStr = aString; if ([aString isKindOfClass:[NSAttributedString class]]) plainStr = ((NSAttributedString*)aString).string; - else - { - plainStr = aString; - [plainStr retain]; - } textCb->setMarkedText([plainStr UTF8String], std::make_pair(selectedRange.location, selectedRange.length), - std::make_pair(replacementRange.location, replacementRange.length)); - [plainStr release]; + std::make_pair(replacementRange.location==NSNotFound ? -1 : replacementRange.location, + replacementRange.length)); } } } - (void)unmarkText { + NSLog(@"unmarkText"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -505,11 +522,12 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (NSArray*)validAttributesForMarkedText { - return [NSArray array]; + return @[]; } - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + NSLog(@"attributedSubstringForProposedRange"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -523,7 +541,6 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a actualRange->length = actualRng.second; NSString* nsStr = [NSString stringWithUTF8String:str.c_str()]; NSAttributedString* ret = [[NSAttributedString alloc] initWithString:nsStr]; - [nsStr release]; return ret; } } @@ -532,28 +549,25 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { + NSLog(@"insertText %@ [%lu,%lu]", aString, replacementRange.location, replacementRange.length); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); if (textCb) { - NSString* plainStr; + NSString* plainStr = aString; if ([aString isKindOfClass:[NSAttributedString class]]) plainStr = ((NSAttributedString*)aString).string; - else - { - plainStr = aString; - [plainStr retain]; - } textCb->insertText([plainStr UTF8String], - std::make_pair(replacementRange.location, replacementRange.length)); - [plainStr release]; + std::make_pair(replacementRange.location == NSNotFound ? -1 : replacementRange.location, + replacementRange.length)); } } } - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { + NSLog(@"characterIndexForPoint"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -572,6 +586,7 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + NSLog(@"firstRectForCharacterRange"); if (booContext->m_callback) { boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback(); @@ -592,7 +607,7 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a - (void)doCommandBySelector:(SEL)aSelector { - + NSLog(@"doCommandBySelector %@", NSStringFromSelector(aSelector)); } static inline boo::EModifierKey getMod(NSUInteger flags) @@ -987,7 +1002,7 @@ static boo::ESpecialKey translateKeycode(short code) else if ([chars length]) booContext->m_callback->charKeyUp([chars characterAtIndex:0], getMod(theEvent.modifierFlags)); - [textContext handleEvent:theEvent]; + //[textContext handleEvent:theEvent]; } - (void)flagsChanged:(NSEvent*)theEvent @@ -1034,12 +1049,6 @@ static boo::ESpecialKey translateKeycode(short code) return YES; } -- (void)dealloc -{ - [textContext release]; - [super dealloc]; -} - @end @implementation GraphicsContextCocoaGLInternal @@ -1055,16 +1064,9 @@ static boo::ESpecialKey translateKeycode(short code) [self setOpenGLContext:sharedCtx]; [sharedCtx setView:self]; } - [nspf release]; return self; } -- (void)dealloc -{ - [resp release]; - [super dealloc]; -} - - (void)reshape { boo::SWindowRect rect = {{int(self.frame.origin.x), int(self.frame.origin.y)}, @@ -1103,12 +1105,6 @@ static boo::ESpecialKey translateKeycode(short code) return self; } -- (void)dealloc -{ - [resp release]; - [super dealloc]; -} - - (CALayer*)makeBackingLayer { CAMetalLayer* layer = [CAMetalLayer new]; @@ -1168,12 +1164,17 @@ static boo::ESpecialKey translateKeycode(short code) namespace boo { + +static NSString* ClipboardTypes[] = +{ + 0, NSPasteboardTypeString, NSPasteboardTypeString, NSPasteboardTypePNG +}; class WindowCocoa : public IWindow { WindowCocoaInternal* m_nsWindow; - IGraphicsContext* m_gfxCtx; + GraphicsContextCocoa* m_gfxCtx; EMouseCursor m_cursor = EMouseCursor::None; public: @@ -1185,16 +1186,18 @@ public: m_nsWindow = [[WindowCocoaInternal alloc] initWithBooWindow:this title:title]; #if BOO_HAS_METAL if (metalCtx->m_dev) - m_gfxCtx = _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI::Metal, this, metalCtx); + m_gfxCtx = static_cast(_GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI::Metal, this, metalCtx)); else #endif - m_gfxCtx = _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, lastGLCtx); + m_gfxCtx = static_cast(_GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, lastGLCtx)); m_gfxCtx->initializeContext(); }); } void _clearWindow() { + /* Caller consumes reference on its own */ + (void)(__bridge_retained void*)m_nsWindow; m_nsWindow = nullptr; } @@ -1202,7 +1205,6 @@ public: { [m_nsWindow orderOut:nil]; delete m_gfxCtx; - [m_nsWindow release]; APP->_deletedWindow(this); } @@ -1236,7 +1238,7 @@ public: { dispatch_sync(dispatch_get_main_queue(), ^{ - [m_nsWindow setTitle:[[NSString stringWithUTF8String:title.c_str()] autorelease]]; + [m_nsWindow setTitle:[NSString stringWithUTF8String:title.c_str()]]; }); } @@ -1337,17 +1339,38 @@ public: void claimKeyboardFocus(const int coord[2]) { - + BooCocoaResponder* resp = m_gfxCtx->responder(); + if (resp) + { + dispatch_async(dispatch_get_main_queue(), + ^{ + if (coord) + [resp->textContext activate]; + else + [resp->textContext deactivate]; + }); + } } bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { - + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb clearContents]; + NSData* d = [NSData dataWithBytes:data length:sz]; + [pb setData:d forType:ClipboardTypes[int(type)]]; + return true; } std::unique_ptr clipboardPaste(EClipboardType type, size_t& sz) { - + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSData* d = [pb dataForType:ClipboardTypes[int(type)]]; + if (!d) + return std::unique_ptr(); + sz = [d length]; + std::unique_ptr ret(new uint8_t[sz]); + [d getBytes:ret.get() length:sz]; + return ret; } ETouchType getTouchType() const @@ -1437,7 +1460,7 @@ IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]; - self.title = [[NSString stringWithUTF8String:title.c_str()] autorelease]; + self.title = [NSString stringWithUTF8String:title.c_str()]; booWindow = bw; return self; }