Browse Source

Use [NSApp run] instead of a custom run loop

pull/2929/head
Nikita Tsukanov 7 years ago
parent
commit
8cb5eedcda
  1. 2
      native/Avalonia.Native/inc/avalonia-native.h
  2. 24
      native/Avalonia.Native/src/OSX/app.mm
  3. 2
      native/Avalonia.Native/src/OSX/common.h
  4. 3
      native/Avalonia.Native/src/OSX/main.mm
  5. 59
      native/Avalonia.Native/src/OSX/platformthreading.mm

2
native/Avalonia.Native/inc/avalonia-native.h

@ -280,7 +280,7 @@ AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
virtual bool GetCurrentThreadIsLoopThread() = 0;
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
virtual void RunLoop(IAvnLoopCancellation* cancel) = 0;
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
// Can't pass int* to sharpgentools for some reason
virtual void Signal(int priority) = 0;
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;

24
native/Avalonia.Native/src/OSX/app.mm

@ -0,0 +1,24 @@
#include "common.h"
@interface AvnAppDelegate : NSObject<NSApplicationDelegate>
@end
@implementation AvnAppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp activateIgnoringOtherApps:true];
}
@end
extern void InitializeAvnApp()
{
NSApplication* app = [NSApplication sharedApplication];
id delegate = [AvnAppDelegate new];
[app setDelegate:delegate];
}

2
native/Avalonia.Native/src/OSX/common.h

@ -19,7 +19,7 @@ extern IAvnClipboard* CreateClipboard();
extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlFeature* GetGlFeature();
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view);
extern void InitializeAvnApp();
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);

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

@ -64,8 +64,9 @@ public:
{
@autoreleasepool{
[[ThreadingInitializer new] do];
return S_OK;
}
InitializeAvnApp();
return S_OK;
};
virtual IAvnMacOptions* GetMacOptions() override

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

@ -57,16 +57,36 @@ class PlatformThreadingInterface : public ComSingleObject<IAvnPlatformThreadingI
{
private:
Signaler* _signaler;
bool _wasRunningAtLeastOnce = false;
class LoopCancellation : public ComSingleObject<IAvnLoopCancellation, &IID_IAvnLoopCancellation>
{
public:
FORWARD_IUNKNOWN()
bool Cancelled = 0;
virtual void Cancel() override
bool Running = false;
bool Cancelled = false;
virtual void Cancel()
{
Cancelled = 1;
Cancelled = true;
if(Running)
{
Running = false;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSApplication sharedApplication] stop:nil];
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:0
windowNumber:0
context:nil
subtype:0
data1:0
data2:0];
[NSApp postEvent:event atStart:YES];
});
}
}
};
public:
@ -99,30 +119,17 @@ public:
return new LoopCancellation();
}
virtual void RunLoop(IAvnLoopCancellation* cancel) override
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) override
{
@autoreleasepool {
auto can = dynamic_cast<LoopCancellation*>(cancel);
[[NSApplication sharedApplication] activateIgnoringOtherApps:true];
while(true)
{
@autoreleasepool
{
if(can != NULL && can->Cancelled)
return;
NSEvent* ev = [[NSApplication sharedApplication]
nextEventMatchingMask:NSEventMaskAny
untilDate: [NSDate dateWithTimeIntervalSinceNow:1]
inMode:NSDefaultRunLoopMode
dequeue:true];
if(can != NULL && can->Cancelled)
return;
if(ev != NULL)
[[NSApplication sharedApplication] sendEvent:ev];
}
}
NSDebugLog(@"RunLoop exited");
}
auto can = dynamic_cast<LoopCancellation*>(cancel);
if(can->Cancelled)
return S_OK;
if(_wasRunningAtLeastOnce)
return E_FAIL;
can->Running = true;
_wasRunningAtLeastOnce = true;
[NSApp run];
return S_OK;
}
virtual void Signal(int priority) override

Loading…
Cancel
Save