Browse Source

Merge branch 'master' into fixes/6202-osx-initial-focus

pull/6212/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
2b76bad329
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 196
      native/Avalonia.Native/inc/comimpl.h
  2. 32
      native/Avalonia.Native/src/OSX/AvnString.mm
  3. 4
      native/Avalonia.Native/src/OSX/Screens.mm
  4. 8
      native/Avalonia.Native/src/OSX/cgl.mm
  5. 82
      native/Avalonia.Native/src/OSX/clipboard.mm
  6. 63
      native/Avalonia.Native/src/OSX/controlhost.mm
  7. 52
      native/Avalonia.Native/src/OSX/cursor.mm
  8. 174
      native/Avalonia.Native/src/OSX/main.mm
  9. 22
      native/Avalonia.Native/src/OSX/menu.mm
  10. 2
      native/Avalonia.Native/src/OSX/platformthreading.mm
  11. 6
      native/Avalonia.Native/src/OSX/rendertarget.mm
  12. 219
      native/Avalonia.Native/src/OSX/window.mm

196
native/Avalonia.Native/inc/comimpl.h

@ -8,8 +8,109 @@
#include <cstring> #include <cstring>
/**
START_COM_CALL causes AddRef to be called at the beggining of a function.
When a function is exited, it causes ReleaseRef to be called.
This ensures that the object cannot be destroyed whilst the function is running.
For example: Window Show is called, which triggers an event, and user calls Close inside the event
causing the refcount to reach 0, and the object to be destroyed. Function then continues and this pointer
will now be invalid.
START_COM_CALL protects against this scenario.
*/
#define START_COM_CALL auto r = this->UnknownSelf()
__IID_DEF(IUnknown, 0, 0, 0, C0, 00, 00, 00, 00, 00, 00, 46); __IID_DEF(IUnknown, 0, 0, 0, C0, 00, 00, 00, 00, 00, 00, 46);
template<class TInterface>
class ComPtr
{
private:
TInterface* _obj;
public:
ComPtr()
{
_obj = 0;
}
ComPtr(TInterface* pObj)
{
_obj = 0;
if (pObj)
{
_obj = pObj;
_obj->AddRef();
}
}
ComPtr(const ComPtr& ptr)
{
_obj = 0;
if (ptr._obj)
{
_obj = ptr._obj;
_obj->AddRef();
}
}
ComPtr& operator=(ComPtr other)
{
if(_obj != NULL)
_obj->Release();
_obj = other._obj;
if(_obj != NULL)
_obj->AddRef();
return *this;
}
~ComPtr()
{
if (_obj)
{
_obj->Release();
_obj = 0;
}
}
TInterface* getRaw()
{
return _obj;
}
TInterface* getRetainedReference()
{
if(_obj == NULL)
return NULL;
_obj->AddRef();
return _obj;
}
TInterface** getPPV()
{
return &_obj;
}
operator TInterface*() const
{
return _obj;
}
TInterface& operator*() const
{
return *_obj;
}
TInterface** operator&()
{
return &_obj;
}
TInterface* operator->() const
{
return _obj;
}
};
class ComObject : public virtual IUnknown class ComObject : public virtual IUnknown
{ {
private: private:
@ -58,6 +159,12 @@ public:
_refCount++; _refCount++;
return S_OK; return S_OK;
} }
protected:
ComPtr<IUnknown> UnknownSelf()
{
return this;
}
}; };
@ -104,94 +211,5 @@ public:
virtual ~ComSingleObject(){} virtual ~ComSingleObject(){}
}; };
template<class TInterface>
class ComPtr
{
private:
TInterface* _obj;
public:
ComPtr()
{
_obj = 0;
}
ComPtr(TInterface* pObj)
{
_obj = 0;
if (pObj)
{
_obj = pObj;
_obj->AddRef();
}
}
ComPtr(const ComPtr& ptr)
{
_obj = 0;
if (ptr._obj)
{
_obj = ptr._obj;
_obj->AddRef();
}
}
ComPtr& operator=(ComPtr other)
{
if(_obj != NULL)
_obj->Release();
_obj = other._obj;
if(_obj != NULL)
_obj->AddRef();
return *this;
}
~ComPtr()
{
if (_obj)
{
_obj->Release();
_obj = 0;
}
}
TInterface* getRaw()
{
return _obj;
}
TInterface* getRetainedReference()
{
if(_obj == NULL)
return NULL;
_obj->AddRef();
return _obj;
}
TInterface** getPPV()
{
return &_obj;
}
operator TInterface*() const
{
return _obj;
}
TInterface& operator*() const
{
return *_obj;
}
TInterface** operator&()
{
return &_obj;
}
TInterface* operator->() const
{
return _obj;
}
};
#endif // COMIMPL_H_INCLUDED #endif // COMIMPL_H_INCLUDED
#pragma clang diagnostic pop #pragma clang diagnostic pop

32
native/Avalonia.Native/src/OSX/AvnString.mm

