├── .changes ├── config.json └── readme.md ├── .editorconfig ├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── docs-report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── config.yml └── workflows │ ├── build-sample-on-pr.yml │ ├── check-on-push.yml │ ├── covector-status.yml │ ├── covector-version-or-publish.yml │ └── test-on-pr.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── examples ├── run_and_terminate.rs └── sample.rs ├── src ├── builder.rs ├── lib.rs └── webview.rs └── webview-official-sys ├── CHANGELOG.md ├── Cargo.toml ├── build.rs └── src └── lib.rs /.changes/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "gitSiteUrl": "https://www.github.com/webview/webview_rust/", 3 | "pkgManagers": { 4 | "rust": { 5 | "version": true, 6 | "getPublishedVersion": "cargo search ${ pkgFile.pkg.package.name } --limit 1 | sed -nE 's/^[^\"]*\"//; s/\".*//1p' -", 7 | "prepublish": [ 8 | "sudo apt-get update", 9 | "sudo apt-get install -y webkit2gtk-4.0", 10 | { 11 | "command": "cargo generate-lockfile", 12 | "dryRunCommand": true, 13 | "runFromRoot": true, 14 | "pipe": true 15 | }, 16 | { 17 | "command": "echo \"# Cargo Audit\"", 18 | "dryRunCommand": true, 19 | "pipe": true 20 | }, 21 | { 22 | "command": "echo \"\\`\\`\\`\"", 23 | "dryRunCommand": true, 24 | "pipe": true 25 | }, 26 | { 27 | "command": "cargo audit", 28 | "dryRunCommand": true, 29 | "runFromRoot": true, 30 | "pipe": true 31 | }, 32 | { 33 | "command": "echo \"\\`\\`\\`\"", 34 | "dryRunCommand": true, 35 | "pipe": true 36 | } 37 | ], 38 | "publish": [ 39 | { 40 | "command": "cargo package --allow-dirty", 41 | "dryRunCommand": true 42 | }, 43 | { 44 | "command": "echo \"# Cargo Publish\"", 45 | "dryRunCommand": true, 46 | "pipe": true 47 | }, 48 | { 49 | "command": "echo \"\\`\\`\\`\"", 50 | "dryRunCommand": true, 51 | "pipe": true 52 | }, 53 | { 54 | "command": "cargo publish", 55 | "dryRunCommand": "cargo publish --dry-run", 56 | "pipe": true 57 | }, 58 | { 59 | "command": "echo \"\\`\\`\\`\"", 60 | "dryRunCommand": true, 61 | "pipe": true 62 | } 63 | ], 64 | "postpublish": [ 65 | "git tag ${ pkgFile.pkg.package.name }-v${ pkgFile.versionMajor } -f", 66 | "git tag ${ pkgFile.pkg.package.name }-v${ pkgFile.versionMajor }.${ pkgFile.versionMinor } -f", 67 | "git push --tags -f" 68 | ], 69 | "assets": [ 70 | { 71 | "path": "${ pkg.path }/${ pkgFile.pkg.package.name }-${ pkgFile.version }.crate", 72 | "name": "${ pkgFile.pkg.package.name }-${ pkgFile.version }.crate" 73 | } 74 | ] 75 | } 76 | }, 77 | "packages": { 78 | "sys": { 79 | "path": "./webview-official-sys", 80 | "manager": "rust" 81 | }, 82 | "webview": { 83 | "path": ".", 84 | "manager": "rust", 85 | "dependencies": ["sys"] 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /.changes/readme.md: -------------------------------------------------------------------------------- 1 | # Changes 2 | ##### via https://github.com/jbolda/covector 3 | 4 | As you create PRs and make changes that require a version bump, please add a new markdown file in this folder. You do not note the version *number*, but rather the type of bump that you expect: major, minor, or patch. The filename is not important, as long as it is a `.md`, but we recommend it represents the overall change for our sanity. 5 | 6 | When you select the version bump required, you do *not* need to consider depedencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process. 7 | 8 | Use the following format: 9 | ```md 10 | --- 11 | "tauri.js": patch 12 | "tauri": minor 13 | --- 14 | 15 | Change summary goes here 16 | 17 | ``` 18 | 19 | Summaries do not have a specific character limit, but are text only. These summaries are used within the (future implementation of) changelogs. They will give context to the change and also point back to the original PR if more details and context are needed. 20 | 21 | Changes will be designated as a `major`, `minor` or `patch` as further described in [semver](https://semver.org/). 22 | 23 | Given a version number MAJOR.MINOR.PATCH, increment the: 24 | 25 | - MAJOR version when you make incompatible API changes, 26 | - MINOR version when you add functionality in a backwards compatible manner, and 27 | - PATCH version when you make backwards compatible bug fixes. 28 | 29 | Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format, but will be discussed prior to usage (as extra steps will be necessary in consideration of merging and publishing). 30 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Current WG Code Sub Teams: 2 | # @tauri-apps/admins 3 | # @tauri-apps/core 4 | # @tauri-apps/testing 5 | 6 | # admins default to review 7 | # Order is important; the last matching pattern takes the most precedence. 8 | * @tauri-apps/admins 9 | 10 | .github @tauri-apps/admins @tauri-apps/testing 11 | 12 | /examples/ @tauri-apps/testing 13 | 14 | /@tauri-app/core 15 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Tauri Contributing Guide 2 | 3 | Hi! We, the maintainers, are really excited that you are interested in contributing to Tauri. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. 4 | 5 | - [Code of Conduct](CODE_OF_CONDUCT.md) 6 | - [Issue Reporting Guidelines](#issue-reporting-guidelines) 7 | - [Pull Request Guidelines](#pull-request-guidelines) 8 | - [Development Setup](#development-setup) 9 | - [Project Structure](#project-structure) 10 | - [Financial Contribution](#financial-contribution) 11 | 12 | ## Issue Reporting Guidelines 13 | 14 | - The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately. 15 | 16 | - For simple beginner questions, you can get quick answers from the [Tauri Discord chat](https://discord.gg/SpmNs4S). 17 | 18 | - Try to search for your issue, it may have already been answered or even fixed in the development branch (`dev`). 19 | 20 | - Check if the issue is reproducible with the latest stable version of Tauri. If you are using a pre-release, please indicate the specific version you are using. 21 | 22 | - It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Although we would love to help our users as much as possible, diagnosing issues without clear reproduction steps is extremely time-consuming and simply not sustainable. 23 | 24 | - Use only the minimum amount of code necessary to reproduce the unexpected behavior. A good bug report should isolate specific methods that exhibit unexpected behavior and precisely define how expectations were violated. What did you expect the method or methods to do, and how did the observed behavior differ? The more precisely you isolate the issue, the faster we can investigate. 25 | 26 | - Issues with no clear repro steps will not be triaged. If an issue labeled "need repro" receives no further input from the issue author for more than 5 days, it will be closed. 27 | 28 | - If your issue is resolved but still open, don’t hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it. 29 | 30 | - Most importantly, we beg your patience: the team must balance your request against many other responsibilities — fixing other bugs, answering other questions, new features, new documentation, etc. The issue list is not paid support and we cannot make guarantees about how fast your issue can be resolved. 31 | 32 | ## Pull Request Guidelines 33 | 34 | - The `master` branch is basically just a snapshot of the latest stable release. All development should be done in dedicated branches. **Do not submit PRs against the `master` branch.** 35 | 36 | - Checkout a topic branch from the relevant branch, e.g. `dev`, and merge back against that branch. 37 | 38 | - **DO NOT** checkin `dist` in the commits. 39 | 40 | - It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging. 41 | 42 | - If adding new feature: 43 | - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it. 44 | 45 | - If fixing a bug: 46 | - If you are resolving a special issue, add `(fix: #xxxx[,#xxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`. 47 | - Provide detailed description of the bug in the PR. Live demo preferred. 48 | 49 | ## Development Setup 50 | TO BE UPDATED. 51 | 52 | ## Financial Contribution 53 | 54 | Tauri is an MIT-licensed open source project. Its ongoing development can be supported via open-collective. 55 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # 4 | patreon: # 5 | open_collective: # 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve Tauri 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Platform and Versions (please complete the following information):** 27 | 28 | OS: 29 | Node: 30 | NPM: 31 | Yarn: 32 | Rustc: 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | 37 | **Stack Trace** 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/docs-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Docs report 3 | about: Create a report to help us improve Tauri docs 4 | title: "[docs]" 5 | labels: docs 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for Tauri 4 | title: '' 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | **What kind of change does this PR introduce?** (check at least one) 10 | 13 | 14 | - [ ] Bugfix 15 | - [ ] Feature 16 | - [ ] New Binding Issue #___ 17 | - [ ] Code style update 18 | - [ ] Refactor 19 | - [ ] Build-related changes 20 | - [ ] Other, please describe: 21 | 22 | **Does this PR introduce a breaking change?** (check one) 23 | 26 | 27 | - [ ] Yes. Issue #___ 28 | - [ ] No 29 | 30 | 31 | **The PR fulfills these requirements:** 32 | 33 | - [ ] It's submitted to the `dev` branch and _not_ the `master` branch 34 | - [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix: #xxx[,#xxx]`, where "xxx" is the issue number) 35 | 36 | If adding a **new feature**, the PR's description includes: 37 | - [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it) 38 | 39 | **Other information:** 40 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webview/webview_rust/6f2c2ccf52dd8a53ba8cf9a543868a578c1f093c/.github/config.yml -------------------------------------------------------------------------------- /.github/workflows/build-sample-on-pr.yml: -------------------------------------------------------------------------------- 1 | name: build sample project 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | build-sample: 7 | runs-on: ${{ matrix.platform }} 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | platform: [ubuntu-latest, macos-latest, windows-latest] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | submodules: true 18 | - name: install stable 19 | uses: actions-rs/toolchain@v1 20 | with: 21 | toolchain: stable 22 | - name: install webkit2gtk (ubuntu only) 23 | if: matrix.platform == 'ubuntu-latest' 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install -y webkit2gtk-4.0 27 | - name: build 28 | run: | 29 | cargo build --example sample 30 | 31 | - name: Upload Artifacts (Windows) 32 | if: matrix.platform == 'windows-latest' 33 | uses: actions/upload-artifact@v1 34 | with: 35 | name: sample-windows 36 | path: target/debug/examples/sample.exe 37 | 38 | - name: Upload Artifacts (Ubuntu) 39 | if: matrix.platform == 'ubuntu-latest' 40 | uses: actions/upload-artifact@v1 41 | with: 42 | name: sample-ubuntu 43 | path: target/debug/examples/sample 44 | 45 | - name: Upload Artifacts (MacOS) 46 | if: matrix.platform == 'macos-latest' 47 | uses: actions/upload-artifact@v1 48 | with: 49 | name: sample-macOS 50 | path: target/debug/examples/sample 51 | 52 | -------------------------------------------------------------------------------- /.github/workflows/check-on-push.yml: -------------------------------------------------------------------------------- 1 | name: clippy check 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - master 7 | - dev 8 | 9 | jobs: 10 | clippy_check: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | submodules: true 17 | - name: install webkit2gtk 18 | run: | 19 | sudo apt-get update 20 | sudo apt-get install -y webkit2gtk-4.0 21 | - run: rustup component add clippy 22 | - uses: actions-rs/clippy-check@v1 23 | with: 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | -------------------------------------------------------------------------------- /.github/workflows/covector-status.yml: -------------------------------------------------------------------------------- 1 | name: covector status 2 | on: [pull_request] 3 | 4 | jobs: 5 | covector: 6 | runs-on: ubuntu-latest 7 | 8 | steps: 9 | - uses: actions/checkout@v2 10 | with: 11 | fetch-depth: 0 12 | - name: covector status 13 | uses: jbolda/covector/packages/action@covector-v0 14 | id: covector 15 | with: 16 | command: 'status' 17 | -------------------------------------------------------------------------------- /.github/workflows/covector-version-or-publish.yml: -------------------------------------------------------------------------------- 1 | name: version or publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - dev 7 | 8 | jobs: 9 | version-or-publish: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | submodules: true 17 | - name: cargo login 18 | run: cargo login ${{ secrets.crate_token }} 19 | - name: git config 20 | run: | 21 | git config --global user.name "${{ github.event.pusher.name }}" 22 | git config --global user.email "${{ github.event.pusher.email }}" 23 | - name: covector version 24 | uses: jbolda/covector/packages/action@covector-v0 25 | id: covector 26 | with: 27 | command: 'version-or-publish' 28 | - name: Create Pull Request With Versions Bumped 29 | if: steps.covector.outputs.commandRan == 'version' 30 | uses: tauri-apps/create-pull-request@v3.4.1 31 | with: 32 | token: ${{ secrets.GITHUB_TOKEN }} 33 | branch: release/version-updates 34 | title: Apply Version Updates From Current Changes 35 | commit-message: "apply version updates" 36 | labels: "version updates" 37 | body: ${{ steps.covector.outputs.change }} 38 | -------------------------------------------------------------------------------- /.github/workflows/test-on-pr.yml: -------------------------------------------------------------------------------- 1 | name: test library 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | test-webview-rust: 7 | runs-on: ${{ matrix.platform }} 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | platform: [ubuntu-latest, macos-latest, windows-latest] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | submodules: true 18 | - name: install stable 19 | uses: actions-rs/toolchain@v1 20 | with: 21 | toolchain: stable 22 | - name: install webkit2gtk (ubuntu only) 23 | if: matrix.platform == 'ubuntu-latest' 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install -y webkit2gtk-4.0 27 | - name: build 28 | run: | 29 | cargo build 30 | - name: test 31 | run: | 32 | cargo test 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # node-waf configuration 26 | .lock-wscript 27 | 28 | # Compiled binary addons (http://nodejs.org/api/addons.html) 29 | build/Release 30 | 31 | # dotenv environment variables file 32 | .env 33 | 34 | /.vs 35 | .DS_Store 36 | .Thumbs.db 37 | *.sublime* 38 | .idea 39 | debug.log 40 | package-lock.json 41 | .vscode/settings.json 42 | */.vscode/ 43 | proptest-regressions/ 44 | TODO.md 45 | 46 | # rust compiled folders 47 | target 48 | 49 | # Cargo lock for libs 50 | Cargo.lock 51 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "webview-official"] 2 | path = webview-official-sys/webview-official 3 | url = https://github.com/webview/webview 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.2.0] 4 | 5 | - Remove lifetime parameter on `Webview` and remove `WebviewMut` struct. 6 | - [b633c25](https://www.github.com/webview/webview_rust/commit/b633c256904381fcb9b027792c0b83bd2d752391) refactor: remove webview lifetime argument, drop WebviewMut ([#61](https://www.github.com/webview/webview_rust/pull/61)) on 2021-02-05 7 | 8 | ## [0.1.1] 9 | 10 | - Add eval method to WebviewMut 11 | - [68ea653](https://www.github.com/webview/webview_rust/commit/68ea653f2a8082ce2dce600595a50aa555183e28) Add eval method to WebviewMut ([#59](https://www.github.com/webview/webview_rust/pull/59)) on 2021-02-03 12 | 13 | ## [0.1.0] 14 | 15 | - Implement Send/Sync trait to Webview 16 | - [49d26ed](https://www.github.com/webview/webview_rust/commit/49d26ed8916ccac2f8eaf9f42b99ee88735af201) Implement Send/Sync trait to Webview ([#57](https://www.github.com/webview/webview_rust/pull/57)) on 2021-01-31 17 | 18 | ## [0.0.5] 19 | 20 | - - Bump WebView2 to version 1.0 21 | - Enable DPI awareness by default on Windows 22 | - Bumped due to a bump in sys. 23 | - [0e311cb](https://www.github.com/webview/webview_rust/commit/0e311cbd8e6083b674547ffbccb9f0247e1bdd16) Update webview-official which enables dpi awareness on windows ([#55](https://www.github.com/webview/webview_rust/pull/55)) on 2021-01-27 24 | 25 | ## [0.0.4] 26 | 27 | - Update webview-official to fix macOS port viability. 28 | - [f7ba383](https://www.github.com/webview/webview_rust/commit/f7ba383af21e13c1ac3076803a22c6a54d974894) chore: restructure submodule and crate, reset version and changelog ([#41](https://www.github.com/webview/webview_rust/pull/41)) on 2020-07-27 29 | - [a196328](https://www.github.com/webview/webview_rust/commit/a196328a375395e8b42a2aa2d65570b7902f4376) apply version updates ([#43](https://www.github.com/webview/webview_rust/pull/43)) on 2020-07-27 30 | - [8ea7f5a](https://www.github.com/webview/webview_rust/commit/8ea7f5a4b922978d8a78f1ffaf455dbc9b7fa978) Bump both crate version ([#53](https://www.github.com/webview/webview_rust/pull/53)) on 2021-01-22 31 | 32 | ## [0.0.3] 33 | 34 | - Separate raw ffi to individual sys crate. 35 | - [f7ba383](https://www.github.com/webview/webview_rust/commit/f7ba383af21e13c1ac3076803a22c6a54d974894) chore: restructure submodule and crate, reset version and changelog ([#41](https://www.github.com/webview/webview_rust/pull/41)) on 2020-07-27 36 | 37 | ## [0.0.2] 38 | 39 | - Fix order of initializing script on windows 40 | - [5faa76c](https://www.github.com/webview/webview_rust/commit/5faa76c268ec1048e5ee20424684ab9de104cbd0) fix: initializing order ([#35](https://www.github.com/webview/webview_rust/pull/35)) on 2020-07-23 41 | 42 | ## [0.0.1] 43 | 44 | - Publishing with Covector. 45 | - [377224c](https://www.github.com/webview/webview_rust/commit/377224c29a8eb2393a6a5dfe3f2e510c57fa3147) feat(workflow) add covector ([#30](https://www.github.com/webview/webview_rust/pull/30)) on 2020-07-20 46 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "webview_official" 3 | version = "0.2.0" 4 | authors = [ 5 | "Lucas Fernandes Gonçalves Nogueira ", 6 | "Daniel Thompson-Yvetot ", 7 | "Tensor Programming ", 8 | "Serge Zaitsev " 9 | ] 10 | readme = "README.md" 11 | license = "MIT OR Apache-2.0" 12 | repository = "https://github.com/tauri-apps/webview_rust" 13 | description = "Official Webview-org Rust bindings, a tiny cross-platform library to render web-based GUIs for desktop applications" 14 | keywords = [ "web", "gui", "desktop", "webkit" ] 15 | categories = [ "gui", "api-bindings" ] 16 | edition = "2018" 17 | 18 | [lib] 19 | name = "webview_official" 20 | path = "src/lib.rs" 21 | 22 | [[example]] 23 | name = "sample" 24 | path = "examples/sample.rs" 25 | 26 | [dependencies] 27 | webview-official-sys = { path = "webview-official-sys", version = "0.1" } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Tauri 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webview_rust 2 | Bindings in rust for webview (zserge) 3 | 4 | This repository is the staging area for the construction of "official" rust bindings to [webview/webview](https://github.com/webview/webview). 5 | 6 | ## Setup for development 7 | Please clone this repository and install the submodule: 8 | ``` 9 | git clone --recurse-submodules -j8 git@github.com:webview/webview_rust.git 10 | ``` 11 | 12 | If it bails, please make sure you are using a proper SSH key. 13 | 14 | ## License 15 | MIT / Apache 2 16 | -------------------------------------------------------------------------------- /examples/run_and_terminate.rs: -------------------------------------------------------------------------------- 1 | use std::{thread, time}; 2 | use webview_official::{SizeHint, WebviewBuilder}; 3 | 4 | fn main() { 5 | let mut webview = WebviewBuilder::new() 6 | .debug(true) 7 | .title("TEST") 8 | .width(800) 9 | .height(600) 10 | .resize(SizeHint::NONE) 11 | .url("https://google.com") 12 | .build(); 13 | 14 | let mut webview_ = webview.clone(); 15 | 16 | thread::spawn(move || { 17 | thread::sleep(time::Duration::from_secs(5)); 18 | webview_.terminate(); 19 | }); 20 | 21 | webview.run(); 22 | } 23 | -------------------------------------------------------------------------------- /examples/sample.rs: -------------------------------------------------------------------------------- 1 | use webview_official::{SizeHint, WebviewBuilder}; 2 | 3 | fn main() { 4 | let mut webview = WebviewBuilder::new() 5 | .debug(true) 6 | .title("TEST") 7 | .width(1024) 8 | .height(768) 9 | .resize(SizeHint::NONE) 10 | .init("window.x = 42") 11 | .dispatch(|w| { 12 | w.set_size(800, 600, SizeHint::MIN); 13 | println!("Hello World"); 14 | }) 15 | .url("https://google.com") 16 | .build(); 17 | 18 | webview.eval("console.log('The anwser is ' + window.x);"); 19 | let w = webview.clone(); 20 | webview.bind("xxx", move |seq, _req| { 21 | w.r#return(seq, 0, "{ result: 'We always knew it!' }"); 22 | }); 23 | webview.run(); 24 | } 25 | -------------------------------------------------------------------------------- /src/builder.rs: -------------------------------------------------------------------------------- 1 | use crate::{SizeHint, Webview, Window}; 2 | 3 | #[derive(Default)] 4 | pub struct WebviewBuilder<'a> { 5 | title: Option<&'a str>, 6 | url: Option<&'a str>, 7 | init: Option<&'a str>, 8 | eval: Option<&'a str>, 9 | size: (usize, usize, SizeHint), 10 | debug: bool, 11 | dispatch: Option>, 12 | window: Option<&'a mut Window>, 13 | } 14 | 15 | impl<'a> WebviewBuilder<'a> { 16 | pub fn new() -> Self { 17 | WebviewBuilder::default() 18 | } 19 | 20 | pub fn debug(mut self, debug: bool) -> Self { 21 | self.debug = debug; 22 | self 23 | } 24 | 25 | pub fn window(mut self, window: &'a mut Window) -> Self { 26 | self.window = Some(window); 27 | self 28 | } 29 | 30 | pub fn title(mut self, title: &'a str) -> Self { 31 | self.title = Some(title); 32 | self 33 | } 34 | 35 | pub fn url(mut self, url: &'a str) -> Self { 36 | self.url = Some(url); 37 | self 38 | } 39 | 40 | pub fn init(mut self, init: &'a str) -> Self { 41 | self.init = Some(init); 42 | self 43 | } 44 | 45 | pub fn eval(mut self, eval: &'a str) -> Self { 46 | self.eval = Some(eval); 47 | self 48 | } 49 | 50 | pub fn width(mut self, width: usize) -> Self { 51 | self.size.0 = width; 52 | self 53 | } 54 | 55 | pub fn height(mut self, height: usize) -> Self { 56 | self.size.1 = height; 57 | self 58 | } 59 | 60 | pub fn resize(mut self, hint: SizeHint) -> Self { 61 | self.size.2 = hint; 62 | self 63 | } 64 | 65 | pub fn dispatch(mut self, f: F) -> Self 66 | where 67 | F: FnOnce(&mut Webview) + Send + 'static, 68 | { 69 | self.dispatch = Some(Box::new(f)); 70 | self 71 | } 72 | 73 | pub fn build(self) -> Webview { 74 | let mut w = Webview::create(self.debug, self.window); 75 | if let Some(title) = self.title { 76 | w.set_title(title); 77 | } 78 | 79 | if let Some(init) = self.init { 80 | w.init(init); 81 | } 82 | 83 | if let Some(url) = self.url { 84 | w.navigate(url); 85 | } 86 | 87 | if let Some(eval) = self.eval { 88 | w.eval(eval); 89 | } 90 | 91 | w.set_size(self.size.0 as i32, self.size.1 as i32, self.size.2); 92 | 93 | if let Some(f) = self.dispatch { 94 | w.dispatch(f); 95 | } 96 | 97 | w 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod builder; 2 | mod webview; 3 | 4 | pub use builder::WebviewBuilder; 5 | pub use webview::{SizeHint, Webview, Window}; 6 | -------------------------------------------------------------------------------- /src/webview.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{CStr, CString}; 2 | use std::mem; 3 | use std::os::raw::*; 4 | use std::ptr::null_mut; 5 | use std::sync::Arc; 6 | 7 | use webview_official_sys as sys; 8 | 9 | pub enum Window {} 10 | 11 | #[repr(i32)] 12 | #[derive(Debug)] 13 | pub enum SizeHint { 14 | NONE = 0, 15 | MIN = 1, 16 | MAX = 2, 17 | FIXED = 3, 18 | } 19 | 20 | impl Default for SizeHint { 21 | fn default() -> Self { 22 | SizeHint::NONE 23 | } 24 | } 25 | 26 | #[derive(Clone)] 27 | pub struct Webview { 28 | inner: Arc, 29 | url: String, 30 | } 31 | 32 | unsafe impl Send for Webview {} 33 | unsafe impl Sync for Webview {} 34 | 35 | impl Drop for Webview { 36 | fn drop(&mut self) { 37 | if Arc::strong_count(&self.inner) == 0 { 38 | unsafe { 39 | sys::webview_terminate(*self.inner); 40 | sys::webview_destroy(*self.inner); 41 | } 42 | } 43 | } 44 | } 45 | 46 | impl Webview { 47 | pub fn create(debug: bool, window: Option<&mut Window>) -> Webview { 48 | if let Some(w) = window { 49 | Webview { 50 | inner: Arc::new(unsafe { 51 | sys::webview_create(debug as c_int, w as *mut Window as *mut _) 52 | }), 53 | url: "".to_string(), 54 | } 55 | } else { 56 | Webview { 57 | inner: Arc::new(unsafe { sys::webview_create(debug as c_int, null_mut()) }), 58 | url: "".to_string(), 59 | } 60 | } 61 | } 62 | 63 | pub fn run(&mut self) { 64 | let c_url = CString::new(self.url.as_bytes()).expect("No null bytes in parameter url"); 65 | unsafe { sys::webview_navigate(*self.inner, c_url.as_ptr()) } 66 | unsafe { sys::webview_run(*self.inner) } 67 | } 68 | 69 | pub fn terminate(&mut self) { 70 | unsafe { sys::webview_terminate(*self.inner) } 71 | } 72 | 73 | // TODO Window instance 74 | pub fn set_title(&mut self, title: &str) { 75 | let c_title = CString::new(title).expect("No null bytes in parameter title"); 76 | unsafe { sys::webview_set_title(*self.inner, c_title.as_ptr()) } 77 | } 78 | 79 | pub fn set_size(&mut self, width: i32, height: i32, hints: SizeHint) { 80 | unsafe { sys::webview_set_size(*self.inner, width, height, hints as i32) } 81 | } 82 | 83 | pub fn get_window(&self) -> *mut Window { 84 | unsafe { sys::webview_get_window(*self.inner) as *mut Window } 85 | } 86 | 87 | pub fn navigate(&mut self, url: &str) { 88 | self.url = url.to_string(); 89 | } 90 | 91 | pub fn init(&mut self, js: &str) { 92 | let c_js = CString::new(js).expect("No null bytes in parameter js"); 93 | unsafe { sys::webview_init(*self.inner, c_js.as_ptr()) } 94 | } 95 | 96 | pub fn eval(&mut self, js: &str) { 97 | let c_js = CString::new(js).expect("No null bytes in parameter js"); 98 | unsafe { sys::webview_eval(*self.inner, c_js.as_ptr()) } 99 | } 100 | 101 | pub fn dispatch(&mut self, f: F) 102 | where 103 | F: FnOnce(&mut Webview) + Send + 'static, 104 | { 105 | let closure = Box::into_raw(Box::new(f)); 106 | extern "C" fn callback(webview: sys::webview_t, arg: *mut c_void) 107 | where 108 | F: FnOnce(&mut Webview) + Send + 'static, 109 | { 110 | let mut webview = Webview { 111 | inner: Arc::new(webview), 112 | url: "".to_string(), 113 | }; 114 | let closure: Box = unsafe { Box::from_raw(arg as *mut F) }; 115 | (*closure)(&mut webview); 116 | } 117 | unsafe { sys::webview_dispatch(*self.inner, Some(callback::), closure as *mut _) } 118 | } 119 | 120 | pub fn bind(&mut self, name: &str, f: F) 121 | where 122 | F: FnMut(&str, &str), 123 | { 124 | let c_name = CString::new(name).expect("No null bytes in parameter name"); 125 | let closure = Box::into_raw(Box::new(f)); 126 | extern "C" fn callback(seq: *const c_char, req: *const c_char, arg: *mut c_void) 127 | where 128 | F: FnMut(&str, &str), 129 | { 130 | let seq = unsafe { 131 | CStr::from_ptr(seq) 132 | .to_str() 133 | .expect("No null bytes in parameter seq") 134 | }; 135 | let req = unsafe { 136 | CStr::from_ptr(req) 137 | .to_str() 138 | .expect("No null bytes in parameter req") 139 | }; 140 | let mut f: Box = unsafe { Box::from_raw(arg as *mut F) }; 141 | (*f)(seq, req); 142 | mem::forget(f); 143 | } 144 | unsafe { 145 | sys::webview_bind( 146 | *self.inner, 147 | c_name.as_ptr(), 148 | Some(callback::), 149 | closure as *mut _, 150 | ) 151 | } 152 | } 153 | 154 | pub fn r#return(&self, seq: &str, status: c_int, result: &str) { 155 | let c_seq = CString::new(seq).expect("No null bytes in parameter seq"); 156 | let c_result = CString::new(result).expect("No null bytes in parameter result"); 157 | unsafe { sys::webview_return(*self.inner, c_seq.as_ptr(), status, c_result.as_ptr()) } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /webview-official-sys/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.1.2] 4 | 5 | - - Bump WebView2 to version 1.0 6 | - Enable DPI awareness by default on Windows 7 | - [0e311cb](https://www.github.com/webview/webview_rust/commit/0e311cbd8e6083b674547ffbccb9f0247e1bdd16) Update webview-official which enables dpi awareness on windows ([#55](https://www.github.com/webview/webview_rust/pull/55)) on 2021-01-27 8 | 9 | ## [0.1.1] 10 | 11 | - Update webview-official to fix macOS port viability. 12 | - [f7ba383](https://www.github.com/webview/webview_rust/commit/f7ba383af21e13c1ac3076803a22c6a54d974894) chore: restructure submodule and crate, reset version and changelog ([#41](https://www.github.com/webview/webview_rust/pull/41)) on 2020-07-27 13 | - [a196328](https://www.github.com/webview/webview_rust/commit/a196328a375395e8b42a2aa2d65570b7902f4376) apply version updates ([#43](https://www.github.com/webview/webview_rust/pull/43)) on 2020-07-27 14 | - [8ea7f5a](https://www.github.com/webview/webview_rust/commit/8ea7f5a4b922978d8a78f1ffaf455dbc9b7fa978) Bump both crate version ([#53](https://www.github.com/webview/webview_rust/pull/53)) on 2021-01-22 15 | 16 | ## [0.1.0] 17 | 18 | - Separate raw ffi to individual sys crate. 19 | - [f7ba383](https://www.github.com/webview/webview_rust/commit/f7ba383af21e13c1ac3076803a22c6a54d974894) chore: restructure submodule and crate, reset version and changelog ([#41](https://www.github.com/webview/webview_rust/pull/41)) on 2020-07-27 20 | -------------------------------------------------------------------------------- /webview-official-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "webview-official-sys" 3 | version = "0.1.2" 4 | authors = [ "Ngo Iok Ui " ] 5 | edition = "2018" 6 | license = "MIT OR Apache-2.0" 7 | description = "Official Webview-org raw ffi bindings" 8 | 9 | [build-dependencies] 10 | cc = "1" 11 | pkg-config = "0.3" 12 | -------------------------------------------------------------------------------- /webview-official-sys/build.rs: -------------------------------------------------------------------------------- 1 | use cc::Build; 2 | use std::env; 3 | use std::fs; 4 | use std::path::PathBuf; 5 | 6 | fn main() { 7 | let mut build = Build::new(); 8 | 9 | let target = env::var("TARGET").unwrap(); 10 | 11 | build 12 | .cpp(true) 13 | .include("webview-official/webview.h") 14 | .flag_if_supported("/std:c++11") 15 | .flag_if_supported("-w"); 16 | 17 | // if env::var("DEBUG").is_err() { 18 | // build.define("NDEBUG", None); 19 | // } else { 20 | // build.define("DEBUG", None); 21 | // } 22 | 23 | if target.contains("windows") { 24 | // build.define("UNICODE", None); // doesn't work atm. 25 | build 26 | .file("webview-official/webview.cc") 27 | .flag_if_supported("/std:c++17"); 28 | build.include("webview-official/script"); 29 | 30 | for &lib in &["windowsapp", "user32", "oleaut32", "ole32"] { 31 | println!("cargo:rustc-link-lib={}", lib); 32 | } 33 | 34 | let webview2_arch = if target.contains("x86_64") { 35 | "x64" 36 | } else { 37 | "x86" 38 | }; 39 | 40 | // calculate full path to WebView2Loader.dll 41 | let mut webview2_path_buf = PathBuf::from(env::current_dir().unwrap().to_str().unwrap()); 42 | webview2_path_buf 43 | .push("webview-official/script/Microsoft.Web.WebView2.0.9.488/build/native"); 44 | webview2_path_buf.push(webview2_arch); 45 | let webview2_dir = webview2_path_buf.as_path().to_str().unwrap(); 46 | 47 | let loader_asm_name = "WebView2Loader.dll"; 48 | 49 | println!("cargo:rustc-link-search={}", webview2_dir); 50 | println!("cargo:rustc-link-lib={}", loader_asm_name); 51 | 52 | // copy WebView2Loader.dll to `target/debug` 53 | let mut src_asm_buf = PathBuf::from(webview2_dir); 54 | src_asm_buf.push(loader_asm_name); 55 | 56 | // we want to be able to calculate C:\crate\root\target\debug\ 57 | // while we can get this ^^^^^^^^^^^^^ and ^^^^^ from env::current_dir() and %PROFILE% respectively 58 | // there's no way to get this (reliably) ^^^^^^ 59 | // we can, however, use %OUT_DIR% (C:\crate\root\target\debug\build\webview_rust-xxxx\out\) 60 | // and navigate backwards to here ^^^^^^^^^^^^^^^^^^^^^^^^^^ 61 | let mut target_asm_buf = PathBuf::from(env::var("OUT_DIR").unwrap()); 62 | target_asm_buf.pop(); 63 | target_asm_buf.pop(); 64 | target_asm_buf.pop(); 65 | target_asm_buf.push(loader_asm_name); 66 | 67 | fs::copy(src_asm_buf.as_path(), target_asm_buf.as_path()).unwrap(); 68 | } else if target.contains("apple") { 69 | build.file("webview-official/webview.cc").flag("-std=c++11"); 70 | 71 | println!("cargo:rustc-link-lib=framework=Cocoa"); 72 | println!("cargo:rustc-link-lib=framework=WebKit"); 73 | } else if target.contains("linux") || target.contains("bsd") { 74 | let lib = pkg_config::Config::new() 75 | .atleast_version("2.8") 76 | .probe("webkit2gtk-4.0") 77 | .unwrap(); 78 | 79 | for path in lib.include_paths { 80 | build.include(path); 81 | } 82 | // pkg_config::Config::new() 83 | // .atleast_version("3.0") 84 | // .probe("gtk+-3.0") 85 | // .unwrap(); 86 | 87 | build.file("webview-official/webview.cc"); 88 | } else { 89 | panic!("Unsupported platform"); 90 | } 91 | 92 | println!("cargo:rerun-if-changed=webview-official/webview.h"); 93 | println!("cargo:rerun-if-changed=webview-official/webview.cc"); 94 | 95 | build.compile("webview"); 96 | } 97 | -------------------------------------------------------------------------------- /webview-official-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::{c_char, c_int, c_void}; 2 | 3 | pub type DispatchFn = extern "C" fn(webview: webview_t, arg: *mut c_void); 4 | pub type BindFn = extern "C" fn(seq: *const c_char, req: *const c_char, arg: *mut c_void); 5 | 6 | #[allow(non_camel_case_types)] 7 | pub type webview_t = *mut c_void; 8 | 9 | extern "C" { 10 | pub fn webview_create(debug: c_int, window: *mut c_void) -> webview_t; 11 | 12 | pub fn webview_destroy(w: webview_t); 13 | 14 | pub fn webview_run(w: webview_t); 15 | 16 | pub fn webview_terminate(w: webview_t); 17 | 18 | pub fn webview_dispatch(w: webview_t, fn_: Option, arg: *mut c_void); 19 | 20 | pub fn webview_get_window(w: webview_t) -> *mut c_void; 21 | 22 | pub fn webview_set_title(w: webview_t, title: *const c_char); 23 | 24 | pub fn webview_set_size(w: webview_t, width: c_int, height: c_int, hints: c_int); 25 | 26 | pub fn webview_navigate(w: webview_t, url: *const c_char); 27 | 28 | pub fn webview_init(w: webview_t, js: *const c_char); 29 | 30 | pub fn webview_eval(w: webview_t, js: *const c_char); 31 | 32 | pub fn webview_bind(w: webview_t, name: *const c_char, fn_: Option, arg: *mut c_void); 33 | 34 | pub fn webview_return(w: webview_t, seq: *const c_char, status: c_int, result: *const c_char); 35 | } 36 | --------------------------------------------------------------------------------