public void Dispose() { if (release && Handle != IntPtr.Zero) { ObjC.Call(Handle, "release"); } }
private static NativeClassDefinition CreateAppDelegate() { var definition = NativeClassDefinition.FromClass( "SpiderEyeAppDelegate", AppKit.GetClass("NSResponder"), // note: NSApplicationDelegate is not available at runtime and returns null AppKit.GetProtocol("NSApplicationDelegate"), AppKit.GetProtocol("NSTouchBarProvider")); definition.AddMethod <ShouldTerminateDelegate>( "applicationShouldTerminateAfterLastWindowClosed:", "c@:@", (self, op, notification) => (byte)(Application.ExitWithLastWindow ? 1 : 0)); definition.AddMethod <NotificationDelegate>( "applicationDidFinishLaunching:", "v@:@", (self, op, notification) => { var instance = definition.GetParent <CocoaApplication>(self); ObjC.Call(instance.Handle, "activateIgnoringOtherApps:", true); }); definition.FinishDeclaration(); return(definition); }
private static void FinishUriSchemeCallback(IntPtr url, IntPtr schemeTask, IntPtr data, long contentLength, Uri uri) { IntPtr response = Foundation.Call("NSURLResponse", "alloc"); ObjC.Call( response, "initWithURL:MIMEType:expectedContentLength:textEncodingName:", url, NSString.Create(MimeTypes.FindForUri(uri)), new IntPtr(contentLength), IntPtr.Zero); ObjC.Call(schemeTask, "didReceiveResponse:", response); IntPtr nsData = Foundation.Call( "NSData", "dataWithBytesNoCopy:length:freeWhenDone:", data, new IntPtr(contentLength), IntPtr.Zero); ObjC.Call(schemeTask, "didReceiveData:", nsData); ObjC.Call(schemeTask, "didFinish"); }
public void Show() { ObjC.Call(Handle, "center"); ObjC.Call(Handle, "makeKeyAndOrderFront:", IntPtr.Zero); MacApplication.SynchronizationContext.Post(s => Shown?.Invoke(this, EventArgs.Empty), null); }
public Task <string?> ExecuteScriptAsync(string script) { var taskResult = new TaskCompletionSource <string?>(); NSBlock?block = null; ScriptEvalCallbackDelegate callback = (IntPtr self, IntPtr result, IntPtr error) => { try { if (error != IntPtr.Zero) { string?message = NSString.GetString(ObjC.Call(error, "localizedDescription")); taskResult.TrySetException(new ScriptException($"Script execution failed with: \"{message}\"")); } else { string?content = NSString.GetString(result); taskResult.TrySetResult(content); } } catch (Exception ex) { taskResult.TrySetException(ex); } finally { block !.Dispose(); } }; block = new NSBlock(callback); ObjC.Call( Handle, "evaluateJavaScript:completionHandler:", NSString.Create(script), block.Handle); return(taskResult.Task); }
public override void CleanUpNativeData(IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { ObjC.MessageSend(pNativeData, Selector.ReleaseHandle); } }
private string CreateSchemeHandler(IntPtr configuration) { string host = null; if (string.IsNullOrWhiteSpace(config.ExternalHost)) { const string scheme = "spidereye"; host = UriTools.GetRandomResourceUrl(scheme); IntPtr handlerClass = ObjC.AllocateClassPair(ObjC.GetClass("NSObject"), "SchemeHandler" + count, IntPtr.Zero); ObjC.AddProtocol(handlerClass, ObjC.GetProtocol("WKURLSchemeHandler")); ObjC.AddMethod( handlerClass, ObjC.RegisterName("webView:startURLSchemeTask:"), uriSchemeStartDelegate, "v@:@@"); ObjC.AddMethod( handlerClass, ObjC.RegisterName("webView:stopURLSchemeTask:"), uriSchemeStopDelegate, "v@:@@"); ObjC.RegisterClassPair(handlerClass); IntPtr handler = ObjC.Call(handlerClass, "new"); ObjC.Call(configuration, "setURLSchemeHandler:forURLScheme:", handler, NSString.Create(scheme)); } return(host); }
private IntPtr CreateCallbackClass() { IntPtr callbackClass = ObjC.AllocateClassPair(ObjC.GetClass("NSObject"), "CallbackClass" + count, IntPtr.Zero); ObjC.AddProtocol(callbackClass, ObjC.GetProtocol("WKNavigationDelegate")); ObjC.AddProtocol(callbackClass, ObjC.GetProtocol("WKScriptMessageHandler")); ObjC.AddMethod( callbackClass, ObjC.RegisterName("webView:didFinishNavigation:"), loadDelegate, "v@:@@"); ObjC.AddMethod( callbackClass, ObjC.RegisterName("webView:didFailNavigation:withError:"), loadFailedDelegate, "v@:@@@"); ObjC.AddMethod( callbackClass, ObjC.RegisterName("observeValueForKeyPath:ofObject:change:context:"), observedValueChangedDelegate, "v@:@@@@"); ObjC.AddMethod( callbackClass, ObjC.RegisterName("userContentController:didReceiveScriptMessage:"), scriptDelegate, "v@:@@"); ObjC.RegisterClassPair(callbackClass); return(ObjC.Call(callbackClass, "new")); }
public CocoaWindow(WindowConfiguration config, WebviewBridge bridge) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (bridge == null) { throw new ArgumentNullException(nameof(bridge)); } Handle = AppKit.Call("NSWindow", "alloc"); canResizeField = config.CanResize; var style = GetWantedStyleMask(); ObjC.SendMessage( Handle, ObjC.RegisterName("initWithContentRect:styleMask:backing:defer:"), new CGRect(0, 0, config.Size.Width, config.Size.Height), new UIntPtr((uint)style), new UIntPtr(2), false); webview = new CocoaWebview(bridge); ObjC.Call(Handle, "setContentView:", webview.Handle); webview.TitleChanged += Webview_TitleChanged; windowDelegate = WindowDelegateDefinition.CreateInstance(this); ObjC.Call(Handle, "setDelegate:", windowDelegate.Handle); }
public void EnterFullscreen() { if (!StyleMask.HasFlag(NSWindowStyleMask.FullScreen)) { ObjC.Call(Handle, "toggleFullScreen:", Handle); } }
public bool PosTest7() { bool retVal = true; string ActualResult; object ObjA; object ObjB; object ObjC; TestLibrary.TestFramework.BeginScenario("PosTest7: Concat null and an object of datetime and one space"); try { ObjA = null; ObjB = new DateTime(); ObjC = " "; ActualResult = string.Concat(ObjA, ObjB, ObjC); if (ActualResult != ObjB.ToString() + ObjC.ToString()) { TestLibrary.TestFramework.LogError("013", "Concat null and an object of datetime and one space ExpectResult is equel" + ObjB.ToString() + ObjC.ToString() + ",ActualResult is (" + ActualResult + ")"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("014", "Unexpected exception" + e); retVal = false; } return(retVal); }
public bool PosTest4() { bool retVal = true; string ActualResult; object ObjA; object ObjB; object ObjC; TestLibrary.TestFramework.BeginScenario("PosTest4: Concat three special strings"); try { ObjA = new string('\t', 2); ObjB = "\n"; ObjC = "\t"; ActualResult = string.Concat(ObjA, ObjB, ObjC); if (ActualResult != ObjA.ToString() + ObjB.ToString() + ObjC.ToString()) { TestLibrary.TestFramework.LogError("007", "Concat three special strings ExpectResult is" + ObjB.ToString() + ObjA.ToString() + ObjC.ToString() + " ,ActualResult is (" + ActualResult + ")"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("008", "Unexpected exception" + e); retVal = false; } return(retVal); }
public bool PosTest5() { bool retVal = true; string ActualResult; object ObjA; object ObjB; object ObjC; TestLibrary.TestFramework.BeginScenario("PosTest5:Concat three numbers of less than 0"); try { ObjA = -123; ObjB = -123; ObjC = -123; ActualResult = string.Concat(ObjA, ObjB, ObjC); if (ActualResult != ObjA.ToString() + ObjB.ToString() + ObjC.ToString()) { TestLibrary.TestFramework.LogError("009", "Concat three numbers of less than 0 ExpectResult is equel" + ObjA.ToString() + ObjB.ToString() + " ,ActualResult is (" + ActualResult + ")"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("010", "Unexpected exception" + e); retVal = false; } return(retVal); }
public override void CleanUpNativeData(IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { ObjC.MessageSend(pNativeData, "release"); } }
public bool PosTest3() { bool retVal = true; string ActualResult; object ObjA; object ObjB; object ObjC; TestLibrary.TestFramework.BeginScenario("PosTest3:Concat two null objects and a number of less than 0"); try { ObjA = null; ObjB = null; ObjC = -12314124; ActualResult = string.Concat(ObjA, ObjB, ObjC); if (ActualResult != ObjC.ToString()) { TestLibrary.TestFramework.LogError("005", "Concat two null objects and a number of less than 0 ExpectResult is equel" + ObjC.ToString() + ",ActualResult is (" + ActualResult + ")"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("006", "Unexpected exception" + e); retVal = false; } return(retVal); }
public void FinishDeclaration() { if (registered) { throw new InvalidOperationException("Native class is already declared and registered"); } registered = true; // variable to hold reference to .NET object that creates an instance const string variableName = "_SEInstance"; ObjC.AddVariable(Handle, variableName, new IntPtr(IntPtr.Size), (byte)Math.Log(IntPtr.Size, 2), "@"); ivar = ObjC.GetVariable(Handle, variableName); foreach (IntPtr protocol in protocols) { if (protocol == IntPtr.Zero) { // must not add null protocol, can cause runtime exception with conformsToProtocol check continue; } ObjC.AddProtocol(Handle, protocol); } ObjC.RegisterClassPair(Handle); }
/// <summary> /// Creates and adds an app menu with default values. /// </summary> /// <returns>The app menu.</returns> public static IMenu CreateDefaultAppMenu() { // TODO: use app name in menu items var menu = CreateAppMenu(); var appMenu = menu.AddLabelMenuItem(string.Empty); var about = appMenu.AddLabelMenuItem("About"); about.Click += (s, e) => ObjC.Call(AppHandle, "orderFrontStandardAboutPanel:", AppHandle); appMenu.AddSeparatorMenuItem(); var hide = appMenu.AddLabelMenuItem("Hide"); hide.SetShortcut(ModifierKey.Super, Key.H); hide.Click += (s, e) => ObjC.Call(AppHandle, "hide:", AppHandle); var hideOthers = appMenu.AddLabelMenuItem("Hide Others"); hideOthers.SetShortcut(ModifierKey.Super | ModifierKey.Alt, Key.H); hideOthers.Click += (s, e) => ObjC.Call(AppHandle, "hideOtherApplications:", AppHandle); var showAll = appMenu.AddLabelMenuItem("Show All"); showAll.Click += (s, e) => ObjC.Call(AppHandle, "unhideAllApplications:", AppHandle); appMenu.AddSeparatorMenuItem(); var quit = appMenu.AddLabelMenuItem("Quit"); quit.SetShortcut(ModifierKey.Super, Key.Q); quit.Click += (s, e) => Exit(); return(Application.appMenu = menu); }
public void Unmaximize() { if (ObjC.Call(Handle, "isZoomed") != IntPtr.Zero) { ObjC.Call(Handle, "zoom:", Handle); } }
public NSRunLoop() { loop = Foundation.Call("NSRunLoop", "currentRunLoop"); mode = ObjC.Call(loop, "currentMode"); date = Foundation.Call("NSDate", "distantFuture"); method = ObjC.RegisterName("runMode:beforeDate:"); }
public CocoaWebview(WindowConfiguration config, IContentProvider contentProvider, WebviewBridge bridge) { this.config = config ?? throw new ArgumentNullException(nameof(config)); this.contentProvider = contentProvider ?? throw new ArgumentNullException(nameof(contentProvider)); this.bridge = bridge ?? throw new ArgumentNullException(nameof(bridge)); Interlocked.Increment(ref count); // need to keep the delegates around or they will get garbage collected loadDelegate = LoadCallback; loadFailedDelegate = LoadFailedCallback; observedValueChangedDelegate = ObservedValueChanged; scriptDelegate = ScriptCallback; uriSchemeStartDelegate = UriSchemeStartCallback; uriSchemeStopDelegate = UriSchemeStopCallback; IntPtr configuration = WebKit.Call("WKWebViewConfiguration", "new"); IntPtr manager = ObjC.Call(configuration, "userContentController"); IntPtr callbackClass = CreateCallbackClass(); customHost = CreateSchemeHandler(configuration); if (config.EnableScriptInterface) { ObjC.Call(manager, "addScriptMessageHandler:name:", callbackClass, NSString.Create("external")); IntPtr script = WebKit.Call("WKUserScript", "alloc"); ObjC.Call( script, "initWithSource:injectionTime:forMainFrameOnly:", NSString.Create(Resources.GetInitScript("Mac")), IntPtr.Zero, IntPtr.Zero); ObjC.Call(manager, "addUserScript:", script); } Handle = WebKit.Call("WKWebView", "alloc"); ObjC.Call(Handle, "initWithFrame:configuration:", CGRect.Zero, configuration); ObjC.Call(Handle, "setNavigationDelegate:", callbackClass); IntPtr bgColor = NSColor.FromHex(config.BackgroundColor); ObjC.Call(Handle, "setBackgroundColor:", bgColor); IntPtr boolValue = Foundation.Call("NSNumber", "numberWithBool:", 0); ObjC.Call(Handle, "setValue:forKey:", boolValue, NSString.Create("drawsBackground")); if (config.UseBrowserTitle) { ObjC.Call(Handle, "addObserver:forKeyPath:options:context:", callbackClass, NSString.Create("title"), IntPtr.Zero, IntPtr.Zero); } if (enableDevTools) { var preferences = ObjC.Call(configuration, "preferences"); ObjC.Call(preferences, "setValue:forKey:", new IntPtr(1), NSString.Create("developerExtrasEnabled")); } }
/// <summary> /// Creates and adds an empty app menu. /// </summary> /// <returns>The app menu.</returns> public static IMenu CreateAppMenu() { var menu = new CocoaMenu(); ObjC.Call(AppHandle, "setMainMenu:", menu.Handle); return(appMenu = menu); }
public void FromNSString() { string text = "WOOT"; IntPtr handle = ObjC.ToNSString(text); string actual = ObjC.FromNSString(handle); Assert.AreEqual(text, actual); }
public object MarshalNativeToManaged(IntPtr pNativeData) { if (pNativeData == IntPtr.Zero) { return(null); } return(ObjC.FromNSString(pNativeData)); }
public void SetShortcut(ModifierKey modifier, Key key) { NSEventModifierFlags nsModifier = KeyMapper.GetModifier(modifier); string mappedKey = KeyMapper.GetKey(key); ObjC.Call(Handle, "setKeyEquivalentModifierMask:", new UIntPtr((ulong)nsModifier)); ObjC.Call(Handle, "setKeyEquivalent:", NSString.Create(mappedKey)); }
public void FromNSUrl() { string url = "http://google.com"; IntPtr handle = ObjC.ToNSUrl(url); var actual = ObjC.FromNSUrl(handle); Assert.AreEqual(url, actual); }
public object MarshalNativeToManaged(IntPtr pNativeData) { if (pNativeData == IntPtr.Zero) { return(default(DateTime)); } return(ObjC.FromNSDate(pNativeData)); }
public IMenu AddMenu() { var menu = new CocoaMenu(); ObjC.Call(statusItem, "setMenu:", menu.Handle); return(menu); }
public void FromNSNumber() { double number = 1.999; IntPtr handle = ObjC.ToNSNumber(number); var actual = ObjC.FromNSNumber(handle); Assert.AreEqual(Math.Round(number, 3), Math.Round(actual, 3)); }
public static string?GetAsString(IntPtr handle) { if (handle == IntPtr.Zero) { return(null); } return(NSString.GetString(ObjC.Call(handle, "absoluteString"))); }
public CocoaWindow(WindowConfiguration config, IUiFactory windowFactory) { if (windowFactory == null) { throw new ArgumentNullException(nameof(windowFactory)); } this.config = config ?? throw new ArgumentNullException(nameof(config)); Interlocked.Increment(ref count); // need to keep the delegates around or they will get garbage collected windowShouldCloseDelegate = WindowShouldCloseCallback; windowWillCloseDelegate = WindowWillCloseCallback; Handle = AppKit.Call("NSWindow", "alloc"); var style = NSWindowStyleMask.Titled | NSWindowStyleMask.Closable | NSWindowStyleMask.Miniaturizable; if (config.CanResize) { style |= NSWindowStyleMask.Resizable; } ObjC.SendMessage( Handle, ObjC.RegisterName("initWithContentRect:styleMask:backing:defer:"), new CGRect(0, 0, config.Width, config.Height), (int)style, 2, 0); Title = config.Title; IntPtr bgColor = NSColor.FromHex(config.BackgroundColor); ObjC.Call(Handle, "setBackgroundColor:", bgColor); var contentProvider = new EmbeddedFileProvider(config.ContentAssembly, config.ContentFolder); bridge = new WebviewBridge(); webview = new CocoaWebview(config, contentProvider, bridge); ObjC.Call(Handle, "setContentView:", webview.Handle); if (config.EnableScriptInterface) { bridge.Init(this, webview, windowFactory); } if (config.UseBrowserTitle) { webview.TitleChanged += Webview_TitleChanged; bridge.TitleChanged += Webview_TitleChanged; } SetWindowDelegate(Handle); }