@ -43,6 +43,8 @@ public:
virtual HRESULT Pointer(void**retOut) override virtual HRESULT Pointer(void**retOut) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(retOut == nullptr) if(retOut == nullptr)
@ -58,14 +60,19 @@ public:
virtual HRESULT Length(int*retOut) override virtual HRESULT Length(int*retOut) override
{ {
if(retOut == nullptr) START_COM_CALL;
@autoreleasepool
{ {
return E_POINTER; if(retOut == nullptr)
{
return E_POINTER;
}
*retOut = _length;
return S_OK;
} }
*retOut = _length;
return S_OK;
} }
}; };
@ -109,10 +116,15 @@ public:
virtual HRESULT Get(unsigned int index, IAvnString**ppv) override virtual HRESULT Get(unsigned int index, IAvnString**ppv) override
{ {
if(_list.size() <= index) START_COM_CALL;
return E_INVALIDARG;
*ppv = _list[index].getRetainedReference(); @autoreleasepool
return S_OK; {
if(_list.size() <= index)
return E_INVALIDARG;
*ppv = _list[index].getRetainedReference();
return S_OK;
}
} }
}; };

4
native/Avalonia.Native/src/OSX/Screens.mm

@ -8,6 +8,8 @@ class Screens : public ComSingleObject<IAvnScreens, &IID_IAvnScreens>
public: public:
virtual HRESULT GetScreenCount (int* ret) override virtual HRESULT GetScreenCount (int* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
*ret = (int)[NSScreen screens].count; *ret = (int)[NSScreen screens].count;
@ -18,6 +20,8 @@ public:
virtual HRESULT GetScreen (int index, AvnScreen* ret) override virtual HRESULT GetScreen (int index, AvnScreen* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(index < 0 || index >= [NSScreen screens].count) if(index < 0 || index >= [NSScreen screens].count)

8
native/Avalonia.Native/src/OSX/cgl.mm

@ -69,6 +69,8 @@ public:
virtual HRESULT LegacyMakeCurrent() override virtual HRESULT LegacyMakeCurrent() override
{ {
START_COM_CALL;
if(CGLSetCurrentContext(Context) != 0) if(CGLSetCurrentContext(Context) != 0)
return E_FAIL; return E_FAIL;
return S_OK; return S_OK;
@ -76,6 +78,8 @@ public:
virtual HRESULT MakeCurrent(IUnknown** ppv) override virtual HRESULT MakeCurrent(IUnknown** ppv) override
{ {
START_COM_CALL;
CGLContextObj saved = CGLGetCurrentContext(); CGLContextObj saved = CGLGetCurrentContext();
CGLLockContext(Context); CGLLockContext(Context);
if(CGLSetCurrentContext(Context) != 0) if(CGLSetCurrentContext(Context) != 0)
@ -128,6 +132,8 @@ public:
virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) override virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) override
{ {
START_COM_CALL;
CGLContextObj shareContext = nil; CGLContextObj shareContext = nil;
if(share != nil) if(share != nil)
{ {
@ -144,6 +150,8 @@ public:
virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) override virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) override
{ {
START_COM_CALL;
if(native == nil) if(native == nil)
return E_INVALIDARG; return E_INVALIDARG;
*ppv = new AvnGlContext((CGLContextObj) native); *ppv = new AvnGlContext((CGLContextObj) native);

82
native/Avalonia.Native/src/OSX/clipboard.mm

@ -25,6 +25,8 @@ public:
virtual HRESULT GetText (char* type, IAvnString**ppv) override virtual HRESULT GetText (char* type, IAvnString**ppv) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ppv == nullptr) if(ppv == nullptr)
@ -42,6 +44,8 @@ public:
virtual HRESULT GetStrings(char* type, IAvnStringArray**ppv) override virtual HRESULT GetStrings(char* type, IAvnStringArray**ppv) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
*ppv= nil; *ppv= nil;
@ -69,56 +73,71 @@ public:
virtual HRESULT SetText (char* type, char* utf8String) override virtual HRESULT SetText (char* type, char* utf8String) override
{ {
Clear(); START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
Clear();
auto string = [NSString stringWithUTF8String:(const char*)utf8String]; auto string = [NSString stringWithUTF8String:(const char*)utf8String];
auto typeString = [NSString stringWithUTF8String:(const char*)type]; auto typeString = [NSString stringWithUTF8String:(const char*)type];
if(_item == nil) if(_item == nil)
[_pb setString: string forType: typeString]; [_pb setString: string forType: typeString];
else else
[_item setString: string forType:typeString]; [_item setString: string forType:typeString];
}
return S_OK; return S_OK;
}
} }
virtual HRESULT SetBytes(char* type, void* bytes, int len) override virtual HRESULT SetBytes(char* type, void* bytes, int len) override
{ {
auto typeString = [NSString stringWithUTF8String:(const char*)type]; START_COM_CALL;
auto data = [NSData dataWithBytes:bytes length:len];
if(_item == nil) @autoreleasepool
[_pb setData:data forType:typeString]; {
else auto typeString = [NSString stringWithUTF8String:(const char*)type];
[_item setData:data forType:typeString]; auto data = [NSData dataWithBytes:bytes length:len];
return S_OK; if(_item == nil)
[_pb setData:data forType:typeString];
else
[_item setData:data forType:typeString];
return S_OK;
}
} }
virtual HRESULT GetBytes(char* type, IAvnString**ppv) override virtual HRESULT GetBytes(char* type, IAvnString**ppv) override
{ {
*ppv = nil; START_COM_CALL;
auto typeString = [NSString stringWithUTF8String:(const char*)type];
NSData*data; @autoreleasepool
@try
{ {
if(_item) *ppv = nil;
data = [_item dataForType:typeString]; auto typeString = [NSString stringWithUTF8String:(const char*)type];
else NSData*data;
data = [_pb dataForType:typeString]; @try
if(data == nil) {
if(_item)
data = [_item dataForType:typeString];
else
data = [_pb dataForType:typeString];
if(data == nil)
return E_FAIL;
}
@catch(NSException* e)
{
return E_FAIL; return E_FAIL;
}
*ppv = CreateByteArray((void*)data.bytes, (int)data.length);
return S_OK;
} }
@catch(NSException* e)
{
return E_FAIL;
}
*ppv = CreateByteArray((void*)data.bytes, (int)data.length);
return S_OK;
} }
virtual HRESULT Clear() override virtual HRESULT Clear() override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(_item != nil) if(_item != nil)
@ -128,15 +147,20 @@ public:
[_pb clearContents]; [_pb clearContents];
[_pb setString:@"" forType:NSPasteboardTypeString]; [_pb setString:@"" forType:NSPasteboardTypeString];
} }
}
return S_OK; return S_OK;
}
} }
virtual HRESULT ObtainFormats(IAvnStringArray** ppv) override virtual HRESULT ObtainFormats(IAvnStringArray** ppv) override
{ {
*ppv = CreateAvnStringArray(_item == nil ? [_pb types] : [_item types]); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = CreateAvnStringArray(_item == nil ? [_pb types] : [_item types]);
return S_OK;
}
} }
}; };

