Skip to content

Commit d75dc4e

Browse files
committed
Implement openURL environment action
1 parent 52eac0a commit d75dc4e

File tree

7 files changed

+58
-0
lines changed

7 files changed

+58
-0
lines changed

Sources/AppKitBackend/AppKitBackend.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ public final class AppKitBackend: AppBackend {
117117
window.makeKeyAndOrderFront(nil)
118118
}
119119

120+
public func openExternalURL(_ url: URL) throws {
121+
NSWorkspace.shared.open(url)
122+
}
123+
120124
private static func renderMenuItems(_ items: [ResolvedMenu.Item]) -> [NSMenuItem] {
121125
items.map { item in
122126
switch item {

Sources/Gtk3Backend/Gtk3Backend.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ public final class Gtk3Backend: AppBackend {
215215
window.present()
216216
}
217217

218+
public func openExternalURL(_ url: URL) throws {
219+
// Used instead of gtk_uri_launcher_launch to maintain <4.10 compatibility
220+
gtk_show_uri(nil, url.absoluteString, GDK_CURRENT_TIME)
221+
}
222+
218223
class ThreadActionContext {
219224
var action: () -> Void
220225

Sources/GtkBackend/GtkBackend.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public final class GtkBackend: AppBackend {
157157
window.present()
158158
}
159159

160+
public func openExternalURL(_ url: URL) throws {
161+
// Used instead of gtk_uri_launcher_launch to maintain <4.10 compatibility
162+
gtk_show_uri(nil, url.absoluteString, GDK_CURRENT_TIME)
163+
}
164+
160165
private func renderMenu(
161166
_ menu: ResolvedMenu,
162167
actionMap: any GActionMap,

Sources/SwiftCrossUI/Backend/AppBackend.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ public protocol AppBackend {
168168
/// associated with a custom URL scheme).
169169
func setIncomingURLHandler(to action: @escaping (URL) -> Void)
170170

171+
/// Opens an external URL in the system browser or app registered for the
172+
/// URL's protocol.
173+
func openExternalURL(_ url: URL) throws
174+
171175
/// Shows a widget after it has been created or updated (may be unnecessary
172176
/// for some backends). Predominantly used by ``ViewGraphNode`` after
173177
/// propagating updates.
@@ -501,6 +505,12 @@ extension AppBackend {
501505
Foundation.exit(1)
502506
}
503507

508+
// MARK: System
509+
510+
public func openExternalURL(_ url: URL) throws {
511+
todo()
512+
}
513+
504514
// MARK: Application
505515

506516
public func setApplicationMenu(_ submenus: [ResolvedMenu.Submenu]) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Foundation
2+
3+
/// Opens a URL with the default application. May present an application picker
4+
/// if multiple applications are registered for the given URL protocol.
5+
public struct OpenURLAction {
6+
let action: (URL) -> Void
7+
8+
init<Backend: AppBackend>(backend: Backend) {
9+
action = { url in
10+
do {
11+
try backend.openExternalURL(url)
12+
} catch {
13+
print("warning: Failed to open external url: \(error)")
14+
}
15+
}
16+
}
17+
18+
public func callAsFunction(_ url: URL) {
19+
action(url)
20+
}
21+
}

Sources/SwiftCrossUI/Environment/EnvironmentValues.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ public struct EnvironmentValues {
9595
)
9696
}
9797

98+
/// Opens a URL with the default application. May present an application
99+
/// picker if multiple applications are registered for the given URL
100+
/// protocol.
101+
public var openURL: OpenURLAction {
102+
return OpenURLAction(
103+
backend: backend
104+
)
105+
}
106+
98107
/// Creates the default environment.
99108
init<Backend: AppBackend>(backend: Backend) {
100109
self.backend = backend

Sources/WinUIBackend/WinUIBackend.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ public final class WinUIBackend: AppBackend {
195195
try! window.activate()
196196
}
197197

198+
public func openExternalURL(_ url: URL) throws {
199+
UWP.Launcher.launchUriAsync(WindowsFoundation.Uri(url.absoluteString))
200+
}
201+
198202
public func runInMainThread(action: @escaping () -> Void) {
199203
_ = try! internalState.dispatcherQueue!.tryEnqueue(.normal) {
200204
action()

0 commit comments

Comments
 (0)