Files
openclaw/apps/macos/Sources/OpenClaw/CanvasWindowController+Navigation.swift
Peter Steinberger ae55a4090c refactor(canvas): make the panel a widget presenter (#126030)
* refactor(canvas): retire legacy host and commands

* refactor(apple): narrow shared Canvas contracts

* refactor(macos): keep Canvas as widget presenter

* refactor(ios): remove Canvas client

* refactor(android): remove Canvas client

* refactor(linux): remove Canvas client

* fix(ci): isolate native locale artifacts

* fix(linux): regenerate companion lockfile

* fix(canvas): refresh native tool display metadata

* test(canvas): align coverage with presenter surface

* test(canvas): remove obsolete asset root seam

* test(canvas): stabilize retirement CI coverage

* refactor(swift): remove orphaned resource wrapper

* test(ios): remove retired canvas layout assertion

* fix(macos): reserve retired canvas command namespace

* refactor(macos): isolate canvas command policy

* fix(canvas): select only eligible macOS panels

* fix(canvas): keep panel selection plugin-owned
2026-08-19 08:21:07 -07:00

69 lines
2.4 KiB
Swift

import AppKit
import WebKit
extension CanvasWindowController {
// MARK: - WKNavigationDelegate
@MainActor
func webView(
_: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping @MainActor @Sendable (WKNavigationActionPolicy) -> Void)
{
guard let url = navigationAction.request.url else {
decisionHandler(.cancel)
return
}
let scheme = url.scheme?.lowercased()
// Deep links: allow local Canvas content to invoke the agent without bouncing through NSWorkspace.
if scheme == "openclaw" {
if let currentScheme = self.webView.url?.scheme,
CanvasScheme.allSchemes.contains(currentScheme)
{
Task { await DeepLinkHandler.shared.handle(url: url) }
} else {
canvasWindowLogger.debug("ignoring deep link from non-canvas page")
}
decisionHandler(.cancel)
return
}
// Keep web content inside the panel when reasonable.
// `about:blank` and friends are common internal navigations for WKWebView; never send them to NSWorkspace.
if CanvasScheme.allSchemes.contains(scheme ?? "")
|| scheme == "https"
|| scheme == "http"
|| scheme == "about"
|| scheme == "blob"
|| scheme == "data"
|| scheme == "javascript"
{
decisionHandler(.allow)
return
}
// Only open external URLs when there is a registered handler, otherwise macOS will show a confusing
// "There is no application set to open the URL ..." alert (e.g. for about:blank).
if let appURL = NSWorkspace.shared.urlForApplication(toOpen: url) {
NSWorkspace.shared.open(
[url],
withApplicationAt: appURL,
configuration: NSWorkspace.OpenConfiguration(),
completionHandler: nil)
} else {
canvasWindowLogger.debug("no application to open scheme=\(scheme ?? "-", privacy: .public)")
}
decisionHandler(.cancel)
}
func webView(_ webView: WKWebView, didCommit _: WKNavigation?) {
if let url = webView.url {
self.updateFilePollingForCommittedNavigation(to: url)
}
}
func webView(_: WKWebView, didFinish _: WKNavigation?) {
self.applyDebugStatusIfNeeded()
}
}