63
native/Avalonia.Native/src/OSX/controlhost.mm

@ -16,11 +16,16 @@ public:
virtual HRESULT CreateDefaultChild(void* parent, void** retOut) override virtual HRESULT CreateDefaultChild(void* parent, void** retOut) override
{ {
NSView* view = [NSView new]; START_COM_CALL;
[view setWantsLayer: true];
*retOut = (__bridge_retained void*)view; @autoreleasepool
return S_OK; {
NSView* view = [NSView new];
[view setWantsLayer: true];
*retOut = (__bridge_retained void*)view;
return S_OK;
}
}; };
virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() override virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() override
@ -69,32 +74,42 @@ public:
virtual HRESULT InitializeWithChildHandle(void* child) override virtual HRESULT InitializeWithChildHandle(void* child) override
{ {
if(_child != nil) START_COM_CALL;
return E_FAIL;
_child = (__bridge NSView*)child; @autoreleasepool
if(_child == nil) {
return E_FAIL; if(_child != nil)
[_holder addSubview:_child]; return E_FAIL;
[_child setHidden: false]; _child = (__bridge NSView*)child;
return S_OK; if(_child == nil)
return E_FAIL;
[_holder addSubview:_child];
[_child setHidden: false];
return S_OK;
}
}; };
virtual HRESULT AttachTo(IAvnNativeControlHost* host) override virtual HRESULT AttachTo(IAvnNativeControlHost* host) override
{ {
if(host == nil) START_COM_CALL;
{
[_holder removeFromSuperview]; @autoreleasepool
[_holder setHidden: true];
}
else
{ {
AvnNativeControlHost* chost = dynamic_cast<AvnNativeControlHost*>(host); if(host == nil)
if(chost == nil || chost->View == nil) {
return E_FAIL; [_holder removeFromSuperview];
[_holder setHidden:true]; [_holder setHidden: true];
[chost->View addSubview:_holder]; }
else
{
AvnNativeControlHost* chost = dynamic_cast<AvnNativeControlHost*>(host);
if(chost == nil || chost->View == nil)
return E_FAIL;
[_holder setHidden:true];
[chost->View addSubview:_holder];
}
return S_OK;
} }
return S_OK;
}; };
virtual void ShowInBounds(float x, float y, float width, float height) override virtual void ShowInBounds(float x, float y, float width, float height) override

52
native/Avalonia.Native/src/OSX/cursor.mm

@ -53,36 +53,46 @@ public:
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) override virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) override
{ {
*retOut = s_cursorMap[cursorType]; START_COM_CALL;
if(*retOut != nullptr) @autoreleasepool
{ {
(*retOut)->AddRef(); *retOut = s_cursorMap[cursorType];
}
return S_OK; if(*retOut != nullptr)
{
(*retOut)->AddRef();
}
return S_OK;
}
} }
virtual HRESULT CreateCustomCursor (void* bitmapData, size_t length, AvnPixelSize hotPixel, IAvnCursor** retOut) override virtual HRESULT CreateCustomCursor (void* bitmapData, size_t length, AvnPixelSize hotPixel, IAvnCursor** retOut) override
{ {
if(bitmapData == nullptr || retOut == nullptr) START_COM_CALL;
@autoreleasepool
{ {
return E_POINTER; if(bitmapData == nullptr || retOut == nullptr)
{
return E_POINTER;
}
NSData *imageData = [NSData dataWithBytes:bitmapData length:length];
NSImage *image = [[NSImage alloc] initWithData:imageData];
NSPoint hotSpot;
hotSpot.x = hotPixel.Width;
hotSpot.y = hotPixel.Height;
*retOut = new Cursor([[NSCursor new] initWithImage: image hotSpot: hotSpot]);
(*retOut)->AddRef();
return S_OK;
} }
NSData *imageData = [NSData dataWithBytes:bitmapData length:length];
NSImage *image = [[NSImage alloc] initWithData:imageData];
NSPoint hotSpot;
hotSpot.x = hotPixel.Width;
hotSpot.y = hotPixel.Height;
*retOut = new Cursor([[NSCursor new] initWithImage: image hotSpot: hotSpot]);
(*retOut)->AddRef();
return S_OK;
} }
}; };

