From 9b8a1fca9911b8d592220878fa68bf04e45faf70 Mon Sep 17 00:00:00 2001 From: Joey Korkames Date: Sun, 27 Sep 2026 13:16:28 -0700 Subject: [PATCH 01/25] fix codesign complaint about empty Resources/ of MacPin.framework --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index aec08b2..51484b2 100644 --- a/Makefile +++ b/Makefile @@ -219,6 +219,7 @@ $(outdir)/Frameworks/%.framework: $(jumbody) $(jumbody).dSYM $(outdir)/Framework @cp -RL $(jumbody) $@/Versions/A/$* @cp -RL $(jumbody).dSYM $@/Versions/A/$*.dSYM # need a Resources/Info-macos.plist & version.plist + touch $@/Versions/A/Resources/stamp.file -[ ! -n "$(codesign)" ] || codesign --verbose=4 --sign '$(appsig)' --timestamp --options runtime --force --deep --ignore-resources --strict --entitlements $(outdir)/$*.entitlements.plist $@ #build the app bundle From fce4f91d2e27b12ca48289d7671aaf4eec67ae52 Mon Sep 17 00:00:00 2001 From: Joey Korkames Date: Sun, 27 Sep 2026 13:18:45 -0700 Subject: [PATCH 02/25] build for macOS 13 --- Package.swift | 25 +++++++++++++++++++------ eXcode.mk | 10 +++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Package.swift b/Package.swift index cebaa78..057422d 100644 --- a/Package.swift +++ b/Package.swift @@ -1,11 +1,9 @@ -// swift-tools-version:5.4 +// swift-tools-version:6.0 import PackageDescription import Foundation let package = Package( name: "MacPin", - //platforms: [.macOS(.v10_15)], - // whines about a lot of unguarded calls to 10.15.4 apis - platforms: [.macOS(.v11)], + platforms: [.macOS(.v13)], products: [ .library(name: "MacPin", type: .dynamic, targets: ["MacPin"]), .executable(name: "MacPin_static", targets: ["MacPin_static"]), @@ -60,7 +58,10 @@ if let iosvar = ProcessInfo.processInfo.environment["MACPIN_IOS"], !iosvar.isEmp dependencies: [ .product(name: "ArgumentParser", package: "swift-argument-parser"), ], - path: "Tools/iconify" + path: "Tools/iconify", + swiftSettings: [ + .swiftLanguageMode(.v5) + ] ), .target(name: "MacPin", dependencies: [ @@ -71,17 +72,29 @@ if let iosvar = ProcessInfo.processInfo.environment["MACPIN_IOS"], !iosvar.isEmp "Linenoise", "UTIKit", ], - path: "Sources/MacPinOSX" + path: "Sources/MacPinOSX", + swiftSettings: [ + .swiftLanguageMode(.v5), + //.interoperabilityMode(.Cxx) + ] ), .executableTarget( name: "MacPin_static", dependencies: [ .target(name: "MacPin") + ], + swiftSettings: [ + .swiftLanguageMode(.v5), + //.interoperabilityMode(.Cxx) ] ), .executableTarget( name: "MacPin_stub", dependencies: [], + swiftSettings: [ + .swiftLanguageMode(.v5), + //.interoperabilityMode(.Cxx) + ], linkerSettings: [ .unsafeFlags(["-Xlinker", "-rpath", "-Xlinker", "@loader_path:@loader_path/../Frameworks"]) ] diff --git a/eXcode.mk b/eXcode.mk index 1a405e8..524bddf 100644 --- a/eXcode.mk +++ b/eXcode.mk @@ -19,7 +19,7 @@ archs_iphonesimulator ?= $(archs_macosx) archs_iphoneos ?= arm64 arch ?= $(shell uname -m) -target_ver_macos ?= 11.6 +target_ver_macos ?= 13.0 # can we get the running version, if not pre-set? target_macos ?= apple-macosx$(target_ver_macos) target_ver_ios ?= 13.0 @@ -72,9 +72,13 @@ verbose ?= ################### # https://github.com/apple/swift-driver ifeq (1,$(CLTOOLS)) -sdkpath := /$(shell pkgutil --volume / --only-dirs --files com.apple.pkg.CLTools_SDK_macOS110 | grep -m1 MacOSX11.3.sdk$$) +sdkpath := /$(shell pkgutil --volume / --only-dirs --regexp --files com.apple.pkg.CLTools.* | grep -m1 -E SDKs/MacOSX\\d+.*.sdk$$) +$(info [$(eXcode)] $$(sdkpath) := $(sdkpath)) swiftc := /$(shell pkgutil --volume / --only-dirs --files com.apple.pkg.CLTools_Executables | grep -m1 usr/bin$$)/swiftc -sdk $(sdk) -target $(arch)-$(target_$(platform)) $(verbose) -swiftbuildbin := /$(patsubst %-build,%,$(shell pkgutil --volume / --only-files --files com.apple.pkg.CLTools_Executables | grep -m1 bin/swift-build$$)) + +# not a thing anymore +#swiftbuildbin := /$(patsubst %-build,%,$(shell pkgutil --volume / --only-files --files com.apple.pkg.CLTools_Executables | grep -m1 bin/swift-build$$)) +swiftbuildbin := /usr/bin/swift ### XXX: appears CLTools doesn't ship SPM libraries yet, so Package.swift can't be compiled else sdkpath := $(shell xcrun --show-sdk-path --sdk $(sdk)) From b81891fe9d862c1788baaa86e8f41c435a05d0ab Mon Sep 17 00:00:00 2001 From: Joey Korkames Date: Fri, 2 Oct 2026 23:03:45 -0700 Subject: [PATCH 03/25] don't need --deep here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 51484b2..2439dc0 100644 --- a/Makefile +++ b/Makefile @@ -238,7 +238,7 @@ $(appdir)/%.app: $(macpin_sites)/% $(macpin_sites)/%/* $(appdir)/%.app/Contents/ [ ! -n "$(codesign)" ] || codesign --verbose=4 --sign '$(appsig)' --timestamp --force --ignore-resources --entitlements $(outdir)/$*.entitlements.plist $@ -codesign --display -r- --verbose=4 --deep --entitlements :- $@ -spctl -vvvv --assess --type execute $@ # App Store-ability - [ ! -n "$(codesign)" ] || codesign --verbose=4 --deep --verify --strict $@ + [ ! -n "$(codesign)" ] || codesign --verbose=4 --verify --strict $@ -[ ! -z "$(codesign)" ] || codesign --verbose=4 --remove-signature $@ @touch $@ #xattr -w com.apple.application-instance $(shell echo uuidgen) $@ From b0b000bbe92a28037f75ad82b160c774c150a63b Mon Sep 17 00:00:00 2001 From: Joey Korkames Date: Sat, 3 Oct 2026 09:45:30 -0700 Subject: [PATCH 04/25] runs again --- Sources/MacPin/WebView.swift | 66 +++++++++++-------- Sources/MacPin/WebViewCallbacks.swift | 4 +- Sources/MacPin/WebViewController.swift | 7 +- Sources/MacPin/WebViewDelegates.swift | 11 ++-- Sources/MacPinOSX/AppDelegateOSX.swift | 2 +- .../MacPinOSX/BrowserViewControllerOSX.swift | 27 ++++---- Sources/MacPinOSX/FoundationExts.swift | 2 +- Sources/MacPinOSX/OmniBoxController.swift | 19 ++++-- Sources/MacPinOSX/WebViewDelegatesOSX.swift | 34 +++++----- Sources/MacPin_stub/main.swift | 2 +- 10 files changed, 98 insertions(+), 76 deletions(-) diff --git a/Sources/MacPin/WebView.swift b/Sources/MacPin/WebView.swift index 5a0e7e5..a2d2177 100644 --- a/Sources/MacPin/WebView.swift +++ b/Sources/MacPin/WebView.swift @@ -21,6 +21,19 @@ extension WKWebView { func wkclone(_ options: MPWebViewConfigOptions...) -> MPWebView { return (self as! MPWebView).clone(options) } + + @nonobjc func gotoURL(_ url: NSURL) { gotoURL(url as URL) } + func gotoURL(_ url: URL) { + let act = ProcessInfo.processInfo.beginActivity(options: [ProcessInfo.ActivityOptions.userInitiated, ProcessInfo.ActivityOptions.idleSystemSleepDisabled], reason: "browsing begun") + if url.scheme == "file", #available(OSX 10.11, iOS 9.1, *) { + let readURL = url.deletingLastPathComponent() + warn("Bypassing CORS: \(readURL)") + loadFileURL(url as URL, allowingReadAccessTo: readURL) + } else { + load(URLRequest(url: url)) + } + ProcessInfo.processInfo.endActivity(act) + } } enum MPWebViewConfigOptions { @@ -269,7 +282,7 @@ extension MPWebViewConfigOptions: RawRepresentable, Hashable { // https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/API/JSWrapperMap.mm#L258 @objc(evalJS::) func evalJS(_ js: String, callback: JSValue?) @objc(asyncEvalJS:::) func asyncEvalJS(_ js: String, delay: Int, callback: JSValue?) - func loadURL(_ urlstr: String) -> Bool + func load_url(_ urlstr: String) -> Bool func loadIcon(_ icon: String) -> Bool func popStyle(_ idx: Int) func style(_ css: String) -> Bool @@ -291,8 +304,7 @@ extension MPWebViewConfigOptions: RawRepresentable, Hashable { // https://github.com/apple/swift-evolution/blob/master/proposals/0195-dynamic-member-lookup.md // https://github.com/apple/swift-evolution/blob/master/proposals/0216-dynamic-callable.md -@objcMembers -class MPWebView: WKWebView, WebViewScriptExports { +final class MPWebView: WKWebView, WebViewScriptExports { //@objc dynamic var isLoading: Bool //@objc dynamic var estimatedProgress: Double @@ -331,7 +343,7 @@ class MPWebView: WKWebView, WebViewScriptExports { override var urlstr: String { // accessor for JSC, which doesn't support `new URL()` get { return url?.absoluteString ?? "" } - set { loadURL(newValue) } + set { load_url(newValue) } } var userAgent: String { @@ -407,7 +419,6 @@ class MPWebView: WKWebView, WebViewScriptExports { var inspector: _WKInspector? { get { if WebKit_version >= (607, 1, 3) { - // https://github.com/WebKit/webkit/commit/1f7d382aa1e6fc67476787ce6a7b9a791b32f434 return _inspector } else { return nil @@ -427,7 +438,6 @@ class MPWebView: WKWebView, WebViewScriptExports { } } - var inspectorAttachmentView: NSView? { // when inspector is open, subviews.first is actually the inspector (WKWebInspectorWKWebView), not the WKView // tabitem.view.subviews = [ WKWebInspectorView, WKView, ... ] @@ -563,7 +573,7 @@ class MPWebView: WKWebView, WebViewScriptExports { } } } - let prefs = WKPreferences() // http://trac.webkit.org/browser/trunk/Source/WebKit2/UIProcess/API/Cocoa/WKPreferences.mm + let prefs = WKPreferences() // https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm #if os(OSX) prefs._developerExtrasEnabled = true // Enable "Inspect Element" in context menu prefs._fullScreenEnabled = true @@ -595,6 +605,14 @@ class MPWebView: WKWebView, WebViewScriptExports { if !caching, #available(macOS 10.13.4, *) { prefs._usesPageCache = false } + + // https://github.com/home-assistant/iOS/issues/4044 + // https://github.com/ahalekelly/iOS/commit/3712028 + for feat in WKPreferences._features() { + if feat.key == "ScreenTimeEnabled" { + prefs._setEnabled(false, for: feat) + } + } #endif if privacy { @@ -606,15 +624,16 @@ class MPWebView: WKWebView, WebViewScriptExports { //prefs._isStandalone = true // `window.navigator.standalone == true` mimicing MobileSafari's springboard-link shell mode //prefs.minimumFontSize = 14 //for blindies prefs.javaScriptCanOpenWindowsAutomatically = true; -#if WK2LOG +//#if WK2LOG prefs._diagnosticLoggingEnabled = true - prefs._logsPageMessagesToSystemConsoleEnabled = true // dumps to ASL + //prefs._logsPageMessagesToSystemConsoleEnabled = true // dumps to ASL //prefs._javaScriptRuntimeFlags = 0 // ?? -#endif +//#endif //prefs._loadsImagesAutomatically = true // STP v20: https://github.com/WebKit/webkit/commit/326fc529da43b4a028a3a1644edb2198d23ecb68 configuration.preferences = prefs configuration.suppressesIncrementalRendering = false + /* var dataStore = privacy ? WKWebsiteDataStore.nonPersistent() : WKWebsiteDataStore.default() if #available(macOS 10.14.4, iOS 12.2, *) { @@ -641,6 +660,7 @@ class MPWebView: WKWebView, WebViewScriptExports { } else { configuration.processPool = configuration.processPool ?? (MPWebView.self.sharedWebProcessPool)! } + */ self.init(frame: CGRect.zero, configuration: configuration) // This is the real init() // its an ObjC++ ctor which is why we couldn't override its impl to do these defaultings @@ -671,7 +691,6 @@ class MPWebView: WKWebView, WebViewScriptExports { #elseif os(iOS) _applicationNameForUserAgent = "Version/10 Mobile/12F70 Safari/\(WebKit_version.major).\(WebKit_version.minor).\(WebKit_version.tiny)" #endif - var url: URL? = nil for option in config.options { @@ -739,7 +758,6 @@ class MPWebView: WKWebView, WebViewScriptExports { } self.notifier = WebNotifier(self) - for originStr in authorizedOriginsForNotifications { self.notifier?.authorizeNotifications(fromOrigin: URL(string: originStr)) } @@ -898,27 +916,14 @@ class MPWebView: WKWebView, WebViewScriptExports { } } - @nonobjc func gotoURL(_ url: NSURL) { gotoURL(url as URL) } - func gotoURL(_ url: URL) { - let act = ProcessInfo.processInfo.beginActivity(options: [ProcessInfo.ActivityOptions.userInitiated, ProcessInfo.ActivityOptions.idleSystemSleepDisabled], reason: "browsing begun") - if url.scheme == "file", #available(OSX 10.11, iOS 9.1, *) { - let readURL = url.deletingLastPathComponent() - warn("Bypassing CORS: \(readURL)") - loadFileURL(url as URL, allowingReadAccessTo: readURL) - } else { - load(URLRequest(url: url)) - } - ProcessInfo.processInfo.endActivity(act) - } - @discardableResult - func loadURL(_ urlstr: String) -> Bool { + func load_url(_ urlstr: String) -> Bool { if let url = URL(string: urlstr) { gotoURL(url) return true } warn("ILLEGAL URL! \(url)") // getting SIGILLd by incomplete URLs: - // $.browser.tabs[0].loadURL("www.example.com") + // $.browser.tabs[0].load_url("www.example.com") return false // tell JS we were given a malformed URL } @@ -1182,6 +1187,11 @@ class MPWebView: WKWebView, WebViewScriptExports { // https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/occ/instm/NSView/beginDraggingSessionWithItems:event:source: } */ + //override func _updateScreenTimeBasedOnWindowVisibility() { + // // https://github.com/WebKit/WebKit/blob/101392f63ca9966babdf9757a1a85793f2b38073/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm#L504 + // // this is constantly being called .... *sigh** + // super._updateScreenTimeBasedOnWindowVisibility() + //} //func dumpImage() -> NSImage { return NSImage(data: view.dataWithPDFInsideRect(view.bounds)) } //var snapshotURL: String { get { NSImage(data: thumbnail.dataWithPDFInsideRect(thumbnail.bounds)) } } //data:: @@ -1327,7 +1337,7 @@ extension MPWebView { // NSTextFinderClient warn(obj: scrollBox) //_setFrame(frame, andScrollBy: scrollBox) // WebKit availability? //scrollRangeToVisible(range) - } + } // https://developer.apple.com/documentation/appkit/nstextfinderclient/1526989-scrollrangetovisible @objc override public func scrollRangeToVisible(_ range: NSRange) { diff --git a/Sources/MacPin/WebViewCallbacks.swift b/Sources/MacPin/WebViewCallbacks.swift index d13fd73..308d1f8 100644 --- a/Sources/MacPin/WebViewCallbacks.swift +++ b/Sources/MacPin/WebViewCallbacks.swift @@ -31,6 +31,7 @@ struct WebViewUICallbacks { static func makeClient() -> WKPageUIClientV2 { var uiClient = WKPageUIClientV2() + // https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/PageClient.h uiClient.base.version = 2 #if os(OSX) uiClient.decidePolicyForGeolocationPermissionRequest = decidePolicyForGeolocationPermissionRequestCallBack @@ -44,6 +45,7 @@ struct WebViewUICallbacks { // V6: // checkUserMediaPermissionForOrigin = checkUserMediaPermissionCallback + // ^ want this -- don't wanna add SSL to my home assistant to use my macbook microphone with it // decidePolicyForUserMediaPermissionRequest = decidePolicyForUserMediaPermissionRequest // V9: @@ -62,7 +64,7 @@ struct WebViewUICallbacks { } static func subscribe(_ webview: MPWebView) { - warn("UI") + warn("subscribe to UI callbacks") var uiClient = makeClient() uiClient.base.clientInfo = UnsafeRawPointer(Unmanaged.passUnretained(webview).toOpaque()) // +0 guard let page = webview._page else { return } diff --git a/Sources/MacPin/WebViewController.swift b/Sources/MacPin/WebViewController.swift index beeaf25..2925435 100644 --- a/Sources/MacPin/WebViewController.swift +++ b/Sources/MacPin/WebViewController.swift @@ -7,7 +7,6 @@ import WebKitPrivates import JavaScriptCore // https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md#re-enabling-objc-inference-within-a-class-hierarchy -@objcMembers class WebViewController: ViewController { //, WebViewControllerScriptExports { @objc unowned var webview: MPWebView @@ -37,9 +36,9 @@ class WebViewController: ViewController { //, WebViewControllerScriptExports { } //webview._historyDelegate = self -#if DEBUG - //webview._diagnosticLoggingDelegate = self -#endif +//#if DEBUG + webview._diagnosticLoggingDelegate = self +//#endif webview.configuration.processPool._downloadDelegate = self webview.configuration.processPool._setCanHandleHTTPSServerTrustEvaluation(true) diff --git a/Sources/MacPin/WebViewDelegates.swift b/Sources/MacPin/WebViewDelegates.swift index b245a82..c38595d 100644 --- a/Sources/MacPin/WebViewDelegates.swift +++ b/Sources/MacPin/WebViewDelegates.swift @@ -61,7 +61,7 @@ extension AppScriptRuntime: WKScriptMessageHandler { // FUTURE: didPerformClientRedirectForNavigation https://github.com/WebKit/webkit/commit/9475f62f3602aa91309f00c64e4430a25d5ae4e9 - func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { + @objc func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { if let url = webView.url { warn("'\(url)'") // check url against regex'd keys of MatchedAddressOptions @@ -72,7 +72,7 @@ extension AppScriptRuntime: WKScriptMessageHandler { #endif } - func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + @objc func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { //navigationAction ._originalURL ._userInitiated ._canHandleRequest 13+:._isRedirect 11+:._shouldOpenExternalSchemes 11+:._shouldOpenAppLinks if let url = navigationAction.request.url, let scheme = url.scheme { switch scheme { @@ -146,13 +146,13 @@ extension AppScriptRuntime: WKScriptMessageHandler { } } - func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { + @objc func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { guard let url = webView.url else { return } warn("~> [\(url)]") browsingReactor.anyHandled(.receivedRedirectionToURL, url.absoluteString as NSString, webView) } - func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { //error returned by webkit when loading content + @objc func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { //error returned by webkit when loading content let url = webView.url ?? URL(string: "about:nil-url")! // no URL? pish-posh! // maybe if webView.loadData was used... // & the anon-URL data had a head/metadata redirect to a URL, which failed. oic wut u did there @@ -258,7 +258,8 @@ extension AppScriptRuntime: WKScriptMessageHandler { //content starts arriving...I assume has materialized in the DOM? } - func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { + @objc func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { + warn("") let mime = navigationResponse.response.mimeType! let url = navigationResponse.response.url! let fn = navigationResponse.response.suggestedFilename! diff --git a/Sources/MacPinOSX/AppDelegateOSX.swift b/Sources/MacPinOSX/AppDelegateOSX.swift index c8db3ff..a80cbbd 100644 --- a/Sources/MacPinOSX/AppDelegateOSX.swift +++ b/Sources/MacPinOSX/AppDelegateOSX.swift @@ -421,7 +421,7 @@ public class MacPinAppDelegateOSX: NSObject, MacPinAppDelegate { case "com.apple.web-internet-location": //.webloc http://stackoverflow.com/questions/146575/crafting-webloc-file if let webloc = NSDictionary(contentsOfFile: filename), let urlstr = webloc.value(forKey: "URL") as? String { if AppScriptRuntime.shared.anyHandled(.handleDragAndDroppedURLs, [urlstr]) { - return true // app.js indicated it handled drag itself + return true // app.js indicated it handled drag itself } else if let url = validateURL(urlstr) { browserController.tabSelected = MPWebView(url: url) return true diff --git a/Sources/MacPinOSX/BrowserViewControllerOSX.swift b/Sources/MacPinOSX/BrowserViewControllerOSX.swift index 6ce69fc..2d49419 100644 --- a/Sources/MacPinOSX/BrowserViewControllerOSX.swift +++ b/Sources/MacPinOSX/BrowserViewControllerOSX.swift @@ -359,15 +359,15 @@ struct WeakThing { #if DEBUG extension TabViewController: NSViewControllerPresentationAnimator { - public func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) { - warn(fromViewController) - warn(viewController) - super.transition(from: fromViewController, to: viewController, options: transitionOptions, completionHandler: nil) - } - - public func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) { - warn() - } + public func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) { + warn(fromViewController) + warn(viewController) + super.transition(from: fromViewController, to: viewController, options: transitionOptions, completionHandler: nil) + } + + public func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) { + warn() + } } #endif @@ -585,7 +585,7 @@ class BrowserViewControllerOSX: TabViewController, BrowserViewController { } if let tvi = self.tabViewItem(for: vc) { let idx = self.tabView.indexOfTabViewItem(tvi) - warn(idx.description) + warn(idx.description) // looks corrupt: >> [tabSelected] 9223372036854775807 if idx != Int.max && idx > -1 { self.selectedTabViewItemIndex = idx prepareTab(vc) @@ -594,6 +594,11 @@ class BrowserViewControllerOSX: TabViewController, BrowserViewController { case let wv as MPWebView: // find the view's existing controller or else make one and re-assign self.tabSelected = self.children.filter({ ($0 as? WebViewControllerOSX)?.webview === wv }).first as? WebViewControllerOSX ?? WebViewControllerOSX(webview: wv) //FIXME: a backref in the wv to wvc would be helpful + case let wv as WKWebView: + let vc = NSViewController(nibName:nil, bundle:nil) + vc.view = wv + vc.representedObject = wv + self.tabSelected = vc //case let js as JSValue: guard let wv = js.toObjectOfClass(MPWebView.self) { self.tabSelected = wv } //custom bridging coercion default: warn("invalid object") @@ -687,7 +692,7 @@ class BrowserViewControllerOSX: TabViewController, BrowserViewController { } func prepareTab(_ viewController: NSViewController) { - guard let webview = viewController.representedObject as? MPWebView else { + guard let webview = viewController.representedObject as? WKWebView else { warn("making plain view first responder!!!") view.window?.makeFirstResponder(viewController.view) return diff --git a/Sources/MacPinOSX/FoundationExts.swift b/Sources/MacPinOSX/FoundationExts.swift index 2aeb2bd..49e82a4 100644 --- a/Sources/MacPinOSX/FoundationExts.swift +++ b/Sources/MacPinOSX/FoundationExts.swift @@ -63,7 +63,7 @@ extension NSPasteboard { // https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html // http://arstechnica.com/apple/2005/04/macosx-10-4/11/ http://www.cocoanetics.com/2012/09/fun-with-uti/ if !uti.rawValue.isEmpty, let value = item.string(forType: uti) { - if let cfdesc = UTTypeCopyDescription(uti as CFString), let cfmime = UTTypeCopyPreferredTagWithClass(uti as CFString, kUTTagClassMIMEType) { + if let cfdesc = UTTypeCopyDescription(uti as CFString), let cfmime = UTTypeCopyPreferredTagWithClass(uti as CFString, kUTTagClassMIMEType) { let desc = cfdesc.takeUnretainedValue() let mime = cfmime.takeUnretainedValue() warn("DnD: uti(\(uti)) `\(desc)` => types['\(mime)'] = '\(value)'") diff --git a/Sources/MacPinOSX/OmniBoxController.swift b/Sources/MacPinOSX/OmniBoxController.swift index 98af275..0eff893 100644 --- a/Sources/MacPinOSX/OmniBoxController.swift +++ b/Sources/MacPinOSX/OmniBoxController.swift @@ -30,7 +30,7 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField var bezel: NSBezierPath = NSBezierPath(roundedRect: NSInsetRect(bounds, 2, 2), xRadius: 5, yRadius: 5) // approximating the geo of 10.10's .roundedBezel NSColor.darkGray.set(); bezel.stroke() // draw bezel - bezel.addClip() // constrain further drawing within bezel + bezel.addClip() // constrain further drawing within bezel if isLoading { // draw a Safari style progress-line along edge of the text box's focus ring @@ -45,7 +45,7 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField NSColor.systemBlue.set() // matches "Highlight Color: Blue" from SysPrefs:General progressRect.fill(using: .sourceOver) } else { - NSColor.clear.setFill() // clear background + NSColor.clear.setFill() // clear background bounds.fill(using: .copy) // .clear } @@ -75,7 +75,7 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField @objc class OmniBoxController: NSViewController { let urlbox = URLAddressField() - @objc weak var webview: MPWebView? = nil { + @objc weak var webview: WKWebView? = nil { didSet { //KVC to copy updates to webviews url & title (user navigations, history.pushState(), window.title=) if let wv = webview { view.bind(NSBindingName.toolTip, to: wv, withKeyPath: #keyPath(MPWebView.title), options: nil) @@ -106,7 +106,7 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) { super.init(nibName:nil, bundle:nil) } // calls loadView() override func loadView() { view = urlbox } // NIBless - func popup(_ webview: MPWebView?) { + func popup(_ webview: WKWebView?) { guard let webview = webview else { return } MacPinApp.shared.appDelegate?.browserController.tabSelected = webview // EWW } @@ -126,7 +126,7 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField override func viewDidLoad() { super.viewDidLoad() - // prepareForReuse() {...} ? + // prepareForReuse() {...} ? urlbox.isBezeled = true urlbox.bezelStyle = .roundedBezel @@ -180,12 +180,17 @@ class URLAddressField: NSTextField { // FIXMEios UILabel + UITextField //FIXME: it should be able to return URL<->NSURL return searchForKeywords(urlstr) }){ - if let wv = webview { // FIXME: Selector(gotoURL:) to nextResponder + if let wv = webview as? MPWebView { // FIXME: Selector(gotoURL:) to nextResponder wv.notifier?.authorizeNotifications(fromOrigin: url) // user typed this address in so they "trust" it to not be spammy? view.window?.makeFirstResponder(wv) // no effect if this vc was brought up as a modal sheet warn(url.description) wv.gotoURL(url) - cancelOperation(self) + cancelOperation(self) // cancel our text-inputting session + } else if let wv = webview { // FIXME: Selector(gotoURL:) to nextResponder + view.window?.makeFirstResponder(wv) // no effect if this vc was brought up as a modal sheet + warn(url.description) + wv.gotoURL(url) + cancelOperation(self) // cancel our text-inputting session } else if let parent = parent { // tab-less browser window ... parent.addChild(WebViewControllerOSX(webview: MPWebView(url: url))) // is parentVC the toolbar or contentView VC?? } else if let presenter = presentingViewController { // urlbox is a popover/sheet ... diff --git a/Sources/MacPinOSX/WebViewDelegatesOSX.swift b/Sources/MacPinOSX/WebViewDelegatesOSX.swift index e07c974..feea498 100644 --- a/Sources/MacPinOSX/WebViewDelegatesOSX.swift +++ b/Sources/MacPinOSX/WebViewDelegatesOSX.swift @@ -8,7 +8,7 @@ import AVFoundation @objc extension WebViewControllerOSX: WKUIDelegate { - func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { + @objc func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { //focus() // tab switches, but re-draw of webview is frozen because webthread is stuck waiting for this delegated call to finish... let alert = NSAlert() @@ -20,7 +20,7 @@ import AVFoundation displayAlert(alert) { (response: NSApplication.ModalResponse) -> Void in completionHandler() } } - func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { + @objc func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { let alert = NSAlert() alert.messageText = webView.title ?? "" alert.addButton(withTitle: "OK") @@ -30,7 +30,7 @@ import AVFoundation displayAlert(alert) { (response: NSApplication.ModalResponse) -> Void in completionHandler(response == .alertFirstButtonReturn ? true : false) } } - func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) { + @objc func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) { let alert = NSAlert() alert.messageText = webView.title ?? "" alert.addButton(withTitle: "Submit") @@ -39,12 +39,12 @@ import AVFoundation let input = NSTextField(frame: NSMakeRect(0, 0, 200, 24)) input.stringValue = defaultText ?? "" input.isEditable = true - alert.accessoryView = input + alert.accessoryView = input displayAlert(alert) { (response: NSApplication.ModalResponse) -> Void in completionHandler(input.stringValue) } } @available(OSX 10.12, *) - func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) { + @objc func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) { // WKOpenPanel for file uploading // https://bugs.webkit.org/show_bug.cgi?id=137759 // https://github.com/WebKit/webkit/blob/4b7052ab44fa581810188638d1fdf074e7d754ca/Tools/MiniBrowser/mac/WK2BrowserWindowController.m#L451 @@ -106,21 +106,21 @@ extension WebViewControllerOSX { let userbox = NSTextField(frame: NSMakeRect(0, 40, 200, 24)) userbox.stringValue = "Enter user" - if let cred = challenge.proposedCredential { + if let cred = challenge.proposedCredential { if let user = cred.user { userbox.stringValue = user } } userbox.isEditable = true let passbox = NSTextField(frame: NSMakeRect(0, 0, 200, 24)) passbox.stringValue = "Enter password" - if let cred = challenge.proposedCredential { + if let cred = challenge.proposedCredential { if cred.hasPassword { passbox.stringValue = cred.password! } } passbox.isEditable = true prompts.subviews = [userbox, passbox] - alert.accessoryView = prompts + alert.accessoryView = prompts //alert.beginSheetModalForWindow(webView.window!, completionHandler:{(response: NSApplication.ModalResponse) -> Void in displayAlert(alert) { (response: NSApplication.ModalResponse) -> Void in @@ -136,7 +136,7 @@ extension WebViewControllerOSX { completionHandler(.rejectProtectionSpace, nil) webView.stopLoading() } - } + } } } @@ -144,7 +144,7 @@ extension WebViewControllerOSX { // https://github.com/WebKit/webkit/blob/master/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm // https://github.com/WebKit/webkit/blob/master/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm extension WebViewControllerOSX { // _WKDownloadDelegate - override func _download(_ download: _WKDownload!, decideDestinationWithSuggestedFilename filename: String!, allowOverwrite: UnsafeMutablePointer) -> String! { + @objc override func _download(_ download: _WKDownload!, decideDestinationWithSuggestedFilename filename: String!, allowOverwrite: UnsafeMutablePointer) -> String! { warn(download.description) //pop open a save Panel to dump data into file let saveDialog = NSSavePanel() @@ -168,7 +168,7 @@ extension WebViewControllerOSX { // _WKDownloadDelegate } extension WebViewControllerOSX { // HTML5 fullscreen - func _webViewFullscreenMayReturn(toInline webView: WKWebView) { + @objc func _webViewFullscreenMayReturn(toInline webView: WKWebView) { // https://developer.apple.com/reference/webkit/wkwebviewconfiguration/1614793-allowsinlinemediaplayback warn() } @@ -179,10 +179,10 @@ extension WebViewControllerOSX { // HTML5 fullscreen // https://github.com/WebKit/webkit/blob/master/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm // https://github.com/WebKit/webkit/search?q=fullScreenWindowController // https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/mac/WebVideoFullscreenInterfaceMac.mm - func _webViewDidEnterFullscreen(_ webView: WKWebView) { + @objc func _webViewDidEnterFullscreen(_ webView: WKWebView) { warn("JS <\(webView.urlstr)>: `