Skip to content

Commit 958cded

Browse files
committed
init
0 parents  commit 958cded

File tree

17 files changed

+62154
-0
lines changed

17 files changed

+62154
-0
lines changed

.github/workflows/doc.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Deploy document
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
paths:
7+
- "src/**"
8+
- "build.zig"
9+
- "build.zig.zon"
10+
- ".github/workflows/doc.yml"
11+
pull_request:
12+
branches: ["main"]
13+
paths:
14+
- "src/**"
15+
- "build.zig"
16+
- "build.zig.zon"
17+
- ".github/workflows/doc.yml"
18+
workflow_dispatch:
19+
20+
permissions:
21+
contents: read
22+
pages: write
23+
id-token: write
24+
25+
concurrency:
26+
group: "pages"
27+
cancel-in-progress: false
28+
29+
jobs:
30+
deploy-docs:
31+
environment:
32+
name: github-pages
33+
url: ${{ steps.deployment.outputs.page_url }}
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v4
38+
- name: Setup Pages
39+
uses: actions/configure-pages@v3
40+
- uses: mlugg/setup-zig@v2
41+
- name: Install development headers
42+
uses: awalsh128/cache-apt-pkgs-action@latest
43+
with:
44+
packages: libgtk-3-dev libwebkit2gtk-4.1-dev
45+
version: 1.0
46+
- name: Generate document
47+
run: |
48+
zig build doc
49+
- name: Upload artifact
50+
uses: actions/upload-pages-artifact@v3
51+
with:
52+
path: "zig-out/doc"
53+
- name: Deploy to GitHub Pages
54+
id: deployment
55+
uses: actions/deploy-pages@v4