174
native/Avalonia.Native/src/OSX/main.mm

@ -107,27 +107,42 @@ public:
virtual HRESULT SetApplicationTitle(char* utf8String) override virtual HRESULT SetApplicationTitle(char* utf8String) override
{ {
auto appTitle = [NSString stringWithUTF8String: utf8String]; START_COM_CALL;
[[NSProcessInfo processInfo] setProcessName:appTitle]; @autoreleasepool
{
auto appTitle = [NSString stringWithUTF8String: utf8String];
SetProcessName(appTitle);
[[NSProcessInfo processInfo] setProcessName:appTitle];
return S_OK;
SetProcessName(appTitle);
return S_OK;
}
} }
virtual HRESULT SetShowInDock(int show) override virtual HRESULT SetShowInDock(int show) override
{ {
AvnDesiredActivationPolicy = show START_COM_CALL;
? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory;
return S_OK; @autoreleasepool
{
AvnDesiredActivationPolicy = show
? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory;
return S_OK;
}
} }
virtual HRESULT SetDisableDefaultApplicationMenuItems (bool enabled) override virtual HRESULT SetDisableDefaultApplicationMenuItems (bool enabled) override
{ {
SetAutoGenerateDefaultAppMenuItems(!enabled); START_COM_CALL;
return S_OK;
@autoreleasepool
{
SetAutoGenerateDefaultAppMenuItems(!enabled);
return S_OK;
}
} }
}; };
@ -165,6 +180,8 @@ public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* events) override virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* events) override
{ {
START_COM_CALL;
_deallocator = deallocator; _deallocator = deallocator;
@autoreleasepool{ @autoreleasepool{
[[ThreadingInitializer new] do]; [[ThreadingInitializer new] do];
@ -180,89 +197,154 @@ public:
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) override virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) override
{ {
if(cb == nullptr || ppv == nullptr) START_COM_CALL;
return E_POINTER;
*ppv = CreateAvnWindow(cb, gl); @autoreleasepool
return S_OK; {
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnWindow(cb, gl);
return S_OK;
}
}; };
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) override virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) override
{ {
if(cb == nullptr || ppv == nullptr) START_COM_CALL;
return E_POINTER;
*ppv = CreateAvnPopup(cb, gl); @autoreleasepool
return S_OK; {
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnPopup(cb, gl);
return S_OK;
}
} }
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) override virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) override
{ {
*ppv = CreatePlatformThreading(); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = CreatePlatformThreading();
return S_OK;
}
} }
virtual HRESULT CreateSystemDialogs(IAvnSystemDialogs** ppv) override virtual HRESULT CreateSystemDialogs(IAvnSystemDialogs** ppv) override
{ {
*ppv = ::CreateSystemDialogs(); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateSystemDialogs();
return S_OK;
}
} }
virtual HRESULT CreateScreens (IAvnScreens** ppv) override virtual HRESULT CreateScreens (IAvnScreens** ppv) override
{ {
*ppv = ::CreateScreens (); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateScreens ();
return S_OK;
}
} }
virtual HRESULT CreateClipboard(IAvnClipboard** ppv) override virtual HRESULT CreateClipboard(IAvnClipboard** ppv) override
{ {
*ppv = ::CreateClipboard (nil, nil); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateClipboard (nil, nil);
return S_OK;
}
} }
virtual HRESULT CreateDndClipboard(IAvnClipboard** ppv) override virtual HRESULT CreateDndClipboard(IAvnClipboard** ppv) override
{ {
*ppv = ::CreateClipboard (nil, [NSPasteboardItem new]); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateClipboard (nil, [NSPasteboardItem new]);
return S_OK;
}
} }
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) override virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) override
{ {
*ppv = ::CreateCursorFactory(); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateCursorFactory();
return S_OK;
}
} }
virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) override virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) override
{ {
auto rv = ::GetGlDisplay(); START_COM_CALL;
if(rv == NULL)
return E_FAIL; @autoreleasepool
rv->AddRef(); {
*ppv = rv; auto rv = ::GetGlDisplay();
return S_OK; if(rv == NULL)
return E_FAIL;
rv->AddRef();
*ppv = rv;
return S_OK;
}
} }
virtual HRESULT CreateMenu (IAvnMenuEvents* cb, IAvnMenu** ppv) override virtual HRESULT CreateMenu (IAvnMenuEvents* cb, IAvnMenu** ppv) override
{ {
*ppv = ::CreateAppMenu(cb); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateAppMenu(cb);
return S_OK;
}
} }
virtual HRESULT CreateMenuItem (IAvnMenuItem** ppv) override virtual HRESULT CreateMenuItem (IAvnMenuItem** ppv) override
{ {
*ppv = ::CreateAppMenuItem(); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateAppMenuItem();
return S_OK;
}
} }
virtual HRESULT CreateMenuItemSeparator (IAvnMenuItem** ppv) override virtual HRESULT CreateMenuItemSeparator (IAvnMenuItem** ppv) override
{ {
*ppv = ::CreateAppMenuItemSeparator(); START_COM_CALL;
return S_OK;
@autoreleasepool
{
*ppv = ::CreateAppMenuItemSeparator();
return S_OK;
}
} }
virtual HRESULT SetAppMenu (IAvnMenu* appMenu) override virtual HRESULT SetAppMenu (IAvnMenu* appMenu) override
{ {
::SetAppMenu(s_appTitle, appMenu); START_COM_CALL;
return S_OK;
@autoreleasepool
{
::SetAppMenu(s_appTitle, appMenu);
return S_OK;
}
} }
}; };

