├── .gitattributes ├── .gitignore ├── .gitmodules ├── .zpm ├── locals.zpm ├── pkgs.zig └── zpm.conf ├── README.md ├── Sdk.zig ├── build.zig ├── design ├── icon.svg ├── social-preview.png └── social-preview.xcf ├── example ├── app.htm ├── design.css ├── login.htm ├── main.zig └── minimal.zig ├── screenshots ├── i3-chat.png ├── i3-login.png ├── windows-chat.png └── windows-login.png ├── src ├── minimal.cpp ├── positron.zig └── wv │ ├── LICENCE │ ├── README.md │ ├── webview-cocoa.h │ ├── webview-gtk.h │ ├── webview-windows-chromium.h │ ├── webview-windows-edgehtml.h │ ├── webview-windows.h │ ├── webview.cpp │ └── webview.h └── vendor ├── Microsoft.Web.WebView2.1.0.902.49 ├── .signature.p7s ├── LICENSE.txt ├── Microsoft.Web.WebView2.1.0.902.49.nupkg ├── WebView2.idl ├── WebView2.tlb ├── build │ ├── Common.targets │ ├── Microsoft.Web.WebView2.targets │ └── native │ │ ├── Microsoft.Web.WebView2.targets │ │ ├── arm64 │ │ ├── WebView2Loader.dll │ │ ├── WebView2Loader.dll.lib │ │ └── WebView2LoaderStatic.lib │ │ ├── include │ │ ├── WebView2.h │ │ └── WebView2EnvironmentOptions.h │ │ ├── x64 │ │ ├── WebView2Loader.dll │ │ ├── WebView2Loader.dll.lib │ │ └── WebView2LoaderStatic.lib │ │ └── x86 │ │ ├── WebView2Loader.dll │ │ ├── WebView2Loader.dll.lib │ │ └── WebView2LoaderStatic.lib ├── lib │ ├── net45 │ │ ├── Microsoft.Web.WebView2.Core.dll │ │ ├── Microsoft.Web.WebView2.Core.xml │ │ ├── Microsoft.Web.WebView2.WinForms.dll │ │ ├── Microsoft.Web.WebView2.WinForms.xml │ │ ├── Microsoft.Web.WebView2.Wpf.dll │ │ └── Microsoft.Web.WebView2.Wpf.xml │ └── netcoreapp3.0 │ │ ├── Microsoft.Web.WebView2.Core.dll │ │ ├── Microsoft.Web.WebView2.Core.xml │ │ ├── Microsoft.Web.WebView2.WinForms.dll │ │ ├── Microsoft.Web.WebView2.WinForms.xml │ │ ├── Microsoft.Web.WebView2.Wpf.dll │ │ └── Microsoft.Web.WebView2.Wpf.xml ├── runtimes │ ├── win-arm64 │ │ └── native │ │ │ └── WebView2Loader.dll │ ├── win-x64 │ │ └── native │ │ │ └── WebView2Loader.dll │ └── win-x86 │ │ └── native │ │ └── WebView2Loader.dll └── tools │ └── VisualStudioToolsManifest.xml └── winsdk ├── EventToken.h ├── windows.devices.haptics.h ├── windows.devices.input.h ├── windows.ui.core.h ├── windows.ui.h └── windows.ui.input.h /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zig text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | zig-cache/ 2 | zig-out/ 3 | .vscode/ 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | 2 | [submodule "vendor/args"] 3 | path = vendor/args 4 | url = https://github.com/MasterQ32/zig-args 5 | [submodule "vendor/serve"] 6 | path = vendor/serve 7 | url = https://github.com/MasterQ32/zig-serve 8 | -------------------------------------------------------------------------------- /.zpm/locals.zpm: -------------------------------------------------------------------------------- 1 | [apple_pie] 2 | file = ../vendor/apple_pie/src/apple_pie.zig 3 | 4 | [positron] 5 | file = ../src/positron.zig 6 | deps = apple_pie -------------------------------------------------------------------------------- /.zpm/pkgs.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | fn pkgRoot() []const u8 { 4 | return std.fs.path.dirname(@src().file) orelse "."; 5 | } 6 | 7 | pub const pkgs = struct { 8 | pub const args = std.build.Pkg{ 9 | .name = "args", 10 | .path = .{ .path = pkgRoot() ++ "/../vendor/args/args.zig" }, 11 | .dependencies = &[_]std.build.Pkg{}, 12 | }; 13 | pub const apple_pie = std.build.Pkg{ 14 | .name = "apple_pie", 15 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../vendor/apple_pie/src/apple_pie.zig" }, 16 | .dependencies = &[_]std.build.Pkg{}, 17 | }; 18 | pub const positron = std.build.Pkg{ 19 | .name = "positron", 20 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../src/positron.zig" }, 21 | .dependencies = &[_]std.build.Pkg{apple_pie}, 22 | }; 23 | }; 24 | 25 | pub const imports = struct { 26 | }; 27 | -------------------------------------------------------------------------------- /.zpm/zpm.conf: -------------------------------------------------------------------------------- 1 | # configures the path where the build.zig import file is generated. 2 | # the path is relative to this file. 3 | # pkgs-file = ./pkgs.zig -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚛️ Positron 2 | 3 |  4 | 5 | A Zig binding to the [webview](https://github.com/webview/webview) library. Make Zig applications with a nice HTML5 frontend a reality! 6 | 7 |   8 | 9 | ## Usage 10 | 11 | ```zig 12 | //! src/minimal.zig 13 | 14 | const std = @import("std"); 15 | const wv = @import("positron"); 16 | 17 | pub fn main() !void { 18 | const view = try wv.View.create(false, null); 19 | defer view.destroy(); 20 | 21 | view.setTitle("Webview Example"); 22 | view.setSize(480, 320, .none); 23 | 24 | view.navigate("https://ziglang.org"); 25 | view.run(); 26 | } 27 | ``` 28 | 29 | ```zig 30 | //! build.zig 31 | 32 | const std = @import("std"); 33 | const pkgs = @import(".zpm/pkgs.zig"); 34 | const Sdk = @import("Sdk.zig"); 35 | 36 | pub fn build(b: *std.build.Builder) void { 37 | const target = b.standardTargetOptions(.{}); 38 | const mode = b.standardReleaseOptions(); 39 | 40 | const exe = b.addExecutable("demo", "src/minimal.zig"); 41 | exe.setTarget(target); 42 | exe.setBuildMode(mode); 43 | 44 | // Add and link the package. 45 | exe.addPackage(Sdk.getPackage("positron")); 46 | Sdk.linkPositron(exe, null); 47 | 48 | exe.install(); 49 | } 50 | ``` 51 | 52 | ## Example 53 | 54 | The example is a small, two-view chat application that transfers data bidirectionally between backend and frontend. 55 | 56 | Log in with `ziggy`/`love` and you can send messages, no real server there though! 57 | 58 | You can build the example with `zig build` and run it with `zig build run`. 59 | 60 | ## Building 61 | 62 | ### Linux 63 | 64 | Install `gtk-3` and `webkit2gtk`, then invoke `zig build`. 65 | 66 | ### Windows 67 | 68 | Download [Edge Dev Channel](https://www.microsoftedgeinsider.com/download), then invoke `zig build`. 69 | 70 | ### MacOS 71 | 72 | No research was done for the support on MacOS. Try with `zig build`. 73 | 74 | ## Contributing 75 | 76 | This library is in a early state and is very WIP. Still, feel free to contribute with PRs, or use it. Just don't assume a stable API. -------------------------------------------------------------------------------- /Sdk.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub const Backend = enum { 4 | gtk, 5 | cocoa, 6 | edge, 7 | }; 8 | 9 | fn sdkRoot() []const u8 { 10 | return std.fs.path.dirname(@src().file) orelse "."; 11 | } 12 | 13 | pub fn getPackage(name: []const u8) std.build.Pkg { 14 | const sdkPath = comptime sdkRoot(); 15 | return std.build.Pkg{ 16 | .name = name, 17 | .source = .{ .path = sdkPath ++ "/src/positron.zig" }, 18 | .dependencies = &[_]std.build.Pkg{ 19 | std.build.Pkg{ 20 | .name = "serve", 21 | .source = .{ .path = sdkPath ++ "/vendor/serve/src/serve.zig" }, 22 | .dependencies = &[_]std.build.Pkg{ 23 | std.build.Pkg{ 24 | .name = "uri", 25 | .source = .{ .path = sdkPath ++ "/vendor/serve/vendor/uri/uri.zig" }, 26 | }, 27 | std.build.Pkg{ 28 | .name = "network", 29 | .source = .{ .path = sdkPath ++ "/vendor/serve/vendor/network/network.zig" }, 30 | }, 31 | }, 32 | }, 33 | }, 34 | }; 35 | } 36 | 37 | /// Links positron to `exe`. `exe` must have its final `target` already set! 38 | /// `backend` selects the backend to be used, use `null` for a good default. 39 | pub fn linkPositron(exe: *std.build.LibExeObjStep, backend: ?Backend) void { 40 | exe.linkLibC(); 41 | exe.linkSystemLibrary("c++"); 42 | 43 | // make webview library standalone 44 | const sdkPath = comptime sdkRoot(); 45 | exe.addCSourceFile(sdkPath ++ "/src/wv/webview.cpp", &[_][]const u8{ 46 | "-std=c++17", 47 | "-fno-sanitize=undefined", 48 | }); 49 | 50 | if (exe.target.isWindows()) { 51 | 52 | // Attempts to fix windows building: 53 | exe.addIncludePath("vendor/winsdk"); 54 | 55 | exe.addIncludePath(sdkPath ++ "/vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/include"); 56 | exe.addLibraryPath(sdkPath ++ "/vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/x64"); 57 | exe.linkSystemLibrary("user32"); 58 | exe.linkSystemLibrary("ole32"); 59 | exe.linkSystemLibrary("oleaut32"); 60 | exe.addObjectFile(sdkPath ++ "/vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/x64/WebView2Loader.dll.lib"); 61 | //exe.linkSystemLibrary("windowsapp"); 62 | } 63 | 64 | if (backend) |b| { 65 | switch (b) { 66 | .gtk => exe.defineCMacro("WEBVIEW_GTK", null), 67 | .cocoa => exe.defineCMacro("WEBVIEW_COCOA", null), 68 | .edge => exe.defineCMacro("WEBVIEW_EDGE", null), 69 | } 70 | } 71 | 72 | switch (exe.target.getOsTag()) { 73 | //# Windows (x64) 74 | //$ c++ main.cc -mwindows -L./dll/x64 -lwebview -lWebView2Loader -o webview-example.exe 75 | .windows => { 76 | exe.addLibraryPath(sdkPath ++ "/vendor/webview/dll/x64"); 77 | }, 78 | //# MacOS 79 | //$ c++ main.cc -std=c++11 -framework WebKit -o webview-example 80 | .macos => { 81 | exe.linkFramework("WebKit"); 82 | }, 83 | //# Linux 84 | //$ c++ main.cc `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0` -o webview-example 85 | .linux => { 86 | exe.linkSystemLibrary("gtk+-3.0"); 87 | exe.linkSystemLibrary("webkit2gtk-4.0"); 88 | }, 89 | else => std.debug.panic("unsupported os: {s}", .{std.meta.tagName(exe.target.getOsTag())}), 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const pkgs = @import(".zpm/pkgs.zig"); 3 | const Sdk = @import("Sdk.zig"); 4 | const ZigServe = @import("vendor/serve/build.zig"); 5 | 6 | pub fn build(b: *std.build.Builder) void { 7 | const target = b.standardTargetOptions(.{}); 8 | const mode = b.standardReleaseOptions(); 9 | const backend = b.option(Sdk.Backend, "backend", "Configures the backend that should be used for webview."); 10 | 11 | const wolfssl = ZigServe.createWolfSSL(b, target); 12 | 13 | const minimal_exe = b.addExecutable("positron-minimal", "example/minimal.zig"); 14 | minimal_exe.setTarget(target); 15 | minimal_exe.setBuildMode(mode); 16 | minimal_exe.linkLibrary(wolfssl); 17 | minimal_exe.addIncludePath("vendor/serve/vendor/wolfssl"); 18 | 19 | minimal_exe.addPackage(Sdk.getPackage("positron")); 20 | Sdk.linkPositron(minimal_exe, null); 21 | 22 | minimal_exe.install(); 23 | 24 | const exe = b.addExecutable("positron-demo", "example/main.zig"); 25 | exe.linkLibrary(wolfssl); 26 | exe.addIncludePath("vendor/serve/vendor/wolfssl"); 27 | exe.setTarget(target); 28 | 29 | exe.setBuildMode(mode); 30 | 31 | Sdk.linkPositron(exe, backend); 32 | exe.addPackage(Sdk.getPackage("positron")); 33 | 34 | exe.install(); 35 | 36 | const positron_test = b.addTest("src/positron.zig"); 37 | 38 | Sdk.linkPositron(positron_test, null); 39 | positron_test.addPackage(Sdk.getPackage("positron")); 40 | 41 | const test_step = b.step("test", "Runs the test suite"); 42 | 43 | test_step.dependOn(&positron_test.step); 44 | 45 | const run_cmd = exe.run(); 46 | 47 | run_cmd.step.dependOn(b.getInstallStep()); 48 | 49 | if (b.args) |args| { 50 | run_cmd.addArgs(args); 51 | } 52 | 53 | const run_step = b.step("run", "Run the app"); 54 | 55 | run_step.dependOn(&run_cmd.step); 56 | 57 | // const demo = b.addExecutable("webview-demo", null); 58 | 59 | // // make webview library standalone 60 | // demo.addCSourceFile("src/minimal.cpp", &[_][]const u8{ 61 | // "-std=c++17", 62 | // "-fno-sanitize=undefined", 63 | // }); 64 | // demo.linkLibC(); 65 | // demo.linkSystemLibrary("c++"); 66 | // demo.install(); 67 | 68 | // demo.addIncludeDir("vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/include"); 69 | // demo.addLibPath("vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/x64"); 70 | // demo.linkSystemLibrary("user32"); 71 | // demo.linkSystemLibrary("ole32"); 72 | // demo.linkSystemLibrary("oleaut32"); 73 | // demo.addObjectFile("vendor/Microsoft.Web.WebView2.1.0.902.49/build/native/x64/WebView2Loader.dll.lib"); 74 | 75 | // const exec = demo.run(); 76 | // exec.step.dependOn(b.getInstallStep()); 77 | 78 | // const demo_run_step = b.step("run.demo", "Run the app"); 79 | // demo_run_step.dependOn(&exec.step); 80 | } 81 | -------------------------------------------------------------------------------- /design/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 111 | -------------------------------------------------------------------------------- /design/social-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ziglibs/positron/f144d53ba4ad9e88e5883212ead13e8c1f7ad234/design/social-preview.png -------------------------------------------------------------------------------- /design/social-preview.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ziglibs/positron/f144d53ba4ad9e88e5883212ead13e8c1f7ad234/design/social-preview.xcf -------------------------------------------------------------------------------- /example/app.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 55 | 144 | 145 | 146 | 147 |