.github/workflows/test.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: ["*"]
6+
paths:
7+
- "src/**"
8+
- "build.zig"
9+
- "build.zig.zon"
10+
- ".github/workflows/test.yml"
11+
pull_request:
12+
branches: ["*"]
13+
paths:
14+
- "src/**"
15+
- "build.zig"
16+
- "build.zig.zon"
17+
- ".github/workflows/test.yml"
18+
workflow_dispatch:
19+
20+
jobs:
21+
test:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
- uses: mlugg/setup-zig@v2
27+
- name: Install development headers
28+
uses: awalsh128/cache-apt-pkgs-action@latest
29+
with:
30+
packages: libgtk-3-dev libwebkit2gtk-4.1-dev
31+
version: 1.0
32+
- name: Run tests
33+
run: |
34+
zig build test
35+
- name: Build examples
36+
run: |
37+
zig build examples
38+
- name: Build examples (ReleaseSafe)
39+
run: |
40+
zig build examples -Doptimize=ReleaseSafe
41+
- name: Build examples (Cross-compile for Windows ReleaseFast)
42+
run: |
43+
zig build examples -Dtarget=x86_64-windows -Doptimize=ReleaseFast

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.zig-cache
2+
zig-out
3+
zig-pkg

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Yutao Fang
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# zig-webview
2+
3+
Zig bindings for [webview/webview](https://github.com/webview/webview) — a tiny cross-platform library for building desktop applications with web technologies using a native browser widget.
4+
5+
Zig API with error unions, comptime-powered typed callbacks, and JS ↔ Zig bindings via `bind` / `respond`.
6+
7+
## Requirements
8+
9+
Minimum Zig version: **0.15.2**.
10+
11+
For platform-specific requirements (WebKitGTK, WebView2, etc.), refer to the [webview/webview](https://github.com/webview/webview) documentation.
12+
13+
## Installation
14+
15+
Run the following command in your project directory to add the dependency:
16+
17+
```sh
18+
zig fetch --save=webview git+https://github.com/happystraw/zig-webview
19+
```
20+
21+
Then import the module in `build.zig`:
22+
23+
```zig
24+
const webview_dep = b.dependency("webview", .{
25+
.target = target,
26+
.optimize = optimize,
27+
});
28+
exe.root_module.addImport("webview", webview_dep.module("webview"));
29+
```
30+
31+
## Quick Start
32+
33+
```zig
34+
const Webview = @import("webview").Webview;
35+
36+
pub fn main() !void {
37+
const w = try Webview.create(false, null);
38+
defer w.destroy() catch unreachable;
39+
try w.setTitle("Hello");
40+
try w.setSize(800, 600, .none);
41+
try w.navigate("https://example.com");
42+
try w.run();
43+
}
44+
```
45+
46+
## Examples
47+
48+
| Example | Description |
49+
|---------|-------------|
50+
| [basic](examples/basic.zig) | Minimal window that loads an HTML string |
51+
| [bind](examples/bind.zig) | Counter and async compute demo using JS ↔ Zig bindings via `bind` / `respond` |
52+
53+
Build and run the bundled examples with:
54+
55+
```sh
56+
zig build examples
57+
./zig-out/bin/basic
58+
./zig-out/bin/bind
59+
```
60+
61+
## Cross-compilation
62+
63+
Cross-compilation to macOS and Windows is supported.
64+
65+
**Targeting macOS**
66+
67+
Obtain a macOS SDK (e.g. via [macosx-sdks](https://github.com/joseluisq/macosx-sdks)) and pass its path with `-Dmacos-sdk`:
68+
69+
```sh
70+
zig build -Dtarget=aarch64-macos -Dmacos-sdk=/path/to/MacOSX.sdk
71+
# or for x86_64
72+
zig build -Dtarget=x86_64-macos -Dmacos-sdk=/path/to/MacOSX.sdk
73+
```
74+
75+
**Targeting Windows**
76+
77+
The required WebView2 headers are already bundled in `deps/WebView2/`, so no extra setup is needed:
78+
79+
```sh
80+
zig build -Dtarget=x86_64-windows
81+
```

build.zig

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
const std = @import("std");
2+
const builtin = @import("builtin");
3+
4+
const WebkitGtkVersion = enum {
5+
@"4.0",
6+
@"4.1",
7+
@"6.0",
8+
};
9+
10+
const BuildOptions = struct {
11+
target: std.Build.ResolvedTarget,
12+
optimize: std.builtin.OptimizeMode,
13+
macos_sdk: ?[]const u8 = null,
14+
webkitgtk: WebkitGtkVersion = .@"4.1",
15+
};
16+
17+
pub fn build(b: *std.Build) void {
18+
const options: BuildOptions = .{
19+
.target = b.standardTargetOptions(.{}),
20+
.optimize = b.standardOptimizeOption(.{}),
21+
.macos_sdk = b.option([]const u8, "macos-sdk", "Path to macOS SDK (optional), used on non-macOS platforms"),
22+
.webkitgtk = b.option(WebkitGtkVersion, "webkitgtk", "Version of WebKitGTK to link against (default: 4.1), Linux only") orelse .@"4.1",
23+
};
24+
25+
const lib = addLibrary(b, options);
26+
const mod = addModule(b, options, lib);
27+
28+
addTestStep(b, mod);
29+
addExamplesStep(b, options, mod);
30+
addDocStep(b, mod);
31+
}
32+
33+
fn addLibrary(b: *std.Build, options: BuildOptions) *std.Build.Step.Compile {
34+
const upstream = b.dependency("webview", .{});
35+
const mod = b.createModule(.{
36+
.target = options.target,
37+
.optimize = options.optimize,
38+
.link_libcpp = true,
39+
});
40+
mod.addIncludePath(upstream.path("core/include"));
41+
mod.addCMacro("WEBVIEW_STATIC", "1");
42+
switch (options.target.result.os.tag) {
43+
.windows => {
44+
mod.addCSourceFile(.{ .file = upstream.path("core/src/webview.cc"), .flags = &.{"-std=c++14"} });
45+
mod.addIncludePath(b.path("deps/WebView2/"));
46+
mod.linkSystemLibrary("advapi32", .{});
47+
mod.linkSystemLibrary("ole32", .{});
48+
mod.linkSystemLibrary("shell32", .{});
49+
mod.linkSystemLibrary("shlwapi", .{});
50+
mod.linkSystemLibrary("user32", .{});
51+
mod.linkSystemLibrary("version", .{});
52+
},
53+
.macos => {
54+
tryApplyMacOsSdk(b, mod, options);
55+
mod.addCSourceFile(.{ .file = upstream.path("core/src/webview.cc"), .flags = &.{"-std=c++11"} });
56+
mod.linkFramework("WebKit", .{});
57+
},
58+
.linux => {
59+
mod.addCSourceFile(.{ .file = upstream.path("core/src/webview.cc"), .flags = &.{"-std=c++11"} });
60+
switch (options.webkitgtk) {
61+
.@"4.0" => {
62+
mod.linkSystemLibrary("gtk+-3.0", .{});
63+
mod.linkSystemLibrary("webkit2gtk-4.0", .{});
64+
},
65+
.@"4.1" => {
66+
mod.linkSystemLibrary("gtk+-3.0", .{});
67+
mod.linkSystemLibrary("webkit2gtk-4.1", .{});
68+
},
69+
.@"6.0" => {
70+
mod.linkSystemLibrary("gtk-4", .{});
71+
mod.linkSystemLibrary("webkitgtk-6.0", .{});
72+
},
73+
}
74+
},
75+
else => unreachable,
76+
}
77+
const lib = b.addLibrary(.{
78+
.name = "webview",
79+
.root_module = mod,
80+
.linkage = .static,
81+
});
82+
b.installArtifact(lib);
83+
return lib;
84+
}
85+
86+
fn addModule(b: *std.Build, options: BuildOptions, lib: *std.Build.Step.Compile) *std.Build.Module {
87+
const webview_c = createCModule(b, options);
88+
const mod = b.addModule("webview", .{
89+
.root_source_file = b.path("src/root.zig"),
90+
.target = options.target,
91+
.optimize = options.optimize,
92+
.imports = &.{
93+
.{ .name = "webview_c", .module = webview_c },
94+
},
95+
});
96+
mod.linkLibrary(lib);
97+
return mod;
98+
}
99+
100+
fn addTestStep(b: *std.Build, mod: *std.Build.Module) void {
101+
const test_step = b.step("test", "Run tests");
102+
const mod_test = b.addTest(.{ .root_module = mod });
103+
const run_mod_test = b.addRunArtifact(mod_test);
104+
test_step.dependOn(&run_mod_test.step);
105+
}
106+
107+
fn addExamplesStep(b: *std.Build, options: BuildOptions, mod: *std.Build.Module) void {
108+
const examples_step = b.step("examples", "Build all examples");
109+
const examples = [_][]const u8{
110+
"basic",
111+
"bind",
112+
};
113+
inline for (examples) |name| {
114+
const example_mod = b.createModule(.{
115+
.root_source_file = b.path(b.fmt("examples/{s}.zig", .{name})),
116+
.target = options.target,
117+
.optimize = options.optimize,
118+
.imports = &.{
119+
.{ .name = "webview", .module = mod },
120+
},
121+
});
122+
if (options.target.result.os.tag == .macos) {
123+
tryApplyMacOsSdk(b, example_mod, options);
124+
}
125+
const exe = b.addExecutable(.{
126+
.name = name,
127+
.root_module = example_mod,
128+
});
129+
const install = b.addInstallArtifact(exe, .{});
130+
examples_step.dependOn(&install.step);
131+
}
132+
}
133+
134+
fn addDocStep(b: *std.Build, mod: *std.Build.Module) void {
135+
const doc_step = b.step("doc", "Generate documentation");
136+
const doc_obj = b.addObject(.{
137+
.name = "webview",
138+
.root_module = mod,
139+
});
140+
const install_doc = b.addInstallDirectory(.{
141+
.source_dir = doc_obj.getEmittedDocs(),
142+
.install_dir = .prefix,
143+
.install_subdir = "doc",
144+
});
145+
doc_step.dependOn(&install_doc.step);
146+
}
147+
148+
fn createCModule(b: *std.Build, options: BuildOptions) *std.Build.Module {
149+
const upstream = b.dependency("webview", .{});
150+
const c_mod = b.addTranslateC(.{
151+
.root_source_file = upstream.path("core/include/webview.h"),
152+
.target = options.target,
153+
.optimize = options.optimize,
154+
}).createModule();
155+
c_mod.addIncludePath(upstream.path("core/include"));
156+
c_mod.addCMacro("WEBVIEW_STATIC", "1");
157+
return c_mod;
158+
}
159+
160+
fn tryApplyMacOsSdk(b: *std.Build, mod: *std.Build.Module, options: BuildOptions) void {
161+
if (builtin.os.tag != .macos and options.macos_sdk != null) {
162+
const macos_sdk_path: std.Build.LazyPath = .{ .cwd_relative = options.macos_sdk.? };
163+
mod.addSystemIncludePath(macos_sdk_path.path(b, "usr/include"));
164+
mod.addLibraryPath(macos_sdk_path.path(b, "usr/lib"));
165+
mod.addSystemFrameworkPath(macos_sdk_path.path(b, "System/Library/Frameworks"));
166+
}
167+
}

build.zig.zon

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.{
2+
.name = .webview,
3+
.version = "0.0.0",
4+
.minimum_zig_version = "0.15.2",
5+
.fingerprint = 0xd0d1ff8d1cf1039a,
6+
.dependencies = .{
7+
.webview = .{
8+
.url = "git+https://github.com/webview/webview#a4caad73f0ce3e311de8c90be3f0bbfdb1530d83",
9+
.hash = "N-V-__8AAEnrCgA7eoIKxmS-Cso7uOUPYcdY1T8_eVQQ7KYG",
10+
},
11+
},
12+
.paths = .{
13+
"build.zig",
14+
"build.zig.zon",
15+
"deps",
16+
// "examples",
17+
"src",
18+
"LICENSE",
19+
"README.md",
20+
},
21+
}

0 commit comments

Comments
 (0)