22
native/Avalonia.Native/src/OSX/menu.mm

@ -95,6 +95,8 @@ NSMenuItem* AvnAppMenuItem::GetNative()
HRESULT AvnAppMenuItem::SetSubMenu (IAvnMenu* menu) HRESULT AvnAppMenuItem::SetSubMenu (IAvnMenu* menu)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(menu != nullptr) if(menu != nullptr)
@ -114,6 +116,8 @@ HRESULT AvnAppMenuItem::SetSubMenu (IAvnMenu* menu)
HRESULT AvnAppMenuItem::SetTitle (char* utf8String) HRESULT AvnAppMenuItem::SetTitle (char* utf8String)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if (utf8String != nullptr) if (utf8String != nullptr)
@ -128,6 +132,8 @@ HRESULT AvnAppMenuItem::SetTitle (char* utf8String)
HRESULT AvnAppMenuItem::SetGesture (AvnKey key, AvnInputModifiers modifiers) HRESULT AvnAppMenuItem::SetGesture (AvnKey key, AvnInputModifiers modifiers)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(key != AvnKeyNone) if(key != AvnKeyNone)
@ -183,6 +189,8 @@ HRESULT AvnAppMenuItem::SetGesture (AvnKey key, AvnInputModifiers modifiers)
HRESULT AvnAppMenuItem::SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) HRESULT AvnAppMenuItem::SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
_predicate = predicate; _predicate = predicate;
@ -193,6 +201,8 @@ HRESULT AvnAppMenuItem::SetAction (IAvnPredicateCallback* predicate, IAvnActionC
HRESULT AvnAppMenuItem::SetIsChecked (bool isChecked) HRESULT AvnAppMenuItem::SetIsChecked (bool isChecked)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[_native setState:(isChecked && _isCheckable ? NSOnState : NSOffState)]; [_native setState:(isChecked && _isCheckable ? NSOnState : NSOffState)];
@ -202,6 +212,8 @@ HRESULT AvnAppMenuItem::SetIsChecked (bool isChecked)
HRESULT AvnAppMenuItem::SetToggleType(AvnMenuItemToggleType toggleType) HRESULT AvnAppMenuItem::SetToggleType(AvnMenuItemToggleType toggleType)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
switch(toggleType) switch(toggleType)
@ -231,6 +243,8 @@ HRESULT AvnAppMenuItem::SetToggleType(AvnMenuItemToggleType toggleType)
HRESULT AvnAppMenuItem::SetIcon(void *data, size_t length) HRESULT AvnAppMenuItem::SetIcon(void *data, size_t length)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(data != nullptr) if(data != nullptr)
@ -317,6 +331,8 @@ void AvnAppMenu::RaiseClosed()
HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item) HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if([_native hasGlobalMenuItem]) if([_native hasGlobalMenuItem])
@ -337,6 +353,8 @@ HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
HRESULT AvnAppMenu::RemoveItem (IAvnMenuItem* item) HRESULT AvnAppMenu::RemoveItem (IAvnMenuItem* item)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
auto avnMenuItem = dynamic_cast<AvnAppMenuItem*>(item); auto avnMenuItem = dynamic_cast<AvnAppMenuItem*>(item);
@ -352,6 +370,8 @@ HRESULT AvnAppMenu::RemoveItem (IAvnMenuItem* item)
HRESULT AvnAppMenu::SetTitle (char* utf8String) HRESULT AvnAppMenu::SetTitle (char* utf8String)
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if (utf8String != nullptr) if (utf8String != nullptr)
@ -365,6 +385,8 @@ HRESULT AvnAppMenu::SetTitle (char* utf8String)
HRESULT AvnAppMenu::Clear() HRESULT AvnAppMenu::Clear()
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[_native removeAllItems]; [_native removeAllItems];

2
native/Avalonia.Native/src/OSX/platformthreading.mm

