Browse Source

Merge pull request #5639 from AvaloniaUI/feature/url-handling

Feature/url handling
pull/5648/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
cadf70238a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      native/Avalonia.Native/src/OSX/AvnString.h
  2. 15
      native/Avalonia.Native/src/OSX/AvnString.mm
  3. 28
      native/Avalonia.Native/src/OSX/app.mm
  4. 2
      native/Avalonia.Native/src/OSX/clipboard.mm
  5. 2
      native/Avalonia.Native/src/OSX/common.h
  6. 4
      native/Avalonia.Native/src/OSX/main.mm
  7. 11
      src/Avalonia.Controls/Application.cs
  8. 14
      src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs
  9. 7
      src/Avalonia.Controls/Platform/IApplicationPlatformEvents.cs
  10. 14
      src/Avalonia.Controls/UrlOpenedEventArgs.cs
  11. 14
      src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs
  12. 7
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  13. 8
      src/Avalonia.Native/avn.idl

1
native/Avalonia.Native/src/OSX/AvnString.h

@ -11,6 +11,7 @@
extern IAvnString* CreateAvnString(NSString* string);
extern IAvnStringArray* CreateAvnStringArray(NSArray<NSString*>* array);
extern IAvnStringArray* CreateAvnStringArray(NSArray<NSURL*>* array);
extern IAvnStringArray* CreateAvnStringArray(NSString* string);
extern IAvnString* CreateByteArray(void* data, int len);
#endif /* AvnString_h */

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

@ -85,6 +85,16 @@ public:
}
}
AvnStringArrayImpl(NSArray<NSURL*>* array)
{
for(int c = 0; c < [array count]; c++)
{
ComPtr<IAvnString> s;
*s.getPPV() = new AvnStringImpl([array objectAtIndex:c].absoluteString);
_list.push_back(s);
}
}
AvnStringArrayImpl(NSString* string)
{
ComPtr<IAvnString> s;
@ -117,6 +127,11 @@ IAvnStringArray* CreateAvnStringArray(NSArray<NSString*> * array)
return new AvnStringArrayImpl(array);
}
IAvnStringArray* CreateAvnStringArray(NSArray<NSURL*> * array)
{
return new AvnStringArrayImpl(array);
}
IAvnStringArray* CreateAvnStringArray(NSString* string)
{
return new AvnStringArrayImpl(string);

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

@ -1,10 +1,20 @@
#include "common.h"
#include "AvnString.h"
@interface AvnAppDelegate : NSObject<NSApplicationDelegate>
-(AvnAppDelegate* _Nonnull) initWithEvents: (IAvnApplicationEvents* _Nonnull) events;
@end
NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
@implementation AvnAppDelegate
ComPtr<IAvnApplicationEvents> _events;
- (AvnAppDelegate *)initWithEvents:(IAvnApplicationEvents *)events
{
_events = events;
return self;
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
if([[NSApplication sharedApplication] activationPolicy] != AvnDesiredActivationPolicy)
@ -27,11 +37,23 @@ NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivati
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
- (void)application:(NSApplication *)sender openFiles:(NSArray<NSString *> *)filenames
{
auto array = CreateAvnStringArray(filenames);
_events->FilesOpened(array);
}
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls
{
auto array = CreateAvnStringArray(urls);
_events->FilesOpened(array);
}
@end
@interface AvnApplication : NSApplication
@end
@implementation AvnApplication
@ -63,9 +85,9 @@ NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivati
@end
extern void InitializeAvnApp()
extern void InitializeAvnApp(IAvnApplicationEvents* events)
{
NSApplication* app = [AvnApplication sharedApplication];
id delegate = [AvnAppDelegate new];
id delegate = [[AvnAppDelegate alloc] initWithEvents:events];
[app setDelegate:delegate];
}

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

@ -56,7 +56,7 @@ public:
return S_OK;
}
NSArray* arr = (NSArray*)data;
NSArray<NSString*>* arr = (NSArray*)data;
for(int c = 0; c < [arr count]; c++)
if(![[arr objectAtIndex:c] isKindOfClass:[NSString class]])

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

@ -31,7 +31,7 @@ extern NSMenuItem* GetAppMenuItem ();
extern void SetAutoGenerateDefaultAppMenuItems (bool enabled);
extern bool GetAutoGenerateDefaultAppMenuItems ();
extern void InitializeAvnApp();
extern void InitializeAvnApp(IAvnApplicationEvents* events);
extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);

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

@ -163,13 +163,13 @@ class AvaloniaNative : public ComSingleObject<IAvaloniaNativeFactory, &IID_IAval
public:
FORWARD_IUNKNOWN()
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator) override
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* events) override
{
_deallocator = deallocator;
@autoreleasepool{
[[ThreadingInitializer new] do];
}
InitializeAvnApp();
InitializeAvnApp(events);
return S_OK;
};

11
src/Avalonia.Controls/Application.cs

@ -30,7 +30,7 @@ namespace Avalonia
/// method.
/// - Tracks the lifetime of the application.
/// </remarks>
public class Application : AvaloniaObject, IDataContextProvider, IGlobalDataTemplates, IGlobalStyles, IResourceHost
public class Application : AvaloniaObject, IDataContextProvider, IGlobalDataTemplates, IGlobalStyles, IResourceHost, IApplicationPlatformEvents
{
/// <summary>
/// The application-global data templates.
@ -55,6 +55,8 @@ namespace Avalonia
/// <inheritdoc/>
public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
public event EventHandler<UrlOpenedEventArgs> UrlsOpened;
/// <summary>
/// Creates an instance of the <see cref="Application"/> class.
/// </summary>
@ -247,7 +249,11 @@ namespace Avalonia
public virtual void OnFrameworkInitializationCompleted()
{
}
void IApplicationPlatformEvents.RaiseUrlsOpened(string[] urls)
{
UrlsOpened?.Invoke(this, new UrlOpenedEventArgs (urls));
}
private void NotifyResourcesChanged(ResourcesChangedEventArgs e)
@ -288,5 +294,6 @@ namespace Avalonia
get => _name;
set => SetAndRaise(NameProperty, ref _name, value);
}
}
}

14
src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs

@ -5,6 +5,7 @@ using System.Threading;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Threading;
namespace Avalonia.Controls.ApplicationLifetimes
@ -102,6 +103,14 @@ namespace Avalonia.Controls.ApplicationLifetimes
public int Start(string[] args)
{
Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args));
var options = AvaloniaLocator.Current.GetService<ClassicDesktopStyleApplicationLifetimeOptions>();
if(options != null && options.ProcessUrlActivationCommandLine && args.Length > 0)
{
((IApplicationPlatformEvents)Application.Current).RaiseUrlsOpened(args);
}
_cts = new CancellationTokenSource();
MainWindow?.Show();
Dispatcher.UIThread.MainLoop(_cts.Token);
@ -115,6 +124,11 @@ namespace Avalonia.Controls.ApplicationLifetimes
_activeLifetime = null;
}
}
public class ClassicDesktopStyleApplicationLifetimeOptions
{
public bool ProcessUrlActivationCommandLine { get; set; }
}
}
namespace Avalonia

7
src/Avalonia.Controls/Platform/IApplicationPlatformEvents.cs

@ -0,0 +1,7 @@
namespace Avalonia.Platform
{
public interface IApplicationPlatformEvents
{
void RaiseUrlsOpened(string[] urls);
}
}

14
src/Avalonia.Controls/UrlOpenedEventArgs.cs

@ -0,0 +1,14 @@
using System;
namespace Avalonia
{
public class UrlOpenedEventArgs : EventArgs
{
public UrlOpenedEventArgs(string[] urls)
{
Urls = urls;
}
public string[] Urls { get; }
}
}

14
src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs

@ -0,0 +1,14 @@
using System;
using Avalonia.Native.Interop;
using Avalonia.Platform;
namespace Avalonia.Native
{
internal class AvaloniaNativeApplicationPlatform : CallbackBase, IAvnApplicationEvents
{
void IAvnApplicationEvents.FilesOpened(IAvnStringArray urls)
{
((IApplicationPlatformEvents)Application.Current).RaiseUrlsOpened(urls.ToStringArray());
}
}
}

7
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -1,6 +1,5 @@
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
@ -9,7 +8,6 @@ using Avalonia.Native.Interop;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Platform.Interop;
namespace Avalonia.Native
{
@ -86,7 +84,10 @@ namespace Avalonia.Native
void DoInitialize(AvaloniaNativePlatformOptions options)
{
_options = options;
_factory.Initialize(new GCHandleDeallocator());
var applicationPlatform = new AvaloniaNativeApplicationPlatform();
_factory.Initialize(new GCHandleDeallocator(), applicationPlatform);
if (_factory.MacOptions != null)
{
var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>();

8
src/Avalonia.Native/avn.idl

@ -403,7 +403,7 @@ enum AvnExtendClientAreaChromeHints
[uuid(809c652e-7396-11d2-9771-00a0c9b4d50c)]
interface IAvaloniaNativeFactory : IUnknown
{
HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator);
HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* appCb);
IAvnMacOptions* GetMacOptions();
HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv);
HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv);
@ -728,3 +728,9 @@ interface IAvnNativeControlHostTopLevelAttachment : IUnknown
void HideWithSize(float width, float height);
void ReleaseChild();
}
[uuid(6575b5af-f27a-4609-866c-f1f014c20f79)]
interface IAvnApplicationEvents : IUnknown
{
void FilesOpened (IAvnStringArray* urls);
}

Loading…
Cancel
Save