@ -114,6 +114,8 @@ public:
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) override virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) override
{ {
START_COM_CALL;
auto can = dynamic_cast<LoopCancellation*>(cancel); auto can = dynamic_cast<LoopCancellation*>(cancel);
if(can->Cancelled) if(can->Cancelled)
return S_OK; return S_OK;

6
native/Avalonia.Native/src/OSX/rendertarget.mm

@ -247,6 +247,8 @@ public:
virtual HRESULT GetPixelSize(AvnPixelSize* ret) override virtual HRESULT GetPixelSize(AvnPixelSize* ret) override
{ {
START_COM_CALL;
if(!_surface) if(!_surface)
return E_FAIL; return E_FAIL;
*ret = _surface->size; *ret = _surface->size;
@ -255,6 +257,8 @@ public:
virtual HRESULT GetScaling(double* ret) override virtual HRESULT GetScaling(double* ret) override
{ {
START_COM_CALL;
if(!_surface) if(!_surface)
return E_FAIL; return E_FAIL;
*ret = _surface->scale; *ret = _surface->scale;
@ -281,6 +285,8 @@ public:
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override
{ {
START_COM_CALL;
ComPtr<IUnknown> releaseContext; ComPtr<IUnknown> releaseContext;
@synchronized (_target->lock) { @synchronized (_target->lock) {
if(_target->surface == nil) if(_target->surface == nil)

219
native/Avalonia.Native/src/OSX/window.mm

@ -54,6 +54,8 @@ public:
virtual HRESULT ObtainNSWindowHandle(void** ret) override virtual HRESULT ObtainNSWindowHandle(void** ret) override
{ {
START_COM_CALL;
if (ret == nullptr) if (ret == nullptr)
{ {
return E_POINTER; return E_POINTER;
@ -66,6 +68,8 @@ public:
virtual HRESULT ObtainNSWindowHandleRetained(void** ret) override virtual HRESULT ObtainNSWindowHandleRetained(void** ret) override
{ {
START_COM_CALL;
if (ret == nullptr) if (ret == nullptr)
{ {
return E_POINTER; return E_POINTER;
@ -78,6 +82,8 @@ public:
virtual HRESULT ObtainNSViewHandle(void** ret) override virtual HRESULT ObtainNSViewHandle(void** ret) override
{ {
START_COM_CALL;
if (ret == nullptr) if (ret == nullptr)
{ {
return E_POINTER; return E_POINTER;
@ -90,6 +96,8 @@ public:
virtual HRESULT ObtainNSViewHandleRetained(void** ret) override virtual HRESULT ObtainNSViewHandleRetained(void** ret) override
{ {
START_COM_CALL;
if (ret == nullptr) if (ret == nullptr)
{ {
return E_POINTER; return E_POINTER;
@ -107,15 +115,19 @@ public:
virtual HRESULT Show(bool activate) override virtual HRESULT Show(bool activate) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
SetPosition(lastPositionSet); SetPosition(lastPositionSet);
UpdateStyle(); UpdateStyle();
[Window setContentView: StandardContainer]; [Window setContentView: StandardContainer];
[Window setTitle:_lastTitle];
if(ShouldTakeFocusOnShow() && activate) if(ShouldTakeFocusOnShow() && activate)
{ {
[Window orderFront: Window];
[Window makeKeyAndOrderFront:Window]; [Window makeKeyAndOrderFront:Window];
[Window makeFirstResponder:View]; [Window makeFirstResponder:View];
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
@ -124,7 +136,6 @@ public:
{ {
[Window orderFront: Window]; [Window orderFront: Window];
} }
[Window setTitle:_lastTitle];
_shown = true; _shown = true;
@ -139,6 +150,8 @@ public:
virtual HRESULT Hide () override virtual HRESULT Hide () override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(Window != nullptr) if(Window != nullptr)
@ -153,6 +166,8 @@ public:
virtual HRESULT Activate () override virtual HRESULT Activate () override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(Window != nullptr) if(Window != nullptr)
@ -167,6 +182,8 @@ public:
virtual HRESULT SetTopMost (bool value) override virtual HRESULT SetTopMost (bool value) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel]; [Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel];
@ -177,11 +194,16 @@ public:
virtual HRESULT Close() override virtual HRESULT Close() override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if (Window != nullptr) if (Window != nullptr)
{ {
[Window close]; auto window = Window;
Window = nullptr;
[window close];
} }
return S_OK; return S_OK;
@ -190,6 +212,8 @@ public:
virtual HRESULT GetClientSize(AvnSize* ret) override virtual HRESULT GetClientSize(AvnSize* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -220,6 +244,8 @@ public:
virtual HRESULT GetScaling (double* ret) override virtual HRESULT GetScaling (double* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -238,6 +264,8 @@ public:
virtual HRESULT SetMinMaxSize (AvnSize minSize, AvnSize maxSize) override virtual HRESULT SetMinMaxSize (AvnSize minSize, AvnSize maxSize) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[Window setMinSize: ToNSSize(minSize)]; [Window setMinSize: ToNSSize(minSize)];
@ -249,6 +277,8 @@ public:
virtual HRESULT Resize(double x, double y) override virtual HRESULT Resize(double x, double y) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
auto maxSize = [Window maxSize]; auto maxSize = [Window maxSize];
@ -288,6 +318,8 @@ public:
virtual HRESULT Invalidate (AvnRect rect) override virtual HRESULT Invalidate (AvnRect rect) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[View setNeedsDisplayInRect:[View frame]]; [View setNeedsDisplayInRect:[View frame]];
@ -298,6 +330,8 @@ public:
virtual HRESULT SetMainMenu(IAvnMenu* menu) override virtual HRESULT SetMainMenu(IAvnMenu* menu) override
{ {
START_COM_CALL;
_mainMenu = menu; _mainMenu = menu;
auto nativeMenu = dynamic_cast<AvnAppMenu*>(menu); auto nativeMenu = dynamic_cast<AvnAppMenu*>(menu);
@ -316,6 +350,8 @@ public:
virtual HRESULT BeginMoveDrag () override virtual HRESULT BeginMoveDrag () override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
auto lastEvent = [View lastMouseDownEvent]; auto lastEvent = [View lastMouseDownEvent];
@ -333,11 +369,15 @@ public:
virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) override virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) override
{ {
START_COM_CALL;
return S_OK; return S_OK;
} }
virtual HRESULT GetPosition (AvnPoint* ret) override virtual HRESULT GetPosition (AvnPoint* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -358,6 +398,8 @@ public:
virtual HRESULT SetPosition (AvnPoint point) override virtual HRESULT SetPosition (AvnPoint point) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
lastPositionSet = point; lastPositionSet = point;
@ -369,6 +411,8 @@ public:
virtual HRESULT PointToClient (AvnPoint point, AvnPoint* ret) override virtual HRESULT PointToClient (AvnPoint point, AvnPoint* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -387,6 +431,8 @@ public:
virtual HRESULT PointToScreen (AvnPoint point, AvnPoint* ret) override virtual HRESULT PointToScreen (AvnPoint point, AvnPoint* ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -404,12 +450,16 @@ public:
virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) override virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) override
{ {
START_COM_CALL;
[View setSwRenderedFrame: fb dispose: dispose]; [View setSwRenderedFrame: fb dispose: dispose];
return S_OK; return S_OK;
} }
virtual HRESULT SetCursor(IAvnCursor* cursor) override virtual HRESULT SetCursor(IAvnCursor* cursor) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
Cursor* avnCursor = dynamic_cast<Cursor*>(cursor); Cursor* avnCursor = dynamic_cast<Cursor*>(cursor);
@ -439,6 +489,8 @@ public:
virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ppv) override virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ppv) override
{ {
START_COM_CALL;
if(View == NULL) if(View == NULL)
return E_FAIL; return E_FAIL;
*ppv = [renderTarget createSurfaceRenderTarget]; *ppv = [renderTarget createSurfaceRenderTarget];
@ -447,6 +499,8 @@ public:
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) override virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) override
{ {
START_COM_CALL;
if(View == NULL) if(View == NULL)
return E_FAIL; return E_FAIL;
*retOut = ::CreateNativeControlHost(View); *retOut = ::CreateNativeControlHost(View);
@ -455,6 +509,8 @@ public:
virtual HRESULT SetBlurEnabled (bool enable) override virtual HRESULT SetBlurEnabled (bool enable) override
{ {
START_COM_CALL;
[StandardContainer ShowBlur:enable]; [StandardContainer ShowBlur:enable];
return S_OK; return S_OK;
@ -464,6 +520,8 @@ public:
IAvnClipboard* clipboard, IAvnDndResultCallback* cb, IAvnClipboard* clipboard, IAvnDndResultCallback* cb,
void* sourceHandle) override void* sourceHandle) override
{ {
START_COM_CALL;
auto item = TryGetPasteboardItem(clipboard); auto item = TryGetPasteboardItem(clipboard);
[item setString:@"" forType:GetAvnCustomDataType()]; [item setString:@"" forType:GetAvnCustomDataType()];
if(item == nil) if(item == nil)
@ -565,6 +623,11 @@ private:
void HideOrShowTrafficLights () void HideOrShowTrafficLights ()
{ {
if (Window == nil)
{
return;
}
for (id subview in Window.contentView.superview.subviews) { for (id subview in Window.contentView.superview.subviews) {
if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) { if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) {
NSView *titlebarView = [subview subviews][0]; NSView *titlebarView = [subview subviews][0];
@ -591,8 +654,10 @@ private:
virtual HRESULT Show (bool activate) override virtual HRESULT Show (bool activate) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
WindowBaseImpl::Show(activate); WindowBaseImpl::Show(activate);
HideOrShowTrafficLights(); HideOrShowTrafficLights();
@ -603,6 +668,8 @@ private:
virtual HRESULT SetEnabled (bool enable) override virtual HRESULT SetEnabled (bool enable) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
[Window setEnabled:enable]; [Window setEnabled:enable];
@ -612,6 +679,8 @@ private:
virtual HRESULT SetParent (IAvnWindow* parent) override virtual HRESULT SetParent (IAvnWindow* parent) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(parent == nullptr) if(parent == nullptr)
@ -723,6 +792,8 @@ private:
virtual HRESULT SetCanResize(bool value) override virtual HRESULT SetCanResize(bool value) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
_canResize = value; _canResize = value;
@ -733,6 +804,8 @@ private:
virtual HRESULT SetDecorations(SystemDecorations value) override virtual HRESULT SetDecorations(SystemDecorations value) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
auto currentWindowState = _lastWindowState; auto currentWindowState = _lastWindowState;
@ -798,6 +871,8 @@ private:
virtual HRESULT SetTitle (char* utf8title) override virtual HRESULT SetTitle (char* utf8title) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
_lastTitle = [NSString stringWithUTF8String:(const char*)utf8title]; _lastTitle = [NSString stringWithUTF8String:(const char*)utf8title];
@ -809,6 +884,8 @@ private:
virtual HRESULT SetTitleBarColor(AvnColor color) override virtual HRESULT SetTitleBarColor(AvnColor color) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
float a = (float)color.Alpha / 255.0f; float a = (float)color.Alpha / 255.0f;
@ -838,6 +915,8 @@ private:
virtual HRESULT GetWindowState (AvnWindowState*ret) override virtual HRESULT GetWindowState (AvnWindowState*ret) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(ret == nullptr) if(ret == nullptr)
@ -871,86 +950,111 @@ private:
virtual HRESULT TakeFocusFromChildren () override virtual HRESULT TakeFocusFromChildren () override
{ {
if(Window == nil) START_COM_CALL;
return S_OK;
if([Window isKeyWindow])
[Window makeFirstResponder: View];
return S_OK; @autoreleasepool
{
if(Window == nil)
return S_OK;
if([Window isKeyWindow])
[Window makeFirstResponder: View];
return S_OK;
}
} }
virtual HRESULT SetExtendClientArea (bool enable) override virtual HRESULT SetExtendClientArea (bool enable) override
{ {
_isClientAreaExtended = enable; START_COM_CALL;
if(enable) @autoreleasepool
{ {
Window.titleVisibility = NSWindowTitleHidden; _isClientAreaExtended = enable;
[Window setTitlebarAppearsTransparent:true];
auto wantsTitleBar = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
if (wantsTitleBar)
{
[StandardContainer ShowTitleBar:true];
}
else
{
[StandardContainer ShowTitleBar:false];
}
if(_extendClientHints & AvnOSXThickTitleBar) if(enable)
{ {
Window.toolbar = [NSToolbar new]; Window.titleVisibility = NSWindowTitleHidden;
Window.toolbar.showsBaselineSeparator = false;
[Window setTitlebarAppearsTransparent:true];
auto wantsTitleBar = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
if (wantsTitleBar)
{
[StandardContainer ShowTitleBar:true];
}
else
{
[StandardContainer ShowTitleBar:false];
}
if(_extendClientHints & AvnOSXThickTitleBar)
{
Window.toolbar = [NSToolbar new];
Window.toolbar.showsBaselineSeparator = false;
}
else
{
Window.toolbar = nullptr;
}
} }
else else
{ {
Window.titleVisibility = NSWindowTitleVisible;
Window.toolbar = nullptr; Window.toolbar = nullptr;
[Window setTitlebarAppearsTransparent:false];
View.layer.zPosition = 0;
} }
[Window setIsExtended:enable];
HideOrShowTrafficLights();
UpdateStyle();
return S_OK;
} }
else
{
Window.titleVisibility = NSWindowTitleVisible;
Window.toolbar = nullptr;
[Window setTitlebarAppearsTransparent:false];
View.layer.zPosition = 0;
}
[Window setIsExtended:enable];
HideOrShowTrafficLights();
UpdateStyle();
return S_OK;
} }
virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) override virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) override
{ {
_extendClientHints = hints; START_COM_CALL;
SetExtendClientArea(_isClientAreaExtended); @autoreleasepool
return S_OK; {
_extendClientHints = hints;
SetExtendClientArea(_isClientAreaExtended);
return S_OK;
}
} }
virtual HRESULT GetExtendTitleBarHeight (double*ret) override virtual HRESULT GetExtendTitleBarHeight (double*ret) override
{ {
if(ret == nullptr) START_COM_CALL;
@autoreleasepool
{ {
return E_POINTER; if(ret == nullptr)
{
return E_POINTER;
}
*ret = [Window getExtendedTitleBarHeight];
return S_OK;
} }
*ret = [Window getExtendedTitleBarHeight];
return S_OK;
} }
virtual HRESULT SetExtendTitleBarHeight (double value) override virtual HRESULT SetExtendTitleBarHeight (double value) override
{ {
[StandardContainer SetTitleBarHeightHint:value]; START_COM_CALL;
return S_OK;
@autoreleasepool
{
[StandardContainer SetTitleBarHeightHint:value];
return S_OK;
}
} }
void EnterFullScreenMode () void EnterFullScreenMode ()
@ -979,8 +1083,15 @@ private:
virtual HRESULT SetWindowState (AvnWindowState state) override virtual HRESULT SetWindowState (AvnWindowState state) override
{ {
START_COM_CALL;
@autoreleasepool @autoreleasepool
{ {
if(Window == nullptr)
{
return S_OK;
}
if(_actualWindowState == state) if(_actualWindowState == state)
{ {
return S_OK; return S_OK;
@ -1927,7 +2038,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
{ {
if(![self windowShouldClose:self]) return; if(![self windowShouldClose:self]) return;
} }
[self close]; [self close];
} }

Loading…
Cancel
Save