mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-11 10:43:31 +02:00
Compare commits
340 Commits
cli.rs-v2
...
@tauri-app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d78fa20d86 | ||
|
|
3b69c1384b | ||
|
|
704260bb3c | ||
|
|
36b082a9c8 | ||
|
|
f45d35cf06 | ||
|
|
ef35a793c5 | ||
|
|
15c62b5d99 | ||
|
|
9b90b67ed2 | ||
|
|
f1b0b00159 | ||
|
|
6bb721cd3d | ||
|
|
7f885bd5ed | ||
|
|
2eb21378a6 | ||
|
|
ab9ec42c10 | ||
|
|
07b6f9fa83 | ||
|
|
db9ec4e79c | ||
|
|
2a9a28044b | ||
|
|
5ee5ed4dc6 | ||
|
|
b8fd8e1bac | ||
|
|
0749a84ae0 | ||
|
|
80db9dff28 | ||
|
|
532279b724 | ||
|
|
3e98145ac3 | ||
|
|
fd2f8ab774 | ||
|
|
caddd5bdd8 | ||
|
|
72c2636527 | ||
|
|
83e024c670 | ||
|
|
07c9e352df | ||
|
|
d00178d60c | ||
|
|
705da977a9 | ||
|
|
1675e41f05 | ||
|
|
f9638b6315 | ||
|
|
aeddc40b9e | ||
|
|
fe6f81fa88 | ||
|
|
9dd67abd93 | ||
|
|
dbe81b8410 | ||
|
|
017861e4d5 | ||
|
|
77cc49ac3c | ||
|
|
e3b6d38d26 | ||
|
|
b705f89a10 | ||
|
|
97a05145fb | ||
|
|
b15948b11c | ||
|
|
5163861588 | ||
|
|
80a215a6f3 | ||
|
|
01ae1218dc | ||
|
|
d42668ce17 | ||
|
|
1ab0db6352 | ||
|
|
e816a46b95 | ||
|
|
a4b82d9dba | ||
|
|
b735b6799f | ||
|
|
7b5e8712e7 | ||
|
|
2421073576 | ||
|
|
510b62261c | ||
|
|
b0f27814b9 | ||
|
|
cc3d8e7731 | ||
|
|
8ce51cec3b | ||
|
|
0bff8c325d | ||
|
|
a9b2c0625c | ||
|
|
7aa30dec85 | ||
|
|
4926648751 | ||
|
|
06890c70c6 | ||
|
|
1ca69bcf2f | ||
|
|
6bdba1f330 | ||
|
|
b546b42db7 | ||
|
|
67d7877f27 | ||
|
|
89911296e4 | ||
|
|
8f8729d918 | ||
|
|
446fc99bbe | ||
|
|
6e48837860 | ||
|
|
883e52153e | ||
|
|
5966812735 | ||
|
|
b44e9c0fcb | ||
|
|
b2f83f03a8 | ||
|
|
0a2175eabb | ||
|
|
645e1dcc6e | ||
|
|
50a3d170f2 | ||
|
|
9b230de7bc | ||
|
|
50e9caad64 | ||
|
|
e5cc72eb40 | ||
|
|
0d0501cb7b | ||
|
|
1c582a942e | ||
|
|
3c371aa8ee | ||
|
|
c1bc4d2948 | ||
|
|
f9c97b7e5b | ||
|
|
5ff9d4592a | ||
|
|
30adc8d45d | ||
|
|
777ddf434a | ||
|
|
327c7aec30 | ||
|
|
14e29f320d | ||
|
|
cf7d584033 | ||
|
|
61cc7d9c5a | ||
|
|
c4b5df12bb | ||
|
|
977a39f4f7 | ||
|
|
c34710de67 | ||
|
|
5e05236b49 | ||
|
|
b3e53e7243 | ||
|
|
5046270273 | ||
|
|
b8756bc34e | ||
|
|
f26d9f0884 | ||
|
|
8accd6940e | ||
|
|
26ccfef999 | ||
|
|
d8f1b6c59b | ||
|
|
4b6a602a89 | ||
|
|
92bc7d0e16 | ||
|
|
9e3aff0a3a | ||
|
|
e221aae531 | ||
|
|
626121e7bf | ||
|
|
2ba8856343 | ||
|
|
f964cbdb93 | ||
|
|
0f7b2c4298 | ||
|
|
14544e4b87 | ||
|
|
1d5aa38ae4 | ||
|
|
416370a627 | ||
|
|
2c7d683ae3 | ||
|
|
b6ef1fab0e | ||
|
|
bf859859d6 | ||
|
|
a635ec2345 | ||
|
|
ae75004cee | ||
|
|
13ce9ac836 | ||
|
|
5264e41db3 | ||
|
|
5f75ebbbbb | ||
|
|
10da70307a | ||
|
|
cfe6fa6c91 | ||
|
|
ae13be2d17 | ||
|
|
3880b42d18 | ||
|
|
9bead42dbc | ||
|
|
2da043f04d | ||
|
|
de985bad18 | ||
|
|
be8e5aa307 | ||
|
|
94bef1c705 | ||
|
|
99865d9e9a | ||
|
|
550173aaf5 | ||
|
|
f259db3596 | ||
|
|
2b0212af49 | ||
|
|
dfe0badf19 | ||
|
|
d6e10e216e | ||
|
|
9d40840299 | ||
|
|
113bcd7b68 | ||
|
|
d0ae67503c | ||
|
|
441eb4f4a5 | ||
|
|
bab05ff607 | ||
|
|
f552c1796a | ||
|
|
21cdbb41a3 | ||
|
|
1241014a46 | ||
|
|
40d340021c | ||
|
|
cdd5516f33 | ||
|
|
19249d78fb | ||
|
|
d6eb46cf11 | ||
|
|
3671edbcff | ||
|
|
a3277a245c | ||
|
|
d1e09da084 | ||
|
|
c001a91d15 | ||
|
|
0af553da72 | ||
|
|
e9e68abb33 | ||
|
|
c68fbfcb2d | ||
|
|
d1858de7a0 | ||
|
|
9aa34ada57 | ||
|
|
e8ff6b153e | ||
|
|
5ecb46b341 | ||
|
|
dcdbe3eb6c | ||
|
|
2f8881c010 | ||
|
|
995ffc629b | ||
|
|
b3ebe4de3c | ||
|
|
4bf1e85e6b | ||
|
|
0b0bc81710 | ||
|
|
1945dec81f | ||
|
|
e3bfb01411 | ||
|
|
dfbbca423b | ||
|
|
0797a002ca | ||
|
|
53ab2042fd | ||
|
|
50878901ba | ||
|
|
49beb67dab | ||
|
|
e152662687 | ||
|
|
13279917d4 | ||
|
|
85112e7f8f | ||
|
|
09f7f57eea | ||
|
|
f19c7fc5c3 | ||
|
|
8c5fcf41e3 | ||
|
|
58d6b899e2 | ||
|
|
964d81ff01 | ||
|
|
a7777ff485 | ||
|
|
72a3d75e8f | ||
|
|
ca977f4b87 | ||
|
|
9308dee0a1 | ||
|
|
10e362d098 | ||
|
|
b420962377 | ||
|
|
cca5301b88 | ||
|
|
eeb6be5422 | ||
|
|
a6b52e44f2 | ||
|
|
9edebbba4e | ||
|
|
cb1d4164e7 | ||
|
|
6c408b736c | ||
|
|
c272e4afbf | ||
|
|
e374bc130d | ||
|
|
57f73f1b6a | ||
|
|
2d35f937de | ||
|
|
4dd4893d7d | ||
|
|
ef962c43af | ||
|
|
290e366ae9 | ||
|
|
c98273387c | ||
|
|
2eab150563 | ||
|
|
fdaee9a5ce | ||
|
|
71a0240166 | ||
|
|
a2be88a21d | ||
|
|
907425df55 | ||
|
|
764968ab38 | ||
|
|
757e959eb2 | ||
|
|
fa7f9b77ab | ||
|
|
eeff1784e1 | ||
|
|
e05cd940d6 | ||
|
|
f6a13f6f23 | ||
|
|
eba8e1315e | ||
|
|
6e36ebbf84 | ||
|
|
32218a6f8c | ||
|
|
0ae53f4139 | ||
|
|
46df2c9b91 | ||
|
|
f4aedce96c | ||
|
|
539247aacf | ||
|
|
dad4f54eec | ||
|
|
df6712cfb3 | ||
|
|
1a3dcdb830 | ||
|
|
8c0166f459 | ||
|
|
fdf68405a4 | ||
|
|
be6f4319ff | ||
|
|
2acc474ccb | ||
|
|
4b3d66c793 | ||
|
|
49dbbbbcdf | ||
|
|
6afd34727f | ||
|
|
066c09a6ea | ||
|
|
28921cb8e8 | ||
|
|
2071265fea | ||
|
|
3fb3f11fc8 | ||
|
|
b7ae725c5e | ||
|
|
bd96edd2b9 | ||
|
|
aa94f049c1 | ||
|
|
c1d36e4953 | ||
|
|
4cfb686d2b | ||
|
|
d5769b3bfb | ||
|
|
066417d3f0 | ||
|
|
29a287ee82 | ||
|
|
d75c1b829b | ||
|
|
696d77c3ce | ||
|
|
5d85d0990c | ||
|
|
076e1a81a5 | ||
|
|
fc2e4083b0 | ||
|
|
1d99f8a3c2 | ||
|
|
d33672cffe | ||
|
|
ba6e5813e6 | ||
|
|
a6da7ef8af | ||
|
|
db7c5fbf2e | ||
|
|
52474e479d | ||
|
|
b41b57ebb2 | ||
|
|
647800c563 | ||
|
|
3a8bb4c153 | ||
|
|
c2acf96306 | ||
|
|
f8bdc7be62 | ||
|
|
0503eb69ce | ||
|
|
85e77fb797 | ||
|
|
3327dd641d | ||
|
|
c596aaefcf | ||
|
|
4d4b72ba38 | ||
|
|
d7a0a2cd1a | ||
|
|
0ddbb3a1dc | ||
|
|
3303041c92 | ||
|
|
27c5f364a8 | ||
|
|
000104bc3b | ||
|
|
8fd9cfa1f2 | ||
|
|
17d5a4f51f | ||
|
|
d68a25e32e | ||
|
|
154ccbe503 | ||
|
|
6c5ade08d9 | ||
|
|
1b8001b8b8 | ||
|
|
c4d6fb4b1e | ||
|
|
65fd674f50 | ||
|
|
35cd751adc | ||
|
|
ff5e4dbbb0 | ||
|
|
df89ccc191 | ||
|
|
60334f9e02 | ||
|
|
0f707d2b53 | ||
|
|
2317913b71 | ||
|
|
359058cecc | ||
|
|
45330e3819 | ||
|
|
17da87d3cd | ||
|
|
8b9f6cf868 | ||
|
|
4c39e46a3b | ||
|
|
43858a3197 | ||
|
|
3cb7a3e642 | ||
|
|
baa581b814 | ||
|
|
fb7ef8dacd | ||
|
|
1161b6788e | ||
|
|
76714dc628 | ||
|
|
af93729031 | ||
|
|
262776d8d8 | ||
|
|
86d3c0cc0f | ||
|
|
a541820aa8 | ||
|
|
0974ecccd6 | ||
|
|
5ec6353a60 | ||
|
|
9e67ec68ac | ||
|
|
ffd4db5ae4 | ||
|
|
ac183948d6 | ||
|
|
0032daf2a3 | ||
|
|
5eba069b1d | ||
|
|
2b487c9467 | ||
|
|
b9eac96cdc | ||
|
|
1253bbf7ae | ||
|
|
61e3ad89e9 | ||
|
|
fc7f9ebada | ||
|
|
0302138f2f | ||
|
|
c7056d1b20 | ||
|
|
acc36fe117 | ||
|
|
cd3846c8ce | ||
|
|
fd3b5a16b1 | ||
|
|
82169e69fc | ||
|
|
aecf146909 | ||
|
|
2b26b2e611 | ||
|
|
d2710e9d2e | ||
|
|
3700793a2f | ||
|
|
21d5eb84ab | ||
|
|
46a58afd9e | ||
|
|
3cc295e997 | ||
|
|
2948820579 | ||
|
|
e0c30a7e8b | ||
|
|
441f964654 | ||
|
|
2c1fd570f8 | ||
|
|
7c23720920 | ||
|
|
fb485d25a0 | ||
|
|
a08d1b248f | ||
|
|
dc682155de | ||
|
|
e092f79946 | ||
|
|
c2b0dab7ef | ||
|
|
b257bebf9e | ||
|
|
bf49a7679a | ||
|
|
469d9f8a4a | ||
|
|
41e10b22fa | ||
|
|
96d346222f | ||
|
|
2b47426be8 | ||
|
|
aa2a30e96b | ||
|
|
540ddd4e6a | ||
|
|
2659ca1ab4 | ||
|
|
24490bca19 | ||
|
|
73a0ad41c7 |
@@ -1,6 +1,16 @@
|
||||
{
|
||||
"gitSiteUrl": "https://www.github.com/tauri-apps/tauri/",
|
||||
"timeout": 3600000,
|
||||
"changeTags": {
|
||||
"feat": "New Features",
|
||||
"enhance": "Enhancements",
|
||||
"bug": "Bug Fixes",
|
||||
"pref": "Performance Improvements",
|
||||
"changes": "What's Changed",
|
||||
"sec": "Security fixes",
|
||||
"deps": "Dependencies",
|
||||
"breaking": "Breaking Changes"
|
||||
},
|
||||
"defaultChangeTag": "changes",
|
||||
"pkgManagers": {
|
||||
"rust": {
|
||||
"errorOnVersionRange": "^2.0.0-0",
|
||||
@@ -62,7 +72,7 @@
|
||||
],
|
||||
"assets": [
|
||||
{
|
||||
"path": "${ pkg.path }/target/package/${ pkg.pkg }-${ pkgFile.version }.crate",
|
||||
"path": "./target/package/${ pkg.pkg }-${ pkgFile.version }.crate",
|
||||
"name": "${ pkg.pkg }-${ pkgFile.version }.crate"
|
||||
}
|
||||
]
|
||||
@@ -123,13 +133,13 @@
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"api": {
|
||||
"@tauri-apps/api": {
|
||||
"path": "./tooling/api",
|
||||
"manager": "javascript",
|
||||
"assets": [
|
||||
{
|
||||
"path": "./tooling/api/dist/tauri-apps-api-${ pkgFile.version }.tgz",
|
||||
"name": "api-${ pkgFile.version }.tgz"
|
||||
"name": "tauri-apps-api-${ pkgFile.version }.tgz"
|
||||
}
|
||||
],
|
||||
"prepublish": [
|
||||
@@ -231,11 +241,11 @@
|
||||
],
|
||||
"postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }"
|
||||
},
|
||||
"cli.js": {
|
||||
"@tauri-apps/cli": {
|
||||
"path": "./tooling/cli/node",
|
||||
"manager": "javascript",
|
||||
"getPublishedVersion": "node ../../../.scripts/covector/package-latest-version.js npm ${ pkgFile.pkg.name } ${ pkgFile.pkg.version }",
|
||||
"dependencies": ["cli.rs"],
|
||||
"dependencies": ["tauri-cli"],
|
||||
"postversion": [
|
||||
"node ../../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }",
|
||||
"cargo build --manifest-path ../../../core/tauri-config-schema/Cargo.toml"
|
||||
@@ -244,7 +254,7 @@
|
||||
"publish": [],
|
||||
"postpublish": []
|
||||
},
|
||||
"cli.rs": {
|
||||
"tauri-cli": {
|
||||
"path": "./tooling/cli",
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-bundler", "tauri-utils"],
|
||||
@@ -261,7 +271,8 @@
|
||||
},
|
||||
"tauri-driver": {
|
||||
"path": "./tooling/webdriver",
|
||||
"manager": "rust"
|
||||
"manager": "rust",
|
||||
"postversion": "cargo check"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'tauri-bundler': 'patch'
|
||||
---
|
||||
|
||||
Correctly escape XML for resource files in WiX bundler.
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
'tauri-bundler': 'patch'
|
||||
---
|
||||
|
||||
Added the following languages to the NSIS bundler:
|
||||
|
||||
- `Spanish`
|
||||
- `SpanishInternational`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'tauri-bundler': 'patch'
|
||||
---
|
||||
|
||||
Correctly escape arguments in NSIS script to fix bundling apps that use non-default WebView2 install modes.
|
||||
@@ -1,31 +1,44 @@
|
||||
# Changes
|
||||
|
||||
##### via https://github.com/jbolda/covector
|
||||
|
||||
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 that it represents the overall change for organizational purposes.
|
||||
|
||||
When you select the version bump required, you do _not_ need to consider dependencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process.
|
||||
|
||||
Use the following format:
|
||||
|
||||
```md
|
||||
---
|
||||
"package-a": patch
|
||||
"package-b": patch
|
||||
---
|
||||
|
||||
Change summary goes here
|
||||
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Changes will be designated as a `major`, `minor` or `patch` as further described in [semver](https://semver.org/).
|
||||
|
||||
Given a version number MAJOR.MINOR.PATCH, increment the:
|
||||
|
||||
- MAJOR version when you make incompatible API changes,
|
||||
- MINOR version when you add functionality in a backwards compatible manner, and
|
||||
- PATCH version when you make backwards compatible bug fixes.
|
||||
|
||||
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).
|
||||
# Changes
|
||||
|
||||
##### via https://github.com/jbolda/covector
|
||||
|
||||
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 that it represents the overall change for organizational purposes.
|
||||
|
||||
When you select the version bump required, you do _not_ need to consider dependencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process.
|
||||
|
||||
Use the following format:
|
||||
|
||||
```md
|
||||
---
|
||||
'package-a': patch
|
||||
'package-b': patch
|
||||
---
|
||||
|
||||
Change summary goes here
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Changes will be designated as a `major`, `minor` or `patch` as further described in [semver](https://semver.org/).
|
||||
|
||||
Given a version number MAJOR.MINOR.PATCH, increment the:
|
||||
|
||||
- MAJOR version when you make incompatible API changes,
|
||||
- MINOR version when you add functionality in a backwards compatible manner, and
|
||||
- PATCH version when you make backwards compatible bug fixes.
|
||||
|
||||
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).
|
||||
|
||||
Additionally you could specify a tag for the change file to group it with other changes by prefixing the bump with `:<tag>`, for example:
|
||||
|
||||
```md
|
||||
---
|
||||
'package-a': patch:bug
|
||||
---
|
||||
|
||||
Change summary goes here
|
||||
```
|
||||
|
||||
which will group this change file with other changes that specify the `bug` tag.
|
||||
|
||||
For list of available tags, see the `changeTags` key in [./config.json](./config.json)
|
||||
|
||||
18
.github/CONTRIBUTING.md
vendored
18
.github/CONTRIBUTING.md
vendored
@@ -54,20 +54,20 @@ Some Tauri packages will be automatically built when running one of the examples
|
||||
|
||||
### Packages Overview
|
||||
|
||||
- The JS API (`/tooling/api`) contains JS bindings to the builtin Rust functions in the Rust API.
|
||||
- cli.rs (`/tooling/cli`) is the primary CLI for creating and developing Tauri apps.
|
||||
- cli.js (`/tooling/cli/node`) is a Node.js CLI wrapper for `cli.rs`.
|
||||
- Tauri Bundler (`/tooling/bundler`) is used by the Rust CLI to package executables into installers.
|
||||
- Tauri Core (`/core/tauri`) is the heart of Tauri. It contains the code that starts the app, configures communication between Rust and the Webview, and ties all the other packages together.
|
||||
- The Macros (`/core/tauri-macros`) are used by Tauri Core for various functions.
|
||||
|
||||
### Developing The Node.js CLI (cli.js)
|
||||
|
||||
`cli.js` is a wrapper to `cli.rs` so most changes should be written on the Rust CLI. The `[Tauri repo root]/tooling/cli/node` folder contains only packaging scripts to properly publish the Rust CLI binaries to NPM.
|
||||
- Tauri Bundler (`/tooling/bundler`) is used by the Rust CLI to package executables into installers.
|
||||
- The Rust CLI aka `tauri-cli` (`/tooling/cli`) is the primary CLI for creating and developing Tauri apps.
|
||||
- The JS CLI aka `@tauri-apps/cli` (`/tooling/cli/node`) is a Node.js CLI wrapper for `tauri-cli`.
|
||||
- The JS API aka `@tauri-apps/api` (`/tooling/api`) contains JS bindings to the builtin Rust functions in the Rust API.
|
||||
|
||||
### Developing Tauri Bundler and Rust CLI
|
||||
|
||||
The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli`. If you are using your local copy of cli.js (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package.
|
||||
The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli`. If you are using your local copy of `@tauri-apps/cli` (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package.
|
||||
|
||||
### Developing The Node.js CLI (`@tauri-apps/cli`)
|
||||
|
||||
`@tauri-apps/cli` is a wrapper to `tauri-cli` so most changes should be written on the Rust CLI. The `[Tauri repo root]/tooling/cli/node` folder contains only packaging scripts to properly publish the Rust CLI binaries to NPM.
|
||||
|
||||
### Developing Tauri Core and Related Components (Rust API, Macros, Codegen, and Utils)
|
||||
|
||||
|
||||
45
.github/PULL_REQUEST_TEMPLATE.md
vendored
45
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,30 +1,21 @@
|
||||
<!--
|
||||
Update "[ ]" to "[x]" to check a box
|
||||
Before submitting a PR, please read https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
|
||||
|
||||
Please make sure to read the Pull Request Guidelines: https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
|
||||
1. Give the PR a descriptive title.
|
||||
|
||||
Examples of good title:
|
||||
- fix(windows): fix race condition in event loop
|
||||
- docs: update docstrings
|
||||
- feat: add `Window::set_fullscreen`
|
||||
|
||||
Examples of bad title:
|
||||
- fix #7123
|
||||
- update docs
|
||||
- fix bugs
|
||||
|
||||
2. If there is a related issue, reference it in the PR text, e.g. closes #123.
|
||||
3. If this change requires a new version, then add a change file in `.changes` directory with the appropriate bump, see https://github.com/tauri-apps/tauri/blob/dev/.changes/readme.md
|
||||
4. Ensure that all your commits are signed https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
|
||||
5. Ensure `cargo test` and `cargo clippy` passes.
|
||||
6. Propose your changes as a draft PR if your work is still in progress.
|
||||
-->
|
||||
|
||||
### What kind of change does this PR introduce?
|
||||
<!-- Check at least one. If you are introducing a new binding, you must reference an issue where this binding has been proposed, discussed and approved by the maintainers. -->
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Docs
|
||||
- [ ] New Binding issue #___
|
||||
- [ ] Code style update
|
||||
- [ ] Refactor
|
||||
- [ ] Build-related changes
|
||||
- [ ] Other, please describe:
|
||||
|
||||
### Does this PR introduce a breaking change?
|
||||
<!-- If yes, please describe the impact and migration path for existing applications in an attached issue. -->
|
||||
|
||||
- [ ] Yes, and the changes were approved in issue #___
|
||||
- [ ] No
|
||||
|
||||
### Checklist
|
||||
- [ ] When resolving issues, they are referenced in the PR's title (e.g `fix: remove a typo, closes #___, #___`)
|
||||
- [ ] A change file is added if any packages will require a version bump due to this PR per [the instructions in the readme](https://github.com/tauri-apps/tauri/blob/dev/.changes/readme.md).
|
||||
- [ ] I have added a convincing reason for adding this feature, if necessary
|
||||
|
||||
### Other information
|
||||
|
||||
8
.github/workflows/audit.yml
vendored
8
.github/workflows/audit.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
- cron: '0 0 * * *'
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/audit.yml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/Cargo.toml'
|
||||
- '**/package.json'
|
||||
@@ -33,6 +34,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: yarn audit
|
||||
- name: audit workspace
|
||||
run: yarn audit
|
||||
- name: audit @tauri-apps/api
|
||||
working-directory: tooling/api
|
||||
run: yarn audit
|
||||
- name: audit @tauri-apps/cli
|
||||
working-directory: tooling/cli/node
|
||||
run: yarn audit
|
||||
|
||||
4
.github/workflows/bench.yml
vendored
4
.github/workflows/bench.yml
vendored
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: benches
|
||||
name: bench
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
|
||||
32
.github/workflows/check-change-tags.yml
vendored
Normal file
32
.github/workflows/check-change-tags.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: check change tags
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.changes/*.md'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
list-files: shell
|
||||
filters: |
|
||||
changes:
|
||||
- added|modified: '.changes/*.md'
|
||||
|
||||
- name: check
|
||||
run: node ./.scripts/ci/check-change-tags.js ${{ steps.filter.outputs.changes_files }}
|
||||
if: ${{ steps.filter.outputs.changes == 'true' }}
|
||||
21
.github/workflows/check-generated-files.yml
vendored
21
.github/workflows/check-generated-files.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Check generated files
|
||||
name: check generated files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -13,16 +13,6 @@ on:
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- '.github/workflows/check-generated-files.yml'
|
||||
- 'tooling/api/src/**'
|
||||
- 'core/tauri/scripts/bundle.global.js'
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -42,14 +32,13 @@ jobs:
|
||||
filters: |
|
||||
api:
|
||||
- 'tooling/api/src/**'
|
||||
- 'tooling/api/docs/js-api.json'
|
||||
- 'core/tauri/scripts/bundle.global.js'
|
||||
schema:
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
|
||||
check-api:
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.api == 'true'
|
||||
@@ -60,11 +49,9 @@ jobs:
|
||||
working-directory: tooling/api
|
||||
run: yarn && yarn build
|
||||
- name: check api
|
||||
run: |
|
||||
git restore tooling/api/docs/js-api.json
|
||||
./.scripts/ci/has-diff.sh
|
||||
run: ./.scripts/ci/has-diff.sh
|
||||
|
||||
check-schema:
|
||||
schema:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.schema == 'true'
|
||||
|
||||
4
.github/workflows/check-license-header.yml
vendored
4
.github/workflows/check-license-header.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Check generated files
|
||||
name: check license headers
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -25,4 +25,4 @@ jobs:
|
||||
- added: '**'
|
||||
- name: check header license on new files
|
||||
if: ${{ steps.filter.outputs.added == 'true' }}
|
||||
run: node check-license-header.js ${{ steps.filter.outputs.added_files }}
|
||||
run: node ./.scripts/ci/check-license-header.js ${{ steps.filter.outputs.added_files }}
|
||||
|
||||
235
.github/workflows/covector-version-or-publish-v1.yml
vendored
Normal file
235
.github/workflows/covector-version-or-publish-v1.yml
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: covector version or publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 1.x
|
||||
|
||||
jobs:
|
||||
msrv-list:
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- {
|
||||
target: x86_64-pc-windows-msvc,
|
||||
os: windows-latest,
|
||||
toolchain: '1.61.0'
|
||||
}
|
||||
- {
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-latest,
|
||||
toolchain: '1.60.0'
|
||||
}
|
||||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
os: macos-13,
|
||||
toolchain: '1.60.0'
|
||||
}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install rust ${{ matrix.platform.toolchain }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.platform.toolchain }}
|
||||
target: ${{ matrix.platform.target }}
|
||||
override: true
|
||||
default: true
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: contains(matrix.platform.target, 'unknown-linux')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: delete lockfile
|
||||
run: rm Cargo.lock
|
||||
|
||||
- name: Downgrade crates with MSRV conflict
|
||||
# The --precise flag can only be used once per invocation.
|
||||
run: |
|
||||
cargo update -p system-deps:6.2.2 --precise 6.1.1
|
||||
cargo update -p toml:0.7.8 --precise 0.7.3
|
||||
cargo update -p toml_edit:0.19.15 --precise 0.19.8
|
||||
cargo update -p embed-resource --precise 2.3.0
|
||||
cargo update -p notify-rust --precise 4.10.0
|
||||
cargo update -p toml_datetime --precise 0.6.1
|
||||
cargo update -p serde_spanned --precise 0.6.1
|
||||
cargo update -p winnow --precise 0.4.1
|
||||
cargo update -p plist --precise 1.5.1
|
||||
cargo update -p time --precise 0.3.15
|
||||
cargo update -p ignore --precise 0.4.18
|
||||
cargo update -p raw-window-handle --precise 0.5.0
|
||||
cargo update -p cargo_toml:0.15.3 --precise 0.15.2
|
||||
cargo update -p zbus --precise 3.13.0
|
||||
cargo update -p zbus_names --precise 2.5.0
|
||||
cargo update -p colored --precise 2.0.2
|
||||
cargo update -p arboard --precise 3.2.1
|
||||
cargo update -p tempfile --precise 3.6.0
|
||||
cargo update -p serde_with:3.8.1 --precise 3.0.0
|
||||
cargo update -p tokio --precise 1.29.0
|
||||
cargo update -p flate2 --precise 1.0.26
|
||||
cargo update -p h2 --precise 0.3.20
|
||||
cargo update -p reqwest --precise 0.11.18
|
||||
cargo update -p bstr --precise 1.6.2
|
||||
cargo update -p cfg-expr:0.15.8 --precise 0.15.4
|
||||
cargo update -p memchr --precise 2.6.2
|
||||
cargo update -p async-executor --precise 1.5.1
|
||||
cargo update -p proptest --precise 1.2.0
|
||||
cargo update -p regex --precise 1.9.6
|
||||
cargo update -p bstr --precise 1.6.2
|
||||
cargo update -p backtrace --precise 0.3.68
|
||||
cargo update -p blocking --precise 1.4.1
|
||||
cargo update -p ignore --precise 0.4.18
|
||||
cargo update -p globset --precise 0.4.13
|
||||
cargo update -p crossbeam-channel --precise 0.5.8
|
||||
cargo update -p crossbeam-utils --precise 0.8.16
|
||||
cargo update -p image --precise 0.24.4
|
||||
cargo update -p async-process --precise 1.7.0
|
||||
cargo update -p is-terminal --precise 0.4.7
|
||||
cargo update -p tar --precise 0.4.39
|
||||
cargo update -p serde_json --precise 1.0.97
|
||||
cargo update -p petgraph --precise 0.6.3
|
||||
cargo update -p os_str_bytes --precise 6.5.1
|
||||
cargo update -p thread_local --precise 1.1.7
|
||||
cargo update -p cc --precise 1.0.94
|
||||
cargo update -p home --precise 0.5.5
|
||||
cargo update -p tree_magic_mini --precise 3.0.3
|
||||
cargo update -p tokio-test --precise 0.4.3
|
||||
cargo update -p tokio-stream --precise 0.1.14
|
||||
cargo update -p tokio-util --precise 0.7.10
|
||||
|
||||
- name: test build
|
||||
run: cargo check --target ${{ matrix.platform.target }} --features tracing,compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test
|
||||
|
||||
run-integration-tests:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
needs: msrv-list
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, macos-13, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev libfuse2
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: |
|
||||
core -> ../target
|
||||
tooling/cli
|
||||
|
||||
- name: build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: run integration tests
|
||||
run: cargo test --test '*' -- --ignored
|
||||
|
||||
- name: run CLI tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
cd ./tooling/cli/node
|
||||
yarn
|
||||
yarn build
|
||||
yarn test
|
||||
|
||||
version-or-publish:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 65
|
||||
outputs:
|
||||
change: ${{ steps.covector.outputs.change }}
|
||||
commandRan: ${{ steps.covector.outputs.commandRan }}
|
||||
successfulPublish: ${{ steps.covector.outputs.successfulPublish }}
|
||||
needs:
|
||||
- run-integration-tests
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
|
||||
- name: cargo login
|
||||
run: cargo login ${{ secrets.ORG_CRATES_IO_TOKEN }}
|
||||
- name: git config
|
||||
run: |
|
||||
git config --global user.name "${{ github.event.pusher.name }}"
|
||||
git config --global user.email "${{ github.event.pusher.email }}"
|
||||
|
||||
- name: covector version or publish (publish when no change files present)
|
||||
uses: jbolda/covector/packages/action@covector-v0
|
||||
id: covector
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
|
||||
CARGO_AUDIT_OPTIONS: ${{ secrets.CARGO_AUDIT_OPTIONS }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
command: 'version-or-publish'
|
||||
createRelease: true
|
||||
|
||||
- name: Create Pull Request With Versions Bumped
|
||||
if: steps.covector.outputs.commandRan == 'version'
|
||||
uses: tauri-apps/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: release/version-updates-v1
|
||||
title: Apply Version Updates From Current Changes (v1)
|
||||
commit-message: 'apply version updates'
|
||||
labels: 'version updates'
|
||||
body: ${{ steps.covector.outputs.change }}
|
||||
|
||||
- name: Trigger doc update
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
steps.covector.outputs.packagesPublished != ''
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri-docs
|
||||
event-type: update-docs
|
||||
|
||||
- name: Trigger `@tauri-apps/cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
event-type: publish-js-cli
|
||||
client-payload: >-
|
||||
{"releaseId": "${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}" }
|
||||
|
||||
- name: Trigger `tauri-cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'tauri-cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
event-type: publish-clirs
|
||||
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: version or publish
|
||||
name: covector version or publish
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 16
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
@@ -115,23 +115,20 @@ jobs:
|
||||
repository: tauri-apps/tauri-docs
|
||||
event-type: update-docs
|
||||
|
||||
- name: Trigger cli.js publishing workflow
|
||||
- name: Trigger `@tauri-apps/cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'cli.rs')
|
||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri
|
||||
event-type: publish-clijs
|
||||
client-payload: '{"releaseId": "${{ steps.covector.outputs.cli.js-releaseId }}" }'
|
||||
event-type: publish-js-cli
|
||||
client-payload: >-
|
||||
{"releaseId": "${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}" }
|
||||
|
||||
- name: Trigger cli.rs publishing workflow
|
||||
- name: Trigger `tauri-cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'cli.rs')
|
||||
contains(steps.covector.outputs.packagesPublished, 'tauri-cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri
|
||||
event-type: publish-clirs
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: cli clippy and fmt check
|
||||
name: lint cli
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/lint-fmt-cli.yml'
|
||||
- '.github/workflows/lint-cli.yml'
|
||||
- 'tooling/cli/**'
|
||||
|
||||
env:
|
||||
@@ -23,7 +23,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt_check:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
command: fmt
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --all -- --check
|
||||
|
||||
cli_clippy_check:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -2,16 +2,16 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: core clippy and fmt check
|
||||
name: lint core
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/lint-fmt-core.yml'
|
||||
- '.github/workflows/lint-core.yml'
|
||||
- 'core/**'
|
||||
- '!core/tauri/scripts/**'
|
||||
- 'examples/**'
|
||||
@@ -25,7 +25,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt_check:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -43,14 +43,14 @@ jobs:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
core_clippy_check:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
clippy:
|
||||
- { args: '', key: 'empty' }
|
||||
- {
|
||||
args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart',
|
||||
args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test',
|
||||
key: 'all'
|
||||
}
|
||||
- { args: '--features custom-protocol', key: 'custom-protocol' }
|
||||
33
.github/workflows/lint-js.yml
vendored
33
.github/workflows/lint-js.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: api and cli.js lint check
|
||||
name: lint js
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -16,32 +16,45 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
eslint-check:
|
||||
eslint-cli:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: 16
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
- name: install cli.js deps via yarn
|
||||
cache-dependency-path: tooling/cli/node/yarn.lock
|
||||
- name: install deps via yarn
|
||||
working-directory: ./tooling/cli/node/
|
||||
run: yarn
|
||||
# nothing to lint
|
||||
#- name: run cli.js lint
|
||||
#- name: run lint
|
||||
# working-directory: ./tooling/cli/node/
|
||||
# run: yarn lint
|
||||
- name: run cli.js format
|
||||
- name: run format
|
||||
working-directory: ./tooling/cli/node/
|
||||
run: yarn format:check
|
||||
|
||||
- name: install api deps via yarn
|
||||
eslint-api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/api/yarn.lock
|
||||
|
||||
- name: install deps via yarn
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn
|
||||
- name: run api lint
|
||||
- name: run ts:check
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn ts:check
|
||||
- name: run lint
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn lint
|
||||
- name: run api format
|
||||
- name: run format
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn format:check
|
||||
|
||||
52
.github/workflows/publish-cli-js.yml
vendored
52
.github/workflows/publish-cli-js.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: publish cli.js
|
||||
name: publish `@tauri-apps/cli`
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
APP_NAME: cli
|
||||
@@ -11,10 +11,10 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
releaseId:
|
||||
description: 'ID of the cli.js release'
|
||||
description: 'ID of the `@tauri-apps/cli` release'
|
||||
required: true
|
||||
repository_dispatch:
|
||||
types: [publish-clijs]
|
||||
types: [publish-js-cli]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -30,41 +30,45 @@ jobs:
|
||||
target: x86_64-apple-darwin
|
||||
architecture: x64
|
||||
build: |
|
||||
yarn build:release --features rustls
|
||||
yarn build:release --target=x86_64-apple-darwin
|
||||
strip -x *.node
|
||||
- host: windows-latest
|
||||
build: yarn build:release --features rustls
|
||||
build: yarn build:release
|
||||
target: x86_64-pc-windows-msvc
|
||||
architecture: x64
|
||||
- host: windows-latest
|
||||
build: yarn build:release --features rustls --target i686-pc-windows-msvc
|
||||
build: yarn build:release --target i686-pc-windows-msvc
|
||||
target: i686-pc-windows-msvc
|
||||
architecture: x64
|
||||
- host: windows-latest
|
||||
architecture: x64
|
||||
target: aarch64-pc-windows-msvc
|
||||
build: yarn build:release --target aarch64-pc-windows-msvc --features native-tls,native-tls-vendored --cargo-flags="--no-default-features"
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
yarn build:release --features rustls --target x86_64-unknown-linux-gnu
|
||||
yarn build:release --target x86_64-unknown-linux-gnu
|
||||
strip *.node
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-musl
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
yarn build:release --features rustls
|
||||
yarn build:release
|
||||
strip *.node
|
||||
- host: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
build: |
|
||||
yarn build:release --features rustls --target=aarch64-apple-darwin
|
||||
yarn build:release --target=aarch64-apple-darwin
|
||||
strip -x *.node
|
||||
- host: ubuntu-20.04
|
||||
target: aarch64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
yarn build:release --features rustls --target aarch64-unknown-linux-gnu
|
||||
yarn build:release --target aarch64-unknown-linux-gnu
|
||||
aarch64-unknown-linux-gnu-strip *.node
|
||||
- host: ubuntu-20.04
|
||||
architecture: x64
|
||||
@@ -73,7 +77,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
|
||||
build: |
|
||||
yarn build:release --features rustls --target=armv7-unknown-linux-gnueabihf
|
||||
yarn build:release --target=armv7-unknown-linux-gnueabihf
|
||||
arm-linux-gnueabihf-strip *.node
|
||||
- host: ubuntu-20.04
|
||||
architecture: x64
|
||||
@@ -82,12 +86,8 @@ jobs:
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
rustup target add aarch64-unknown-linux-musl
|
||||
yarn build:release --features rustls --target aarch64-unknown-linux-musl
|
||||
yarn build:release --target aarch64-unknown-linux-musl
|
||||
/aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node
|
||||
#- host: windows-latest
|
||||
# architecture: x64
|
||||
# target: aarch64-pc-windows-msvc
|
||||
# build: yarn build:release --features rustls --target aarch64-pc-windows-msvc
|
||||
name: stable - ${{ matrix.settings.target }} - node@16
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
@@ -158,7 +158,7 @@ jobs:
|
||||
# usesh: true
|
||||
# mem: 3000
|
||||
# prepare: |
|
||||
# pkg install -y curl node14 python2
|
||||
# pkg install -y curl node16 python2
|
||||
# curl -qL https://www.npmjs.com/install.sh | sh
|
||||
# npm install -g yarn
|
||||
# curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
@@ -179,7 +179,7 @@ jobs:
|
||||
# freebsd-version
|
||||
# cd ./tooling/cli/node/
|
||||
# yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
# yarn build:release --features rustls
|
||||
# yarn build:release
|
||||
# strip -x *.node
|
||||
# rm -rf node_modules
|
||||
# rm -rf ../target
|
||||
@@ -198,13 +198,13 @@ jobs:
|
||||
matrix:
|
||||
settings:
|
||||
- host: macos-latest
|
||||
target: 'x86_64-apple-darwin'
|
||||
target: 'aarch64-apple-darwin'
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -235,9 +235,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -272,9 +272,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
@@ -297,14 +297,10 @@ jobs:
|
||||
- name: List packages
|
||||
run: ls -R .
|
||||
shell: bash
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
apk add openssl-dev musl-dev glib-dev cairo-dev pkgconfig gdk-pixbuf-dev webkit2gtk-dev curl gtk+3.0-dev
|
||||
- name: Setup and run tests
|
||||
run: |
|
||||
yarn tauri --help
|
||||
ls -la
|
||||
# TODO: fix this test: https://github.com/tauri-apps/tauri/runs/5145729140?check_suite_focus=true#step:9:704
|
||||
#- name: Setup and run tests
|
||||
# run: |
|
||||
# rustup install stable
|
||||
@@ -319,9 +315,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
image:
|
||||
- ghcr.io/napi-rs/napi-rs/nodejs:aarch64-16
|
||||
- ghcr.io/napi-rs/napi-rs/nodejs:armhf-16
|
||||
@@ -379,7 +375,7 @@ jobs:
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
check-latest: true
|
||||
cache: yarn
|
||||
cache-dependency-path: 'tooling/cli/node/yarn.lock'
|
||||
|
||||
14
.github/workflows/publish-cli-rs.yml
vendored
14
.github/workflows/publish-cli-rs.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: publish cli.rs
|
||||
name: publish `tauri-cli`
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
on:
|
||||
@@ -21,15 +21,23 @@ jobs:
|
||||
- os: ubuntu-20.04
|
||||
rust_target: x86_64-unknown-linux-gnu
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: macos-latest
|
||||
rust_target: x86_64-apple-darwin
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: macos-latest
|
||||
rust_target: aarch64-apple-darwin
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: windows-latest
|
||||
rust_target: x86_64-pc-windows-msvc
|
||||
ext: '.exe'
|
||||
args: ''
|
||||
- os: windows-latest
|
||||
rust_target: aarch64-pc-windows-msvc
|
||||
ext: '.exe'
|
||||
args: '--no-default-features --features native-tls,native-tls-vendored'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -54,7 +62,7 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --release
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --release ${{ matrix.config.args }}
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -85,7 +93,7 @@ jobs:
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@50195ba7f6f93d1ac97ba8332a178e008ad176aa
|
||||
with:
|
||||
tag_name: cli.rs-v${{ env.CLI_VERSION }}
|
||||
tag_name: tauri-cli-v${{ env.CLI_VERSION }}
|
||||
files: |
|
||||
outputs/cargo-tauri-*.zip
|
||||
outputs/cargo-tauri-*.tgz
|
||||
|
||||
10
.github/workflows/test-cli-js.yml
vendored
10
.github/workflows/test-cli-js.yml
vendored
@@ -2,17 +2,17 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test cli.js
|
||||
name: test `@tauri-apps/cli`
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-cli-js.yml'
|
||||
# currently cli.js only tests the template
|
||||
# currently` @tauri-apps/cli` only tests the template
|
||||
- 'tooling/cli/templates/app/**'
|
||||
|
||||
env:
|
||||
@@ -24,7 +24,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-js-cli:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 16
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/cli/node/yarn.lock
|
||||
|
||||
|
||||
10
.github/workflows/test-cli-rs.yml
vendored
10
.github/workflows/test-cli-rs.yml
vendored
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test cli.rs
|
||||
name: test `tauri-cli`
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-cli-rs.yml'
|
||||
@@ -23,7 +23,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-cli:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -50,8 +50,8 @@ jobs:
|
||||
with:
|
||||
workspaces: tooling/cli
|
||||
|
||||
- name: build CLI
|
||||
- name: test CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
command: test
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
8
.github/workflows/test-core.yml
vendored
8
.github/workflows/test-core.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-core.yml'
|
||||
@@ -24,7 +24,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-core:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
|
||||
strategy:
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
}
|
||||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
os: macos-latest,
|
||||
os: macos-13,
|
||||
toolchain: '1.60.0'
|
||||
}
|
||||
features:
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
key: api-all
|
||||
}
|
||||
- {
|
||||
args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,
|
||||
args: --features tracing,compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test,
|
||||
key: all
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test bundler
|
||||
name: test and lint bundler
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-bundler.yml'
|
||||
@@ -23,7 +23,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-tauri-bundler:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
cd ./tooling/bundler
|
||||
cargo test
|
||||
|
||||
fmt_check:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
command: fmt
|
||||
args: --manifest-path ./tooling/bundler/Cargo.toml --all -- --check
|
||||
|
||||
clippy-check:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: updater test artifacts
|
||||
name: test updater artifacts
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/artifacts-updater.yml'
|
||||
- '.github/workflows/test-updater-artifacts.yml'
|
||||
- 'examples/updater/**'
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -21,7 +21,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-artifacts:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
core -> ../target
|
||||
tooling/cli
|
||||
|
||||
- name: build and install cli.rs
|
||||
- name: build and install `tauri-cli`
|
||||
run: cargo install --path tooling/cli --force
|
||||
- name: Check whether code signing should be enabled
|
||||
id: enablecodesigning
|
||||
2
.github/workflows/udeps.yml
vendored
2
.github/workflows/udeps.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -73,7 +73,7 @@ TODO.md
|
||||
target
|
||||
|
||||
# lock for libs
|
||||
/Cargo.lock
|
||||
#/Cargo.lock Committed to prevent msrv checks from failing
|
||||
/tooling/bench/tests/Cargo.lock
|
||||
/yarn.lock
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ if [ -z "$(git diff --name-only tooling/api)" ]; then
|
||||
else
|
||||
cd tooling/api
|
||||
yarn format
|
||||
yarn lint-fix
|
||||
yarn lint:fix
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
if [ -z "$(git diff --name-only tooling/cli/node)" ]; then
|
||||
echo "skipping cli.js - no changes detected"
|
||||
echo "skipping \`@tauri-apps/cli\` - no changes detected"
|
||||
else
|
||||
cd tooling/cli/node
|
||||
yarn format
|
||||
|
||||
@@ -9,5 +9,4 @@ dist
|
||||
/tooling/cli/templates
|
||||
/tooling/cli/node
|
||||
/tooling/cli/schema.json
|
||||
/tooling/api/docs/js-api.json
|
||||
/core/tauri-config-schema/schema.json
|
||||
|
||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
semi: false,
|
||||
trailingComma: 'none'
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
79
.scripts/ci/check-change-tags.js
Normal file
79
.scripts/ci/check-change-tags.js
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const ignorePackages = [
|
||||
'tauri-macros',
|
||||
'tauri-codegen',
|
||||
'tauri-runtime',
|
||||
'tauri-runtime-wry',
|
||||
'tauri-driver'
|
||||
]
|
||||
|
||||
const covectorConfig = JSON.parse(
|
||||
fs.readFileSync('.changes/config.json', 'utf8')
|
||||
)
|
||||
const tags = Object.keys(covectorConfig.changeTags)
|
||||
|
||||
const missingTagsFiles = {}
|
||||
const unknownTagsFiles = {}
|
||||
|
||||
function checkChangeFiles(changeFiles) {
|
||||
for (const file of changeFiles) {
|
||||
const content = fs.readFileSync(file, 'utf8')
|
||||
const [frontMatter] = /^---[\s\S.]*---\n/i.exec(content)
|
||||
const packages = frontMatter
|
||||
.split('\n')
|
||||
.filter((l) => !(l === '---' || !l))
|
||||
.map((l) => l.replace(/('|")/g, '').split(':'))
|
||||
|
||||
for (const [package, _, tag] of packages) {
|
||||
if (!tag) {
|
||||
if (ignorePackages.includes(package)) continue
|
||||
|
||||
if (!missingTagsFiles[file]) missingTagsFiles[file] = []
|
||||
missingTagsFiles[file].push(package)
|
||||
} else if (!tags.includes(tag)) {
|
||||
if (!unknownTagsFiles[file]) unknownTagsFiles[file] = []
|
||||
unknownTagsFiles[file].push({ package, tag })
|
||||
}
|
||||
}
|
||||
}
|
||||
const missingTagsEntries = Object.entries(missingTagsFiles)
|
||||
const unknownTagsEntries = Object.entries(unknownTagsFiles)
|
||||
if (missingTagsEntries.length > 0 || unknownTagsEntries.length > 0) {
|
||||
for (const [file, packages] of missingTagsEntries) {
|
||||
for (const package of packages) {
|
||||
console.error(
|
||||
`Package \`${package}\` is missing a change tag in ${file} `
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (const [file, packages] of unknownTagsEntries) {
|
||||
for (const { package, tag } of packages) {
|
||||
console.error(
|
||||
`Package \`${package}\` has an uknown change tag ${tag} in ${file} `
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
const [_bin, _script, ...files] = process.argv
|
||||
|
||||
if (files.length > 0) {
|
||||
checkChangeFiles(files.filter((f) => f.toLowerCase() !== 'readme.md'))
|
||||
} else {
|
||||
const changeFiles = fs
|
||||
.readdirSync('.changes')
|
||||
.filter((f) => f.endsWith('.md') && f.toLowerCase() !== 'readme.md')
|
||||
.map((p) => path.join('.changes', p))
|
||||
checkChangeFiles(changeFiles)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -9,13 +11,22 @@ const readline = require('readline')
|
||||
const header = `Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
SPDX-License-Identifier: MIT`
|
||||
const bundlerLicense = '// Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>'
|
||||
const bundlerLicense =
|
||||
'// Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>'
|
||||
|
||||
const extensions = ['.rs', '.js', '.ts', '.yml']
|
||||
const ignore = ['target', 'templates', 'node_modules', 'gen', 'dist', 'bundle.js', 'bundle.global.js']
|
||||
const ignore = [
|
||||
'target',
|
||||
'templates',
|
||||
'node_modules',
|
||||
'gen',
|
||||
'dist',
|
||||
'bundle.js',
|
||||
'bundle.global.js'
|
||||
]
|
||||
|
||||
async function checkFile(file) {
|
||||
if (extensions.some(e => file.endsWith(e))) {
|
||||
if (extensions.some((e) => file.endsWith(e))) {
|
||||
const fileStream = fs.createReadStream(file)
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
@@ -26,7 +37,11 @@ async function checkFile(file) {
|
||||
let i = 0
|
||||
for await (let line of rl) {
|
||||
// ignore empty lines, allow shebang and bundler license
|
||||
if (line.length === 0 || line.startsWith("#!") || line === bundlerLicense) {
|
||||
if (
|
||||
line.length === 0 ||
|
||||
line.startsWith('#!') ||
|
||||
line === bundlerLicense
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -93,7 +108,7 @@ if (files.length > 0) {
|
||||
|
||||
run()
|
||||
} else {
|
||||
check('.').then(missing => {
|
||||
check('.').then((missing) => {
|
||||
if (missing.length > 0) {
|
||||
console.log(missing.join('\n'))
|
||||
process.exit(1)
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if git diff --quiet --ignore-submodules HEAD
|
||||
then
|
||||
echo "working directory is clean"
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
for o in outputs/*; do
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -6,7 +7,7 @@
|
||||
/*
|
||||
This script is solely intended to be run as part of the `covector version` step to
|
||||
keep the `../tooling/cli/metadata.json` up to date with other version bumps. Long term
|
||||
we should look to find a more "rusty way" to import / "pin" a version value in our cli.rs
|
||||
we should look to find a more "rusty way" to import / "pin" a version value in our tauri-cli
|
||||
rust binaries.
|
||||
*/
|
||||
|
||||
@@ -14,7 +15,7 @@ const { readFileSync, writeFileSync } = require('fs')
|
||||
|
||||
const packageNickname = process.argv[2]
|
||||
const filePath =
|
||||
packageNickname === 'cli.js'
|
||||
packageNickname === '@tauri-apps/cli'
|
||||
? `../../../tooling/cli/metadata.json`
|
||||
: `../../tooling/cli/metadata.json`
|
||||
const bump = process.argv[3]
|
||||
@@ -51,9 +52,9 @@ const metadata = JSON.parse(readFileSync(filePath, 'utf-8'))
|
||||
|
||||
// set field version
|
||||
let version
|
||||
if (packageNickname === 'cli.js') {
|
||||
version = inc(metadata[packageNickname].version)
|
||||
metadata[packageNickname].version = version
|
||||
if (packageNickname === '@tauri-apps/cli') {
|
||||
version = inc(metadata['cli.js'].version)
|
||||
metadata['cli.js'].version = version
|
||||
} else {
|
||||
version = inc(metadata[packageNickname])
|
||||
metadata[packageNickname] = version
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
docker build -t aarch64-unknown-linux-gnu:latest --file .docker/cross/aarch64.Dockerfile .docker/cross
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
: Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
: SPDX-License-Identifier: Apache-2.0
|
||||
: SPDX-License-Identifier: MIT
|
||||
|
||||
@ECHO OFF
|
||||
|
||||
REM Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
|
||||
@@ -39,16 +39,16 @@ This is common code that is reused in many places and offers useful utilities li
|
||||
|
||||
|
||||
### Tauri Tooling
|
||||
#### [api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS]
|
||||
#### [@tauri-apps/api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS]
|
||||
A TypeScript library that creates `cjs` and `esm` JavaScript endpoints for you to import into your Frontend framework so that the Webview can call and listen to backend activity. We also ship the pure TypeScript, because for some frameworks this is more optimal. It uses the message passing of webviews to their hosts.
|
||||
|
||||
#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) [RUST / SHELL]
|
||||
The bundler is a library that builds a Tauri App for the platform triple it detects / is told. At the moment it currently supports macOS, Windows and Linux - but in the near future will support mobile platforms as well. May be used outside of Tauri projects.
|
||||
|
||||
#### [cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) [JS]
|
||||
It is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli) using [napi-rs](https://github.com/napi-rs/napi-rs) to produce NPM packages for each platform.
|
||||
#### [@tauri-apps/cli](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) [JS]
|
||||
It is a wrapper around [tauri-cli](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli) using [napi-rs](https://github.com/napi-rs/napi-rs) to produce NPM packages for each platform.
|
||||
|
||||
#### [cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST]
|
||||
#### [tauri-cli](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST]
|
||||
This rust executable provides the full interface to all of the required activities for which the CLI is required. It will run on macOS, Windows, and Linux.
|
||||
|
||||
#### [create-tauri-app](https://github.com/tauri-apps/create-tauri-app) [JS]
|
||||
@@ -67,9 +67,6 @@ Tauri uses WRY as the abstract layer responsible to determine which webview is u
|
||||
|
||||
# Additional tooling
|
||||
|
||||
## [binary-releases](https://github.com/tauri-apps/binary-releases)
|
||||
This is the delivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by cli.js) and rustup binaries (used by the deps install command of cli.js). These artifacts are automatically created on release.
|
||||
|
||||
## [tauri-action](https://github.com/tauri-apps/tauri-action)
|
||||
This is a github workflow that builds tauri binaries for all platforms. It is not the fastest out there, but it gets the job done and is highly configurable. Even allowing you to create a (very basic) tauri app even if tauri is not setup.
|
||||
|
||||
@@ -119,7 +116,7 @@ This will do several things:
|
||||
1. start the JS Framework devserver
|
||||
2. begin the long process of downloading and compiling the rust libraries
|
||||
3. open an application window with devtools enabled
|
||||
4. keep a long-lived console alive
|
||||
4. keep a long-lived console alive
|
||||
|
||||
If you change your HTML/CSS/TS/JS, your framework devserver should give you its best shot at instant hot module reloading and you will see the changes instantly.
|
||||
|
||||
@@ -149,7 +146,7 @@ After some time, the process will end and you can see the results in the `./src-
|
||||
End users will be provided with binaries in ways that are appropriate for their systems. Whether macOS, Linux, or Windows, direct download or store installations - they will be able to follow procedures for installing and removing that they are used to.
|
||||
|
||||
## What does the Updating flow look like?
|
||||
When a new version is ready, the developer publishes the new signed artifacts to a server (that they have configured within `tauri.conf.json`).
|
||||
When a new version is ready, the developer publishes the new signed artifacts to a server (that they have configured within `tauri.conf.json`).
|
||||
|
||||
The application can poll this server to see if there is a new release. When there is a new release, the user is prompted to update. The application update is downloaded, verified (checksum & signature), updated, closed, and restarted.
|
||||
|
||||
|
||||
5736
Cargo.lock
generated
Normal file
5736
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# core
|
||||
"core/tauri",
|
||||
|
||||
16
README.md
16
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
### Tooling
|
||||
|
||||
| Component | Description | Version | Lin | Win | Mac |
|
||||
| --------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ | --- | --- | --- |
|
||||
| [**bundler**](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) | manufacture the final binaries | [](https://crates.io/crates/tauri-bundler) | ✅ | ✅ | ✅ |
|
||||
| [**api.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) | JS API for interaction with Rust backend | [](https://www.npmjs.com/package/@tauri-apps/api) | ✅ | ✅ | ✅ |
|
||||
| [**cli.rs**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) | create, develop and build apps | [](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ |
|
||||
| [**cli.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) | Node.js CLI wrapper for cli.rs | [](https://www.npmjs.com/package/@tauri-apps/cli) | ✅ | ✅ | ✅ |
|
||||
| Component | Description | Version | Lin | Win | Mac |
|
||||
| ------------------------------------------------------------------------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ | --- | --- | --- |
|
||||
| [**bundler**](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) | manufacture the final binaries | [](https://crates.io/crates/tauri-bundler) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-cli**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) | create, develop and build apps | [](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ |
|
||||
| [**@tauri-apps/cli**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) | Node.js CLI wrapper for `tauri-cli` | [](https://www.npmjs.com/package/@tauri-apps/cli) | ✅ | ✅ | ✅ |
|
||||
| [**@tauri-apps/api**](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) | JS API for interaction with Rust backend | [](https://www.npmjs.com/package/@tauri-apps/api) | ✅ | ✅ | ✅ |
|
||||
|
||||
### Utilities and Plugins
|
||||
|
||||
@@ -75,6 +75,8 @@ For **running** Tauri apps we support the below configurations (these are automa
|
||||
- `webkit2gtk`, `gtk3`, `libayatana-appindicator`<sup>1</sup>
|
||||
- Fedora (latest 2 versions) with the following packages installed:
|
||||
- `webkit2gtk3`, `gtk3`, `libappindicator-gtk3`<sup>1</sup>
|
||||
- Void with the following packages installed:
|
||||
- `webkit2gtk`, `gtk+3`, `libappindicator`<sup>1</sup>
|
||||
|
||||
<sup>1</sup> `appindicator` is only required if system trays are used
|
||||
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# Changelog
|
||||
|
||||
## \[1.5.2]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
- Upgraded to `tauri-codegen@1.4.3`
|
||||
|
||||
## \[1.5.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
- Upgraded to `tauri-codegen@1.4.2`
|
||||
|
||||
## \[1.5.0]
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`d1e09da0`](https://www.github.com/tauri-apps/tauri/commit/d1e09da084b849b9e384fc27ed250dd17e72c7a3)([#7918](https://www.github.com/tauri-apps/tauri/pull/7918)) Bump to 1.5 due to tauri-utils dependency bump.
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`5ecb46b3`](https://www.github.com/tauri-apps/tauri/commit/5ecb46b3410afd1b5c82494c1e0a91d5a358c41a)([#7773](https://www.github.com/tauri-apps/tauri/pull/7773)) Automatically set rpath on macOS if frameworks are bundled and copy frameworks to `src-tauri/target/Frameworks` for usage in development.
|
||||
- [`290e366a`](https://www.github.com/tauri-apps/tauri/commit/290e366ae98e9a52b1b43bfd3e285150427ebffa)([#7419](https://www.github.com/tauri-apps/tauri/pull/7419)) Correctly copy the WebView2 runtime in development when `webviewInstallMode` is used instead of `webviewFixedRuntimePath`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-codegen@1.4.1`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`52474e47`](https://www.github.com/tauri-apps/tauri/commit/52474e479d695865299d8c8d868fb98b99731020)([#7141](https://www.github.com/tauri-apps/tauri/pull/7141)) Enhance Cargo features check.
|
||||
- [`af937290`](https://www.github.com/tauri-apps/tauri/commit/af93729031565a69d1fde6cf16bea3b9b6e43a65)([#6676](https://www.github.com/tauri-apps/tauri/pull/6676)) On Windows, set `LegalCopyright` and `FileDescription` file properties on the executable from `tauri.bundle.copyright` and `tauri.bundle.shortDescription`,
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-build"
|
||||
version = "1.3.0"
|
||||
version = "1.5.2"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
@@ -19,16 +19,17 @@ rustdoc-args = [ "--cfg", "doc_cfg" ]
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
quote = { version = "1", optional = true }
|
||||
tauri-codegen = { version = "1.3.0", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
tauri-codegen = { version = "1.4.3", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "1.5.4", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
cargo_toml = "0.15"
|
||||
winnow = "=0.4.1"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
heck = "0.4"
|
||||
json-patch = "1.0"
|
||||
heck = "0.5"
|
||||
json-patch = "1.2"
|
||||
tauri-winres = "0.1"
|
||||
semver = "1"
|
||||
walkdir = "2"
|
||||
dirs-next = "2"
|
||||
|
||||
[features]
|
||||
codegen = [ "tauri-codegen", "quote" ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
211
core/tauri-build/src/allowlist.rs
Normal file
211
core/tauri-build/src/allowlist.rs
Normal file
@@ -0,0 +1,211 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use cargo_toml::{Dependency, Manifest};
|
||||
use tauri_utils::config::{Config, PatternKind, TauriConfig};
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
struct Diff {
|
||||
remove: Vec<String>,
|
||||
add: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum DependencyKind {
|
||||
Build,
|
||||
Normal,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AllowlistedDependency {
|
||||
name: String,
|
||||
alias: Option<String>,
|
||||
kind: DependencyKind,
|
||||
all_cli_managed_features: Option<Vec<&'static str>>,
|
||||
expected_features: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn check(config: &Config, manifest: &mut Manifest) -> Result<()> {
|
||||
let dependencies = vec![
|
||||
AllowlistedDependency {
|
||||
name: "tauri-build".into(),
|
||||
alias: None,
|
||||
kind: DependencyKind::Build,
|
||||
all_cli_managed_features: Some(vec!["isolation"]),
|
||||
expected_features: match config.tauri.pattern {
|
||||
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
|
||||
_ => vec![],
|
||||
},
|
||||
},
|
||||
AllowlistedDependency {
|
||||
name: "tauri".into(),
|
||||
alias: None,
|
||||
kind: DependencyKind::Normal,
|
||||
all_cli_managed_features: Some(TauriConfig::all_features()),
|
||||
expected_features: config
|
||||
.tauri
|
||||
.features()
|
||||
.into_iter()
|
||||
.map(|f| f.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
},
|
||||
];
|
||||
|
||||
for metadata in dependencies {
|
||||
let mut name = metadata.name.clone();
|
||||
let mut deps = find_dependency(manifest, &metadata.name, metadata.kind);
|
||||
if deps.is_empty() {
|
||||
if let Some(alias) = &metadata.alias {
|
||||
deps = find_dependency(manifest, alias, metadata.kind);
|
||||
name = alias.clone();
|
||||
}
|
||||
}
|
||||
|
||||
for dep in deps {
|
||||
if let Err(error) = check_features(dep, &metadata) {
|
||||
return Err(anyhow!("
|
||||
The `{}` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", name, error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn find_dependency(manifest: &mut Manifest, name: &str, kind: DependencyKind) -> Vec<Dependency> {
|
||||
let dep = match kind {
|
||||
DependencyKind::Build => manifest.build_dependencies.remove(name),
|
||||
DependencyKind::Normal => manifest.dependencies.remove(name),
|
||||
};
|
||||
|
||||
if let Some(dep) = dep {
|
||||
vec![dep]
|
||||
} else {
|
||||
let mut deps = Vec::new();
|
||||
for target in manifest.target.values_mut() {
|
||||
if let Some(dep) = match kind {
|
||||
DependencyKind::Build => target.build_dependencies.remove(name),
|
||||
DependencyKind::Normal => target.dependencies.remove(name),
|
||||
} {
|
||||
deps.push(dep);
|
||||
}
|
||||
}
|
||||
deps
|
||||
}
|
||||
}
|
||||
|
||||
fn features_diff(current: &[String], expected: &[String]) -> Diff {
|
||||
let mut remove = Vec::new();
|
||||
let mut add = Vec::new();
|
||||
for feature in current {
|
||||
if !expected.contains(feature) {
|
||||
remove.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for feature in expected {
|
||||
if !current.contains(feature) {
|
||||
add.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Diff { remove, add }
|
||||
}
|
||||
|
||||
fn check_features(dependency: Dependency, metadata: &AllowlistedDependency) -> Result<(), String> {
|
||||
let features = match dependency {
|
||||
Dependency::Simple(_) => Vec::new(),
|
||||
Dependency::Detailed(dep) => dep.features,
|
||||
Dependency::Inherited(dep) => dep.features,
|
||||
};
|
||||
|
||||
let diff = if let Some(all_cli_managed_features) = &metadata.all_cli_managed_features {
|
||||
features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
|
||||
.collect::<Vec<String>>(),
|
||||
&metadata.expected_features,
|
||||
)
|
||||
} else {
|
||||
features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| f.starts_with("allow-"))
|
||||
.collect::<Vec<String>>(),
|
||||
&metadata.expected_features,
|
||||
)
|
||||
};
|
||||
|
||||
let mut error_message = String::new();
|
||||
if !diff.remove.is_empty() {
|
||||
error_message.push_str("remove the `");
|
||||
error_message.push_str(&diff.remove.join(", "));
|
||||
error_message.push_str(if diff.remove.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str(" and ");
|
||||
}
|
||||
}
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str("add the `");
|
||||
error_message.push_str(&diff.add.join(", "));
|
||||
error_message.push_str(if diff.add.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
}
|
||||
|
||||
if error_message.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error_message)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Diff;
|
||||
|
||||
#[test]
|
||||
fn array_diff() {
|
||||
for (current, expected, result) in [
|
||||
(vec![], vec![], Default::default()),
|
||||
(
|
||||
vec!["a".into()],
|
||||
vec![],
|
||||
Diff {
|
||||
remove: vec!["a".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(vec!["a".into()], vec!["a".into()], Default::default()),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into(), "c".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec!["c".into()],
|
||||
},
|
||||
),
|
||||
] {
|
||||
assert_eq!(super::features_diff(¤t, &expected), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,17 +4,19 @@
|
||||
|
||||
#![cfg_attr(doc_cfg, feature(doc_cfg))]
|
||||
|
||||
use anyhow::Context;
|
||||
pub use anyhow::Result;
|
||||
use cargo_toml::{Dependency, Manifest};
|
||||
use cargo_toml::Manifest;
|
||||
use heck::AsShoutySnakeCase;
|
||||
|
||||
use tauri_utils::{
|
||||
config::Config,
|
||||
resources::{external_binaries, resource_relpath, ResourcePaths},
|
||||
config::{BundleResources, Config, WebviewInstallMode},
|
||||
resources::{external_binaries, ResourcePaths},
|
||||
};
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
mod allowlist;
|
||||
#[cfg(feature = "codegen")]
|
||||
mod codegen;
|
||||
mod static_vcruntime;
|
||||
@@ -71,11 +73,117 @@ fn copy_binaries(
|
||||
|
||||
/// Copies resources to a path.
|
||||
fn copy_resources(resources: ResourcePaths<'_>, path: &Path) -> Result<()> {
|
||||
for src in resources {
|
||||
let src = src?;
|
||||
println!("cargo:rerun-if-changed={}", src.display());
|
||||
let dest = path.join(resource_relpath(&src));
|
||||
copy_file(&src, dest)?;
|
||||
for resource in resources.iter() {
|
||||
let resource = resource?;
|
||||
println!("cargo:rerun-if-changed={}", resource.path().display());
|
||||
copy_file(resource.path(), path.join(resource.target()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::unix::fs::symlink(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a directory.
|
||||
#[cfg(windows)]
|
||||
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::windows::fs::symlink_dir(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a file.
|
||||
#[cfg(unix)]
|
||||
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::unix::fs::symlink(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a file.
|
||||
#[cfg(windows)]
|
||||
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::windows::fs::symlink_file(src, dst)
|
||||
}
|
||||
|
||||
fn copy_dir(from: &Path, to: &Path) -> Result<()> {
|
||||
for entry in walkdir::WalkDir::new(from) {
|
||||
let entry = entry?;
|
||||
debug_assert!(entry.path().starts_with(from));
|
||||
let rel_path = entry.path().strip_prefix(from)?;
|
||||
let dest_path = to.join(rel_path);
|
||||
if entry.file_type().is_symlink() {
|
||||
let target = std::fs::read_link(entry.path())?;
|
||||
if entry.path().is_dir() {
|
||||
symlink_dir(&target, &dest_path)?;
|
||||
} else {
|
||||
symlink_file(&target, &dest_path)?;
|
||||
}
|
||||
} else if entry.file_type().is_dir() {
|
||||
std::fs::create_dir(dest_path)?;
|
||||
} else {
|
||||
std::fs::copy(entry.path(), dest_path)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Copies the framework under `{src_dir}/{framework}.framework` to `{dest_dir}/{framework}.framework`.
|
||||
fn copy_framework_from(src_dir: &Path, framework: &str, dest_dir: &Path) -> Result<bool> {
|
||||
let src_name = format!("{}.framework", framework);
|
||||
let src_path = src_dir.join(&src_name);
|
||||
if src_path.exists() {
|
||||
copy_dir(&src_path, &dest_dir.join(&src_name))?;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Copies the macOS application bundle frameworks to the target folder
|
||||
fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
|
||||
std::fs::create_dir_all(dest_dir).with_context(|| {
|
||||
format!(
|
||||
"Failed to create frameworks output directory at {:?}",
|
||||
dest_dir
|
||||
)
|
||||
})?;
|
||||
for framework in frameworks.iter() {
|
||||
if framework.ends_with(".framework") {
|
||||
let src_path = PathBuf::from(framework);
|
||||
let src_name = src_path
|
||||
.file_name()
|
||||
.expect("Couldn't get framework filename");
|
||||
let dest_path = dest_dir.join(src_name);
|
||||
copy_dir(&src_path, &dest_path)?;
|
||||
continue;
|
||||
} else if framework.ends_with(".dylib") {
|
||||
let src_path = PathBuf::from(framework);
|
||||
if !src_path.exists() {
|
||||
return Err(anyhow::anyhow!("Library not found: {}", framework));
|
||||
}
|
||||
let src_name = src_path.file_name().expect("Couldn't get library filename");
|
||||
let dest_path = dest_dir.join(src_name);
|
||||
copy_file(&src_path, &dest_path)?;
|
||||
continue;
|
||||
} else if framework.contains('/') {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Framework path should have .framework extension: {}",
|
||||
framework
|
||||
));
|
||||
}
|
||||
if let Some(home_dir) = dirs_next::home_dir() {
|
||||
if copy_framework_from(&home_dir.join("Library/Frameworks/"), framework, dest_dir)? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if copy_framework_from(&PathBuf::from("/Library/Frameworks/"), framework, dest_dir)?
|
||||
|| copy_framework_from(
|
||||
&PathBuf::from("/Network/Library/Frameworks/"),
|
||||
framework,
|
||||
dest_dir,
|
||||
)?
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -116,10 +224,28 @@ pub struct WindowsAttributes {
|
||||
/// A string containing an [application manifest] to be included with the application on Windows.
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```ignore
|
||||
/// ```text
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// ```
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// if you are using tauri's dialog APIs, you need to specify a dependency on Common Control v6 by adding the following to your custom manifest:
|
||||
/// ```text
|
||||
/// <dependency>
|
||||
/// <dependentAssembly>
|
||||
/// <assemblyIdentity
|
||||
/// type="win32"
|
||||
/// name="Microsoft.Windows.Common-Controls"
|
||||
/// version="6.0.0.0"
|
||||
/// processorArchitecture="*"
|
||||
/// publicKeyToken="6595b64144ccf1df"
|
||||
/// language="*"
|
||||
/// />
|
||||
/// </dependentAssembly>
|
||||
/// </dependency>
|
||||
/// ```
|
||||
///
|
||||
/// [application manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
|
||||
app_manifest: Option<String>,
|
||||
}
|
||||
@@ -148,39 +274,57 @@ impl WindowsAttributes {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the Windows app [manifest].
|
||||
/// Sets the [application manifest] to be included with the application on Windows.
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```text
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// ```
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// if you are using tauri's dialog APIs, you need to specify a dependency on Common Control v6 by adding the following to your custom manifest:
|
||||
/// ```text
|
||||
/// <dependency>
|
||||
/// <dependentAssembly>
|
||||
/// <assemblyIdentity
|
||||
/// type="win32"
|
||||
/// name="Microsoft.Windows.Common-Controls"
|
||||
/// version="6.0.0.0"
|
||||
/// processorArchitecture="*"
|
||||
/// publicKeyToken="6595b64144ccf1df"
|
||||
/// language="*"
|
||||
/// />
|
||||
/// </dependentAssembly>
|
||||
/// </dependency>
|
||||
/// ```
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// The following manifest will brand the exe as requesting administrator privileges.
|
||||
/// Thus, everytime it is executed, a Windows UAC dialog will appear.
|
||||
///
|
||||
/// Note that you can move the manifest contents to a separate file and use `include_str!("manifest.xml")`
|
||||
/// instead of the inline string.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// let mut windows = tauri_build::WindowsAttributes::new();
|
||||
/// windows = windows.app_manifest(r#"
|
||||
/// <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
/// <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
/// <security>
|
||||
/// <requestedPrivileges>
|
||||
/// <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
/// </requestedPrivileges>
|
||||
/// </security>
|
||||
/// </trustInfo>
|
||||
/// <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
/// <security>
|
||||
/// <requestedPrivileges>
|
||||
/// <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
/// </requestedPrivileges>
|
||||
/// </security>
|
||||
/// </trustInfo>
|
||||
/// </assembly>
|
||||
/// "#);
|
||||
/// tauri_build::try_build(
|
||||
/// tauri_build::Attributes::new().windows_attributes(windows)
|
||||
/// ).expect("failed to run build script");
|
||||
/// let attrs = tauri_build::Attributes::new().windows_attributes(windows);
|
||||
/// tauri_build::try_build(attrs).expect("failed to run build script");
|
||||
/// ```
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```ignore
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// Note that you can move the manifest contents to a separate file and use `include_str!("manifest.xml")`
|
||||
/// instead of the inline string.
|
||||
///
|
||||
/// [manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn app_manifest<S: AsRef<str>>(mut self, manifest: S) -> Self {
|
||||
self.app_manifest = Some(manifest.as_ref().to_string());
|
||||
@@ -284,27 +428,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
Manifest::complete_from_path(&mut manifest, Path::new("Cargo.toml"))?;
|
||||
}
|
||||
|
||||
if let Some(tauri_build) = manifest.build_dependencies.remove("tauri-build") {
|
||||
let error_message = check_features(&config, tauri_build, true);
|
||||
|
||||
if !error_message.is_empty() {
|
||||
return Err(anyhow!("
|
||||
The `tauri-build` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", error_message));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tauri) = manifest.dependencies.remove("tauri") {
|
||||
let error_message = check_features(&config, tauri, false);
|
||||
|
||||
if !error_message.is_empty() {
|
||||
return Err(anyhow!("
|
||||
The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", error_message));
|
||||
}
|
||||
}
|
||||
allowlist::check(&config, &mut manifest)?;
|
||||
|
||||
let target_triple = std::env::var("TARGET").unwrap();
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
@@ -327,24 +451,53 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
|
||||
#[allow(unused_mut, clippy::redundant_clone)]
|
||||
let mut resources = config.tauri.bundle.resources.clone().unwrap_or_default();
|
||||
let mut resources = config
|
||||
.tauri
|
||||
.bundle
|
||||
.resources
|
||||
.clone()
|
||||
.unwrap_or_else(|| BundleResources::List(Vec::new()));
|
||||
if target_triple.contains("windows") {
|
||||
if let Some(fixed_webview2_runtime_path) =
|
||||
&config.tauri.bundle.windows.webview_fixed_runtime_path
|
||||
match &config.tauri.bundle.windows.webview_fixed_runtime_path {
|
||||
Some(path) => Some(path),
|
||||
None => match &config.tauri.bundle.windows.webview_install_mode {
|
||||
WebviewInstallMode::FixedRuntime { path } => Some(path),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
{
|
||||
resources.push(fixed_webview2_runtime_path.display().to_string());
|
||||
}
|
||||
}
|
||||
copy_resources(ResourcePaths::new(resources.as_slice(), true), target_dir)?;
|
||||
match resources {
|
||||
BundleResources::List(res) => {
|
||||
copy_resources(ResourcePaths::new(res.as_slice(), true), target_dir)?
|
||||
}
|
||||
BundleResources::Map(map) => copy_resources(ResourcePaths::from_map(&map, true), target_dir)?,
|
||||
}
|
||||
|
||||
if target_triple.contains("darwin") {
|
||||
if let Some(frameworks) = &config.tauri.bundle.macos.frameworks {
|
||||
if !frameworks.is_empty() {
|
||||
let frameworks_dir = target_dir.parent().unwrap().join("Frameworks");
|
||||
let _ = std::fs::remove_dir_all(&frameworks_dir);
|
||||
// copy frameworks to the root `target` folder (instead of `target/debug` for instance)
|
||||
// because the rpath is set to `@executable_path/../Frameworks`.
|
||||
copy_frameworks(&frameworks_dir, frameworks)?;
|
||||
|
||||
// If we have frameworks, we need to set the @rpath
|
||||
// https://github.com/tauri-apps/tauri/issues/7710
|
||||
println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path/../Frameworks");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(version) = &config.tauri.bundle.macos.minimum_system_version {
|
||||
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={version}");
|
||||
}
|
||||
}
|
||||
|
||||
if target_triple.contains("windows") {
|
||||
use anyhow::Context;
|
||||
use semver::Version;
|
||||
use tauri_winres::{VersionInfo, WindowsResource};
|
||||
|
||||
@@ -374,27 +527,23 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
res.set_manifest(include_str!("window-app-manifest.xml"));
|
||||
}
|
||||
|
||||
if let Some(sdk_dir) = &attributes.windows_attributes.sdk_dir {
|
||||
if let Some(sdk_dir_str) = sdk_dir.to_str() {
|
||||
res.set_toolkit_path(sdk_dir_str);
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"sdk_dir path is not valid; only UTF-8 characters are allowed"
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(version) = &config.package.version {
|
||||
if let Ok(v) = Version::parse(version) {
|
||||
if let Some(version_str) = &config.package.version {
|
||||
if let Ok(v) = Version::parse(version_str) {
|
||||
let version = v.major << 48 | v.minor << 32 | v.patch << 16;
|
||||
res.set_version_info(VersionInfo::FILEVERSION, version);
|
||||
res.set_version_info(VersionInfo::PRODUCTVERSION, version);
|
||||
}
|
||||
res.set("FileVersion", version);
|
||||
res.set("ProductVersion", version);
|
||||
res.set("FileVersion", version_str);
|
||||
res.set("ProductVersion", version_str);
|
||||
}
|
||||
if let Some(product_name) = &config.package.product_name {
|
||||
res.set("ProductName", product_name);
|
||||
res.set("FileDescription", product_name);
|
||||
}
|
||||
if let Some(short_description) = &config.tauri.bundle.short_description {
|
||||
res.set("FileDescription", short_description);
|
||||
}
|
||||
if let Some(copyright) = &config.tauri.bundle.copyright {
|
||||
res.set("LegalCopyright", copyright);
|
||||
}
|
||||
res.set_icon_with_id(&window_icon_path.display().to_string(), "32512");
|
||||
res.compile().with_context(|| {
|
||||
@@ -446,93 +595,6 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
struct Diff {
|
||||
remove: Vec<String>,
|
||||
add: Vec<String>,
|
||||
}
|
||||
|
||||
fn features_diff(current: &[String], expected: &[String]) -> Diff {
|
||||
let mut remove = Vec::new();
|
||||
let mut add = Vec::new();
|
||||
for feature in current {
|
||||
if !expected.contains(feature) {
|
||||
remove.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for feature in expected {
|
||||
if !current.contains(feature) {
|
||||
add.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Diff { remove, add }
|
||||
}
|
||||
|
||||
fn check_features(config: &Config, dependency: Dependency, is_tauri_build: bool) -> String {
|
||||
use tauri_utils::config::{PatternKind, TauriConfig};
|
||||
|
||||
let features = match dependency {
|
||||
Dependency::Simple(_) => Vec::new(),
|
||||
Dependency::Detailed(dep) => dep.features,
|
||||
Dependency::Inherited(dep) => dep.features,
|
||||
};
|
||||
|
||||
let all_cli_managed_features = if is_tauri_build {
|
||||
vec!["isolation"]
|
||||
} else {
|
||||
TauriConfig::all_features()
|
||||
};
|
||||
|
||||
let expected = if is_tauri_build {
|
||||
match config.tauri.pattern {
|
||||
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
|
||||
_ => vec![],
|
||||
}
|
||||
} else {
|
||||
config
|
||||
.tauri
|
||||
.features()
|
||||
.into_iter()
|
||||
.map(|f| f.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
};
|
||||
|
||||
let diff = features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
|
||||
.collect::<Vec<String>>(),
|
||||
&expected,
|
||||
);
|
||||
|
||||
let mut error_message = String::new();
|
||||
if !diff.remove.is_empty() {
|
||||
error_message.push_str("remove the `");
|
||||
error_message.push_str(&diff.remove.join(", "));
|
||||
error_message.push_str(if diff.remove.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str(" and ");
|
||||
}
|
||||
}
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str("add the `");
|
||||
error_message.push_str(&diff.add.join(", "));
|
||||
error_message.push_str(if diff.add.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
}
|
||||
|
||||
error_message
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct CargoMetadata {
|
||||
workspace_root: PathBuf,
|
||||
@@ -552,42 +614,3 @@ fn get_workspace_dir() -> Result<PathBuf> {
|
||||
|
||||
Ok(serde_json::from_slice::<CargoMetadata>(&output.stdout)?.workspace_root)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Diff;
|
||||
|
||||
#[test]
|
||||
fn array_diff() {
|
||||
for (current, expected, result) in [
|
||||
(vec![], vec![], Default::default()),
|
||||
(
|
||||
vec!["a".into()],
|
||||
vec![],
|
||||
Diff {
|
||||
remove: vec!["a".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(vec!["a".into()], vec!["a".into()], Default::default()),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into(), "c".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec!["c".into()],
|
||||
},
|
||||
),
|
||||
] {
|
||||
assert_eq!(super::features_diff(¤t, &expected), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## \[1.4.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
|
||||
## \[1.4.2]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`17d5a4f5`](https://www.github.com/tauri-apps/tauri/commit/17d5a4f51f244d3ff42014b5d1b075fad7c636a5)([#6706](https://www.github.com/tauri-apps/tauri/pull/6706)) Early panic if the PNG icon is not RGBA.
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-codegen"
|
||||
version = "1.3.0"
|
||||
version = "1.4.3"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
@@ -19,20 +19,20 @@ proc-macro2 = "1"
|
||||
quote = "1"
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_json = "1"
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils", features = [ "build" ] }
|
||||
tauri-utils = { version = "1.5.4", path = "../tauri-utils", features = [ "build" ] }
|
||||
thiserror = "1"
|
||||
walkdir = "2"
|
||||
brotli = { version = "3", optional = true, default-features = false, features = [ "std" ] }
|
||||
regex = { version = "1.7.1", optional = true }
|
||||
regex = { version = "1", optional = true }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
semver = "1"
|
||||
ico = "0.3"
|
||||
png = "0.17"
|
||||
json-patch = "1.0"
|
||||
json-patch = "1.2"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
plist = "1"
|
||||
time = { version = "=0.3.15", features = [ "parsing", "formatting" ] }
|
||||
time = { version = "0.3", features = [ "parsing", "formatting" ] }
|
||||
|
||||
[features]
|
||||
default = [ "compression" ]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
|
||||
@@ -176,10 +176,10 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
.tauri
|
||||
.security
|
||||
.dev_csp
|
||||
.clone()
|
||||
.or_else(|| config.tauri.security.csp.clone())
|
||||
.as_ref()
|
||||
.or(config.tauri.security.csp.as_ref())
|
||||
} else {
|
||||
config.tauri.security.csp.clone()
|
||||
config.tauri.security.csp.as_ref()
|
||||
};
|
||||
if csp.is_some() {
|
||||
options = options.with_csp();
|
||||
@@ -350,14 +350,11 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
}
|
||||
|
||||
let out_path = out_dir.join("Info.plist");
|
||||
info_plist
|
||||
.to_file_xml(&out_path)
|
||||
.to_file_xml(out_dir.join("Info.plist"))
|
||||
.expect("failed to write Info.plist");
|
||||
|
||||
let info_plist_path = out_path.display().to_string();
|
||||
quote!({
|
||||
tauri::embed_plist::embed_info_plist!(#info_plist_path);
|
||||
tauri::embed_plist::embed_info_plist!(concat!(std::env!("OUT_DIR"), "/Info.plist"));
|
||||
})
|
||||
} else {
|
||||
quote!(())
|
||||
@@ -473,15 +470,20 @@ fn ico_icon<P: AsRef<Path>>(
|
||||
let width = entry.width();
|
||||
let height = entry.height();
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
let icon_file_name = path.file_name().unwrap();
|
||||
let out_path = out_dir.join(icon_file_name);
|
||||
write_if_changed(&out_path, &rgba).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }));
|
||||
let icon_file_name = icon_file_name.to_str().unwrap();
|
||||
let icon = quote!(Some(
|
||||
#root::Icon::Rgba {
|
||||
rgba: include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)).to_vec(),
|
||||
width: #width,
|
||||
height: #height
|
||||
}));
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
@@ -497,9 +499,10 @@ fn raw_icon<P: AsRef<Path>>(out_dir: &Path, path: P) -> Result<TokenStream, Embe
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(include_bytes!(#out_path).to_vec()));
|
||||
let icon_path = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
let icon = quote!(::std::option::Option::Some(
|
||||
include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_path)).to_vec()
|
||||
));
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
@@ -516,6 +519,13 @@ fn png_icon<P: AsRef<Path>>(
|
||||
let mut reader = decoder
|
||||
.read_info()
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e));
|
||||
|
||||
let (color_type, _) = reader.output_color_type();
|
||||
|
||||
if color_type != png::ColorType::Rgba {
|
||||
panic!("icon {} is not RGBA", path.display());
|
||||
}
|
||||
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
while let Ok(Some(row)) = reader.next_row() {
|
||||
buffer.extend(row.data());
|
||||
@@ -523,15 +533,21 @@ fn png_icon<P: AsRef<Path>>(
|
||||
let width = reader.info().width;
|
||||
let height = reader.info().height;
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
let icon_file_name = path.file_name().unwrap();
|
||||
let out_path = out_dir.join(icon_file_name);
|
||||
write_if_changed(&out_path, &buffer).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }));
|
||||
let icon_file_name = icon_file_name.to_str().unwrap();
|
||||
let icon = quote!(Some(
|
||||
#root::Icon::Rgba {
|
||||
rgba: include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)).to_vec(),
|
||||
width: #width,
|
||||
height: #height,
|
||||
}
|
||||
));
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "tauri-tauri-config-schema"
|
||||
name = "tauri-config-schema"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
@@ -8,8 +8,7 @@ publish = false
|
||||
tauri-utils = { version = "1.0.0", features = [
|
||||
"schema",
|
||||
], path = "../tauri-utils" }
|
||||
schemars = { version = "0.8", features = ["url", "preserve_order"] }
|
||||
schemars = { version = "0.8.18", features = ["url", "preserve_order"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_with = "1.12"
|
||||
url = { version = "2.3", features = ["serde"] }
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setClosable": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
@@ -116,7 +117,9 @@
|
||||
"setIcon": false,
|
||||
"setIgnoreCursorEvents": false,
|
||||
"setMaxSize": false,
|
||||
"setMaximizable": false,
|
||||
"setMinSize": false,
|
||||
"setMinimizable": false,
|
||||
"setPosition": false,
|
||||
"setResizable": false,
|
||||
"setSize": false,
|
||||
@@ -164,6 +167,7 @@
|
||||
"security": {
|
||||
"dangerousDisableAssetCspModification": false,
|
||||
"dangerousRemoteDomainIpcAccess": [],
|
||||
"dangerousUseHttpScheme": false,
|
||||
"freezePrototype": false
|
||||
},
|
||||
"updater": {
|
||||
@@ -221,8 +225,7 @@
|
||||
"pattern": "^[^/\\:*?\"<>|]+$"
|
||||
},
|
||||
"version": {
|
||||
"description": "App version. It is a semver version number or a path to a `package.json` file containing the `version` field.",
|
||||
"default": null,
|
||||
"description": "App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -383,6 +386,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setClosable": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
@@ -394,7 +398,9 @@
|
||||
"setIcon": false,
|
||||
"setIgnoreCursorEvents": false,
|
||||
"setMaxSize": false,
|
||||
"setMaximizable": false,
|
||||
"setMinSize": false,
|
||||
"setMinimizable": false,
|
||||
"setPosition": false,
|
||||
"setResizable": false,
|
||||
"setSize": false,
|
||||
@@ -417,6 +423,7 @@
|
||||
"default": {
|
||||
"dangerousDisableAssetCspModification": false,
|
||||
"dangerousRemoteDomainIpcAccess": [],
|
||||
"dangerousUseHttpScheme": false,
|
||||
"freezePrototype": false
|
||||
},
|
||||
"allOf": [
|
||||
@@ -605,7 +612,22 @@
|
||||
"format": "double"
|
||||
},
|
||||
"resizable": {
|
||||
"description": "Whether the window is resizable or not.",
|
||||
"description": "Whether the window is resizable or not. When resizable is set to false, native window's maximize button is automatically disabled.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"maximizable": {
|
||||
"description": "Whether the window's native maximize button is enabled or not. If resizable is set to false, this setting is ignored.\n\n## Platform-specific\n\n- **macOS:** Disables the \"zoom\" button in the window titlebar, which is also used to enter fullscreen mode. - **Linux / iOS / Android:** Unsupported.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"minimizable": {
|
||||
"description": "Whether the window's native minimize button is enabled or not.\n\n## Platform-specific\n\n- **Linux / iOS / Android:** Unsupported.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"closable": {
|
||||
"description": "Whether the window's native close button is enabled or not.\n\n## Platform-specific\n\n- **Linux:** \"GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible\" - **iOS / Android:** Unsupported.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -1053,13 +1075,14 @@
|
||||
},
|
||||
"resources": {
|
||||
"description": "App resources to bundle. Each resource is a path to a file or directory. Glob patterns are supported.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BundleResources"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"copyright": {
|
||||
"description": "A copyright string associated with your application.",
|
||||
@@ -1237,6 +1260,25 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"BundleResources": {
|
||||
"description": "Definition for bundle resources. Can be either a list of paths to include or a map of source to target paths.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "A list of paths to include.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A map of source to target paths.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"AppImageConfig": {
|
||||
"description": "Configuration for AppImage bundles.\n\nSee more: https://tauri.app/v1/api/config#appimageconfig",
|
||||
"type": "object",
|
||||
@@ -1270,6 +1312,34 @@
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"desktopTemplate": {
|
||||
"description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"section": {
|
||||
"description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"priority": {
|
||||
"description": "Change the priority of the Debian Package. By default, it is set to `optional`. Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"changelog": {
|
||||
"description": "Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -1661,6 +1731,13 @@
|
||||
"description": "Configuration for the Installer bundle using NSIS.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"template": {
|
||||
"description": "A custom .nsi template to use.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"license": {
|
||||
"description": "The path to the license file to render on the installer.",
|
||||
"type": [
|
||||
@@ -1708,10 +1785,31 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"customLanguageFiles": {
|
||||
"description": "A key-value pair where the key is the language and the value is the path to a custom `.nsh` file that holds the translated text for tauri's custom messages.\n\nSee <https://github.com/tauri-apps/tauri/blob/dev/tooling/bundler/src/bundle/windows/templates/nsis-languages/English.nsh> for an example `.nsh` file.\n\n**Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`] languages array,",
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"displayLanguageSelector": {
|
||||
"description": "Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not. By default the OS language is selected, with a fallback to the first language in the `languages` array.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"compression": {
|
||||
"description": "Set the compression algorithm used to compress files in the installer.\n\nSee <https://nsis.sourceforge.io/Reference/SetCompressor>",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NsisCompression"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -1742,6 +1840,32 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"NsisCompression": {
|
||||
"description": "Compression algorithms used in the NSIS installer.\n\nSee <https://nsis.sourceforge.io/Reference/SetCompressor>",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "ZLIB uses the deflate algorithm, it is a quick and simple method. With the default compression level it uses about 300 KB of memory.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "BZIP2 usually gives better compression ratios than ZLIB, but it is a bit slower and uses more memory. With the default compression level it uses about 4 MB of memory.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"bzip2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "LZMA (default) is a new compression method that gives very good compression ratios. The decompression speed is high (10-20 MB/s on a 2 GHz CPU), the compression speed is lower. The memory size that will be used for decompression is the dictionary size plus a few KBs, the default is 8 MB.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"lzma"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"AllowlistConfig": {
|
||||
"description": "Allowlist configuration. The allowlist is a translation of the [Cargo allowlist features](https://docs.rs/tauri/latest/tauri/#cargo-allowlist-features).\n\n# Notes\n\n- Endpoints that don't have their own allowlist option are enabled by default. - There is only \"opt-in\", no \"opt-out\". Setting an option to `false` has no effect.\n\n# Examples\n\n- * [`\"app-all\": true`](https://tauri.app/v1/api/config/#appallowlistconfig.all) will make the [hide](https://tauri.app/v1/api/js/app#hide) endpoint be available regardless of whether `hide` is set to `false` or `true` in the allowlist.",
|
||||
"type": "object",
|
||||
@@ -1785,6 +1909,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setClosable": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
@@ -1796,7 +1921,9 @@
|
||||
"setIcon": false,
|
||||
"setIgnoreCursorEvents": false,
|
||||
"setMaxSize": false,
|
||||
"setMaximizable": false,
|
||||
"setMinSize": false,
|
||||
"setMinimizable": false,
|
||||
"setPosition": false,
|
||||
"setResizable": false,
|
||||
"setSize": false,
|
||||
@@ -2052,6 +2179,13 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"requireLiteralLeadingDot": {
|
||||
"description": "Whether or not paths that contain components that start with a `.` will require that `.` appears literally in the pattern; `*`, `?`, `**`, or `[...]` will not match. This is useful because such files are conventionally considered hidden on Unix systems and it might be desirable to skip them when listing files.\n\nDefaults to `true` on Unix systems and `false` on Windows",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2086,6 +2220,21 @@
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"setMaximizable": {
|
||||
"description": "Allows setting whether the window's native maximize button is enabled or not.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"setMinimizable": {
|
||||
"description": "Allows setting whether the window's native minimize button is enabled or not.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"setClosable": {
|
||||
"description": "Allows setting whether the window's native close button is enabled or not.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"setTitle": {
|
||||
"description": "Allows changing the window title.",
|
||||
"default": false,
|
||||
@@ -2414,7 +2563,7 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
"HttpAllowlistScope": {
|
||||
"description": "HTTP API scope definition. It is a list of URLs that can be accessed by the webview when using the HTTP APIs. The scoped URL is matched against the request URL using a glob pattern.\n\nExamples: - \"https://**\": allows all HTTPS urls - \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path - \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"description": "HTTP API scope definition. It is a list of URLs that can be accessed by the webview when using the HTTP APIs. The scoped URL is matched against the request URL using a glob pattern.\n\nExamples: - \"https://*\": allows all HTTPS urls - \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path - \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
@@ -2613,6 +2762,11 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/RemoteDomainAccessScope"
|
||||
}
|
||||
},
|
||||
"dangerousUseHttpScheme": {
|
||||
"description": "Sets whether the custom protocols should use `http://<scheme>.localhost` instead of the default `https://<scheme>.localhost` on Windows.\n\n**WARNING:** Using a `http` scheme will allow mixed content when trying to fetch `http` endpoints and is therefore less secure but will match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -2692,7 +2846,7 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"description": "The list of plugins that are allowed in this scope.",
|
||||
"description": "The list of plugins that are allowed in this scope. The names should be without the `tauri-plugin-` prefix, for example `\"store\"` for `tauri-plugin-store`.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -2791,7 +2945,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "The quiet mode means there's no user interaction required. Requires admin privileges if the installer does (WiX).",
|
||||
"description": "The quiet mode means there's no user interaction required. Requires admin privileges if the installer does.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"quiet"
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
## \[1.4.4]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
- Upgraded to `tauri-codegen@1.4.3`
|
||||
|
||||
## \[1.4.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
- Upgraded to `tauri-codegen@1.4.2`
|
||||
|
||||
## \[1.4.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-codegen@1.4.1`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d68a25e3`](https://www.github.com/tauri-apps/tauri/commit/d68a25e32e012e57a9e5225b589b9ecbea70a887)([#6124](https://www.github.com/tauri-apps/tauri/pull/6124)) Improve compiler error message when generating an async command that has a reference input and don't return a Result.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-macros"
|
||||
version = "1.3.0"
|
||||
version = "1.4.4"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "os", "filesystem", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
@@ -16,12 +16,12 @@ readme = "README.md"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
proc-macro2 = { version = "1", features = [ "span-locations" ] }
|
||||
quote = "1"
|
||||
syn = { version = "1", features = [ "full" ] }
|
||||
heck = "0.4"
|
||||
tauri-codegen = { version = "1.3.0", default-features = false, path = "../tauri-codegen" }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
heck = "0.5"
|
||||
tauri-codegen = { version = "1.4.3", default-features = false, path = "../tauri-codegen" }
|
||||
tauri-utils = { version = "1.5.4", path = "../tauri-utils" }
|
||||
|
||||
[features]
|
||||
custom-protocol = [ ]
|
||||
@@ -30,3 +30,4 @@ isolation = [ "tauri-codegen/isolation" ]
|
||||
shell-scope = [ "tauri-codegen/shell-scope" ]
|
||||
config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-codegen/config-toml", "tauri-utils/config-toml" ]
|
||||
tracing = [ ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{
|
||||
ext::IdentExt,
|
||||
parse::{Parse, ParseStream},
|
||||
@@ -103,24 +103,113 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
resolver: format_ident!("__tauri_resolver__"),
|
||||
};
|
||||
|
||||
// Tauri currently doesn't support async commands that take a reference as input and don't return
|
||||
// a result. See: https://github.com/tauri-apps/tauri/issues/2533
|
||||
//
|
||||
// For now, we provide an informative error message to the user in that case. Once #2533 is
|
||||
// resolved, this check can be removed.
|
||||
let mut async_command_check = TokenStream2::new();
|
||||
if function.sig.asyncness.is_some() {
|
||||
// This check won't catch all possible problems but it should catch the most common ones.
|
||||
let mut ref_argument_span = None;
|
||||
|
||||
for arg in &function.sig.inputs {
|
||||
if let syn::FnArg::Typed(pat) = arg {
|
||||
match &*pat.ty {
|
||||
syn::Type::Reference(_) => {
|
||||
ref_argument_span = Some(pat.span());
|
||||
}
|
||||
syn::Type::Path(path) => {
|
||||
// Check if the type contains a lifetime argument
|
||||
let last = path.path.segments.last().unwrap();
|
||||
if let syn::PathArguments::AngleBracketed(args) = &last.arguments {
|
||||
if args
|
||||
.args
|
||||
.iter()
|
||||
.any(|arg| matches!(arg, syn::GenericArgument::Lifetime(_)))
|
||||
{
|
||||
ref_argument_span = Some(pat.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(span) = ref_argument_span {
|
||||
if let syn::ReturnType::Type(_, return_type) = &function.sig.output {
|
||||
// To check if the return type is `Result` we require it to check a trait that is
|
||||
// only implemented by `Result`. That way we don't exclude renamed result types
|
||||
// which we wouldn't otherwise be able to detect purely from the token stream.
|
||||
// The "error message" displayed to the user is simply the trait name.
|
||||
async_command_check = quote_spanned! {return_type.span() =>
|
||||
#[allow(unreachable_code, clippy::diverging_sub_expression)]
|
||||
const _: () = if false {
|
||||
trait AsyncCommandMustReturnResult {}
|
||||
impl<A, B> AsyncCommandMustReturnResult for ::std::result::Result<A, B> {}
|
||||
let _check: #return_type = unreachable!();
|
||||
let _: &dyn AsyncCommandMustReturnResult = &_check;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
return quote_spanned! {
|
||||
span => compile_error!("async commands that contain references as inputs must return a `Result`");
|
||||
}.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// body to the command wrapper or a `compile_error!` of an error occurred while parsing it.
|
||||
let body = syn::parse::<WrapperAttributes>(attributes)
|
||||
let (body, attributes) = syn::parse::<WrapperAttributes>(attributes)
|
||||
.map(|mut attrs| {
|
||||
if function.sig.asyncness.is_some() {
|
||||
attrs.execution_context = ExecutionContext::Async;
|
||||
}
|
||||
attrs
|
||||
})
|
||||
.and_then(|attrs| match attrs.execution_context {
|
||||
ExecutionContext::Async => body_async(&function, &invoke, attrs.argument_case),
|
||||
ExecutionContext::Blocking => body_blocking(&function, &invoke, attrs.argument_case),
|
||||
.and_then(|attrs| {
|
||||
let body = match attrs.execution_context {
|
||||
ExecutionContext::Async => body_async(&function, &invoke, attrs.argument_case),
|
||||
ExecutionContext::Blocking => body_blocking(&function, &invoke, attrs.argument_case),
|
||||
};
|
||||
body.map(|b| (b, Some(attrs)))
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
.unwrap_or_else(|e| (syn::Error::into_compile_error(e), None));
|
||||
|
||||
let Invoke { message, resolver } = invoke;
|
||||
|
||||
let kind = match attributes.as_ref().map(|a| &a.execution_context) {
|
||||
Some(ExecutionContext::Async) if function.sig.asyncness.is_none() => "sync_threadpool",
|
||||
Some(ExecutionContext::Async) => "async",
|
||||
Some(ExecutionContext::Blocking) => "sync",
|
||||
_ => "sync",
|
||||
};
|
||||
|
||||
let loc = function.span().start();
|
||||
let line = loc.line;
|
||||
let col = loc.column;
|
||||
|
||||
let maybe_span = if cfg!(feature = "tracing") {
|
||||
quote!({
|
||||
let _span = tracing::debug_span!(
|
||||
"ipc::request::handler",
|
||||
cmd = #message.command(),
|
||||
kind = #kind,
|
||||
loc.line = #line,
|
||||
loc.col = #col,
|
||||
is_internal = false,
|
||||
)
|
||||
.entered();
|
||||
})
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
// Rely on rust 2018 edition to allow importing a macro from a path.
|
||||
quote!(
|
||||
#async_command_check
|
||||
|
||||
#function
|
||||
|
||||
#maybe_macro_export
|
||||
@@ -134,6 +223,8 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
#[allow(unused_variables)]
|
||||
let ::tauri::Invoke { message: #message, resolver: #resolver } = $invoke;
|
||||
|
||||
#maybe_span
|
||||
|
||||
#body
|
||||
}};
|
||||
}
|
||||
@@ -153,6 +244,20 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
fn body_async(function: &ItemFn, invoke: &Invoke, case: ArgumentCase) -> syn::Result<TokenStream2> {
|
||||
let Invoke { message, resolver } = invoke;
|
||||
parse_args(function, message, case).map(|args| {
|
||||
#[cfg(feature = "tracing")]
|
||||
quote! {
|
||||
use tracing::Instrument;
|
||||
|
||||
let span = tracing::debug_span!("ipc::request::run");
|
||||
#resolver.respond_async_serialized(async move {
|
||||
let result = $path(#(#args?),*);
|
||||
let kind = (&result).async_kind();
|
||||
kind.future(result).await
|
||||
}
|
||||
.instrument(span));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
quote! {
|
||||
#resolver.respond_async_serialized(async move {
|
||||
let result = $path(#(#args?),*);
|
||||
@@ -182,7 +287,14 @@ fn body_blocking(
|
||||
Err(err) => return #resolver.invoke_error(err),
|
||||
});
|
||||
|
||||
let maybe_span = if cfg!(feature = "tracing") {
|
||||
quote!(let _span = tracing::debug_span!("ipc::request::run").entered();)
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
#maybe_span
|
||||
let result = $path(#(match #args #match_body),*);
|
||||
let kind = (&result).blocking_kind();
|
||||
kind.block(result, #resolver);
|
||||
|
||||
@@ -272,12 +272,12 @@ pub fn command_handler(attributes: HandlerAttributes, function: ItemFn) -> Token
|
||||
pub fn command_test(attributes: HandlerTestAttributes, function: ItemFn) -> TokenStream2 {
|
||||
let allowlist = attributes.allowlist;
|
||||
let error_message = attributes.error_message.as_str();
|
||||
let signature = function.sig.clone();
|
||||
let signature = &function.sig;
|
||||
|
||||
let enum_variant_name = function.sig.ident.to_string().to_lower_camel_case();
|
||||
let response = match attributes.allowlist_check_kind {
|
||||
AllowlistCheckKind::Runtime => {
|
||||
let test_name = function.sig.ident.clone();
|
||||
let test_name = &signature.ident;
|
||||
quote!(super::Cmd::#test_name(crate::test::mock_invoke_context()))
|
||||
}
|
||||
AllowlistCheckKind::Serde => quote! {
|
||||
|
||||
@@ -1,5 +1,84 @@
|
||||
# Changelog
|
||||
|
||||
## \[0.14.7]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`2eb21378a`](https://www.github.com/tauri-apps/tauri/commit/2eb21378a65107da0d4a1ab425767e99580966c2)([#9718](https://www.github.com/tauri-apps/tauri/pull/9718)) Fixes redraw tracing span not closing.
|
||||
|
||||
## \[0.14.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
- Upgraded to `tauri-runtime@0.14.3`
|
||||
|
||||
## \[0.14.5]
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`d42668ce`](https://www.github.com/tauri-apps/tauri/commit/d42668ce17494ab778f436aaa9b216d6db3f0b31)([#9003](https://www.github.com/tauri-apps/tauri/pull/9003)) Fix panic during intialization on wayland when using `clipboard` feature, instead propagate the error during API usage.
|
||||
|
||||
## \[0.14.4]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`24210735`](https://www.github.com/tauri-apps/tauri/commit/2421073576a6d45783176be57b0188668558aff7)([#8117](https://www.github.com/tauri-apps/tauri/pull/8117)) Fixes a crash on macOS when accessing the windows map.
|
||||
- [`510b6226`](https://www.github.com/tauri-apps/tauri/commit/510b62261c70331ce3f5bfd24137dac1bc4a0bbe)([#8822](https://www.github.com/tauri-apps/tauri/pull/8822)) Add missing `arboard` feature flag to prevent panics in wayland session.
|
||||
|
||||
## \[0.14.3]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`0d0501cb`](https://www.github.com/tauri-apps/tauri/commit/0d0501cb7b5e767c51a3697a148acfe84211a7ad)([#8394](https://www.github.com/tauri-apps/tauri/pull/8394)) Use `arboard` instead of `tao` clipboard implementation to prevent a crash.
|
||||
- [`b2f83f03`](https://www.github.com/tauri-apps/tauri/commit/b2f83f03a872baa91e2b6bbb22a3e7a5cd975dc0)([#8402](https://www.github.com/tauri-apps/tauri/pull/8402)) Use `Arc` instead of `Rc` to prevent crashes on macOS.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
- Upgraded to `tauri-runtime@0.14.2`
|
||||
|
||||
## \[0.14.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
## \[0.14.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`4bf1e85e`](https://www.github.com/tauri-apps/tauri/commit/4bf1e85e6bf85a7ec92d50c8465bc0588a6399d8)([#7722](https://www.github.com/tauri-apps/tauri/pull/7722)) Properly respect the `focused` option when creating the webview.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-runtime@0.14.1`
|
||||
|
||||
## \[0.14.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` methods to `WindowBuilder`.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added `set_maximizable`, `set_minimizable`, `set_closable`, `is_maximizable`, `is_minimizable` and `is_closable` methods to the `Dispatch` trait.
|
||||
- [`000104bc`](https://www.github.com/tauri-apps/tauri/commit/000104bc3bc0c9ff3d20558ab9cf2080f126e9e0)([#6472](https://www.github.com/tauri-apps/tauri/pull/6472)) Add `Window::is_focused` getter.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`b41b57eb`](https://www.github.com/tauri-apps/tauri/commit/b41b57ebb27befd366db5befaafb6043c18fdfef)([#7105](https://www.github.com/tauri-apps/tauri/pull/7105)) Fix panics when registering an invalid global shortcuts or checking it is registered and return proper errors instead.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`076e1a81`](https://www.github.com/tauri-apps/tauri/commit/076e1a81a50468e3dfb34ae9ca7e77c5e1758daa)([#7119](https://www.github.com/tauri-apps/tauri/pull/7119)) Use `u32` instead of `u64` for js event listener ids
|
||||
|
||||
## \[0.13.0]
|
||||
|
||||
- Added the `additional_browser_args` option when creating a window.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "0.13.0"
|
||||
version = "0.14.7"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
@@ -13,12 +13,14 @@ exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
wry = { version = "0.24.1", default-features = false, features = [ "file-drop", "protocol" ] }
|
||||
tauri-runtime = { version = "0.13.0", path = "../tauri-runtime" }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
wry = { version = "0.24.6", default-features = false, features = [ "file-drop", "protocol" ] }
|
||||
tauri-runtime = { version = "0.14.3", path = "../tauri-runtime" }
|
||||
tauri-utils = { version = "1.5.4", path = "../tauri-utils" }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
rand = "0.8"
|
||||
raw-window-handle = "=0.5.0"
|
||||
raw-window-handle = "0.5"
|
||||
tracing = { version = "0.1", optional = true }
|
||||
arboard = { version = "3", optional = true }
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
webview2-com = "0.19.1"
|
||||
@@ -46,5 +48,6 @@ macos-private-api = [
|
||||
]
|
||||
objc-exception = [ "wry/objc-exception" ]
|
||||
global-shortcut = [ "tauri-runtime/global-shortcut" ]
|
||||
clipboard = [ "tauri-runtime/clipboard" ]
|
||||
clipboard = [ "tauri-runtime/clipboard", "arboard/wayland-data-control" ]
|
||||
linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]
|
||||
tracing = [ "dep:tracing", "wry/tracing" ]
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
|
||||
@@ -4,59 +4,66 @@
|
||||
|
||||
//! Clipboard implementation.
|
||||
|
||||
use crate::{getter, Context, Message};
|
||||
|
||||
use std::sync::{
|
||||
mpsc::{channel, Sender},
|
||||
Arc, Mutex,
|
||||
use std::{
|
||||
fmt,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use tauri_runtime::{ClipboardManager, Result, UserEvent};
|
||||
pub use wry::application::clipboard::Clipboard;
|
||||
pub use arboard::Clipboard;
|
||||
use tauri_runtime::{ClipboardManager, Result};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ClipboardMessage {
|
||||
WriteText(String, Sender<()>),
|
||||
ReadText(Sender<Option<String>>),
|
||||
#[derive(Clone)]
|
||||
pub struct ClipboardManagerWrapper {
|
||||
pub clipboard: Arc<Mutex<std::result::Result<Clipboard, arboard::Error>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ClipboardManagerWrapper<T: UserEvent> {
|
||||
pub context: Context<T>,
|
||||
impl fmt::Debug for ClipboardManagerWrapper {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ClipboardManagerWrapper").finish()
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl<T: UserEvent> Sync for ClipboardManagerWrapper<T> {}
|
||||
struct ClipboardError(String);
|
||||
impl std::error::Error for ClipboardError {}
|
||||
impl fmt::Display for ClipboardError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ClipboardError: {}", self.0)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for ClipboardError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("ClipboardError").field(&self.0).finish()
|
||||
}
|
||||
}
|
||||
impl From<ClipboardError> for crate::Error {
|
||||
fn from(e: ClipboardError) -> crate::Error {
|
||||
crate::Error::Clipboard(Box::new(e))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent> ClipboardManager for ClipboardManagerWrapper<T> {
|
||||
impl ClipboardManager for ClipboardManagerWrapper {
|
||||
fn read_text(&self) -> Result<Option<String>> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx)))
|
||||
self
|
||||
.clipboard
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.map(|c| c.get_text().map(Some))
|
||||
.map_err(|e| ClipboardError(e.to_string()))?
|
||||
.map_err(|e| ClipboardError(e.to_string()))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn write_text<V: Into<String>>(&mut self, text: V) -> Result<()> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx))
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_clipboard_message(
|
||||
message: ClipboardMessage,
|
||||
clipboard_manager: &Arc<Mutex<Clipboard>>,
|
||||
) {
|
||||
match message {
|
||||
ClipboardMessage::WriteText(text, tx) => {
|
||||
clipboard_manager.lock().unwrap().write_text(text);
|
||||
tx.send(()).unwrap();
|
||||
}
|
||||
ClipboardMessage::ReadText(tx) => tx
|
||||
.send(clipboard_manager.lock().unwrap().read_text())
|
||||
.unwrap(),
|
||||
let text = text.into();
|
||||
self
|
||||
.clipboard
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.map(|c| c.set_text(text))
|
||||
.map_err(|e| ClipboardError(e.to_string()))?
|
||||
.map_err(|e| ClipboardError(e.to_string()))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
error::Error as StdError,
|
||||
fmt,
|
||||
rc::Rc,
|
||||
sync::{
|
||||
mpsc::{channel, Sender},
|
||||
Arc, Mutex,
|
||||
@@ -18,7 +20,7 @@ use crate::{getter, Context, Message};
|
||||
use tauri_runtime::{Error, GlobalShortcutManager, Result, UserEvent};
|
||||
#[cfg(desktop)]
|
||||
pub use wry::application::{
|
||||
accelerator::{Accelerator, AcceleratorId},
|
||||
accelerator::{Accelerator, AcceleratorId, AcceleratorParseError},
|
||||
global_shortcut::{GlobalShortcut, ShortcutManager as WryShortcutManager},
|
||||
};
|
||||
|
||||
@@ -39,6 +41,15 @@ pub struct GlobalShortcutWrapper(GlobalShortcut);
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Send for GlobalShortcutWrapper {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct AcceleratorParseErrorWrapper(AcceleratorParseError);
|
||||
impl fmt::Display for AcceleratorParseErrorWrapper {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
impl StdError for AcceleratorParseErrorWrapper {}
|
||||
|
||||
/// Wrapper around [`WryShortcutManager`].
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalShortcutManagerHandle<T: UserEvent> {
|
||||
@@ -67,14 +78,21 @@ impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered(
|
||||
accelerator.parse().expect("invalid accelerator"),
|
||||
accelerator
|
||||
.parse()
|
||||
.map_err(|e: AcceleratorParseError| Error::GlobalShortcut(Box::new(
|
||||
AcceleratorParseErrorWrapper(e)
|
||||
)))?,
|
||||
tx
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()> {
|
||||
let wry_accelerator: Accelerator = accelerator.parse().expect("invalid accelerator");
|
||||
let wry_accelerator: Accelerator =
|
||||
accelerator.parse().map_err(|e: AcceleratorParseError| {
|
||||
Error::GlobalShortcut(Box::new(AcceleratorParseErrorWrapper(e)))
|
||||
})?;
|
||||
let id = wry_accelerator.clone().id();
|
||||
let (tx, rx) = channel();
|
||||
let shortcut = getter!(
|
||||
@@ -121,7 +139,7 @@ impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {
|
||||
|
||||
pub fn handle_global_shortcut_message(
|
||||
message: GlobalShortcutMessage,
|
||||
global_shortcut_manager: &Arc<Mutex<WryShortcutManager>>,
|
||||
global_shortcut_manager: &Rc<Mutex<WryShortcutManager>>,
|
||||
) {
|
||||
match message {
|
||||
GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//! The [`wry`] Tauri [`Runtime`].
|
||||
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle};
|
||||
use std::{collections::BTreeMap, rc::Rc};
|
||||
use tauri_runtime::{
|
||||
http::{header::CONTENT_TYPE, Request as HttpRequest, RequestParts, Response as HttpResponse},
|
||||
menu::{AboutMetadata, CustomMenuItem, Menu, MenuEntry, MenuHash, MenuId, MenuItem, MenuUpdate},
|
||||
@@ -68,6 +69,7 @@ use wry::{
|
||||
};
|
||||
|
||||
pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, WindowId};
|
||||
pub use wry::webview::webview_version;
|
||||
|
||||
#[cfg(windows)]
|
||||
use wry::webview::WebviewExtWindows;
|
||||
@@ -173,8 +175,6 @@ pub(crate) fn send_user_message<T: UserEvent>(
|
||||
webview_id_map: context.webview_id_map.clone(),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(),
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: context.main_thread.clipboard_manager.clone(),
|
||||
windows: context.main_thread.windows.clone(),
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: context.main_thread.system_tray_manager.clone(),
|
||||
@@ -214,7 +214,6 @@ impl<T: UserEvent> Context<T> {
|
||||
impl<T: UserEvent> Context<T> {
|
||||
fn create_webview(&self, pending: PendingWindow<T, Wry<T>>) -> Result<DetachedWindow<T, Wry<T>>> {
|
||||
let label = pending.label.clone();
|
||||
let current_url = pending.current_url.clone();
|
||||
let menu_ids = pending.menu_ids.clone();
|
||||
let js_event_listeners = pending.js_event_listeners.clone();
|
||||
let context = self.clone();
|
||||
@@ -236,7 +235,6 @@ impl<T: UserEvent> Context<T> {
|
||||
};
|
||||
Ok(DetachedWindow {
|
||||
label,
|
||||
current_url,
|
||||
dispatcher,
|
||||
menu_ids,
|
||||
js_event_listeners,
|
||||
@@ -244,17 +242,52 @@ impl<T: UserEvent> Context<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ActiveTraceSpanStore(Rc<RefCell<Vec<ActiveTracingSpan>>>);
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
impl ActiveTraceSpanStore {
|
||||
pub fn remove_window_draw(&self) {
|
||||
self
|
||||
.0
|
||||
.borrow_mut()
|
||||
.retain(|t| !matches!(t, ActiveTracingSpan::WindowDraw { id: _, span: _ }));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
#[derive(Debug)]
|
||||
pub enum ActiveTracingSpan {
|
||||
WindowDraw {
|
||||
id: WindowId,
|
||||
span: tracing::span::EnteredSpan,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WindowsStore(RefCell<BTreeMap<WebviewId, WindowWrapper>>);
|
||||
|
||||
// SAFETY: we ensure this type is only used on the main thread.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Send for WindowsStore {}
|
||||
|
||||
// SAFETY: we ensure this type is only used on the main thread.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Sync for WindowsStore {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DispatcherMainThreadContext<T: UserEvent> {
|
||||
pub window_target: EventLoopWindowTarget<Message<T>>,
|
||||
pub web_context: WebContextStore,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
||||
#[cfg(feature = "clipboard")]
|
||||
pub clipboard_manager: Arc<Mutex<Clipboard>>,
|
||||
pub windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
|
||||
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
|
||||
// changing this to an Rc will cause frequent app crashes.
|
||||
pub windows: Arc<WindowsStore>,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: SystemTrayManager,
|
||||
#[cfg(feature = "tracing")]
|
||||
pub active_tracing_spans: ActiveTraceSpanStore,
|
||||
}
|
||||
|
||||
// SAFETY: we ensure this type is only used on the main thread.
|
||||
@@ -718,6 +751,9 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
.inner_size(config.width, config.height)
|
||||
.visible(config.visible)
|
||||
.resizable(config.resizable)
|
||||
.maximizable(config.maximizable)
|
||||
.minimizable(config.minimizable)
|
||||
.closable(config.closable)
|
||||
.fullscreen(config.fullscreen)
|
||||
.decorations(config.decorations)
|
||||
.maximized(config.maximized)
|
||||
@@ -816,6 +852,21 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
self
|
||||
}
|
||||
|
||||
fn maximizable(mut self, maximizable: bool) -> Self {
|
||||
self.inner = self.inner.with_maximizable(maximizable);
|
||||
self
|
||||
}
|
||||
|
||||
fn minimizable(mut self, minimizable: bool) -> Self {
|
||||
self.inner = self.inner.with_minimizable(minimizable);
|
||||
self
|
||||
}
|
||||
|
||||
fn closable(mut self, closable: bool) -> Self {
|
||||
self.inner = self.inner.with_closable(closable);
|
||||
self
|
||||
}
|
||||
|
||||
fn title<S: Into<String>>(mut self, title: S) -> Self {
|
||||
self.inner = self.inner.with_title(title.into());
|
||||
self
|
||||
@@ -1055,8 +1106,12 @@ pub enum WindowMessage {
|
||||
IsFullscreen(Sender<bool>),
|
||||
IsMinimized(Sender<bool>),
|
||||
IsMaximized(Sender<bool>),
|
||||
IsFocused(Sender<bool>),
|
||||
IsDecorated(Sender<bool>),
|
||||
IsResizable(Sender<bool>),
|
||||
IsMaximizable(Sender<bool>),
|
||||
IsMinimizable(Sender<bool>),
|
||||
IsClosable(Sender<bool>),
|
||||
IsVisible(Sender<bool>),
|
||||
Title(Sender<String>),
|
||||
IsMenuVisible(Sender<bool>),
|
||||
@@ -1077,6 +1132,9 @@ pub enum WindowMessage {
|
||||
Center,
|
||||
RequestUserAttention(Option<UserAttentionTypeWrapper>),
|
||||
SetResizable(bool),
|
||||
SetMaximizable(bool),
|
||||
SetMinimizable(bool),
|
||||
SetClosable(bool),
|
||||
SetTitle(String),
|
||||
Maximize,
|
||||
Unmaximize,
|
||||
@@ -1110,7 +1168,10 @@ pub enum WindowMessage {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WebviewMessage {
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
EvaluateScript(String),
|
||||
#[cfg(feature = "tracing")]
|
||||
EvaluateScript(String, Sender<()>, tracing::Span),
|
||||
#[allow(dead_code)]
|
||||
WebviewEvent(WebviewEvent),
|
||||
Print,
|
||||
@@ -1157,8 +1218,6 @@ pub enum Message<T: 'static> {
|
||||
),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
GlobalShortcut(GlobalShortcutMessage),
|
||||
#[cfg(feature = "clipboard")]
|
||||
Clipboard(ClipboardMessage),
|
||||
UserEvent(T),
|
||||
}
|
||||
|
||||
@@ -1170,8 +1229,6 @@ impl<T: UserEvent> Clone for Message<T> {
|
||||
Self::Tray(i, m) => Self::Tray(*i, m.clone()),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()),
|
||||
#[cfg(feature = "clipboard")]
|
||||
Self::Clipboard(m) => Self::Clipboard(m.clone()),
|
||||
Self::UserEvent(t) => Self::UserEvent(t.clone()),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
@@ -1285,6 +1342,10 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
||||
window_getter!(self, WindowMessage::IsMaximized)
|
||||
}
|
||||
|
||||
fn is_focused(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsFocused)
|
||||
}
|
||||
|
||||
/// Gets the window’s current decoration state.
|
||||
fn is_decorated(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsDecorated)
|
||||
@@ -1295,6 +1356,21 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
||||
window_getter!(self, WindowMessage::IsResizable)
|
||||
}
|
||||
|
||||
/// Gets the current native window's maximize button state
|
||||
fn is_maximizable(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsMaximizable)
|
||||
}
|
||||
|
||||
/// Gets the current native window's minimize button state
|
||||
fn is_minimizable(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsMinimizable)
|
||||
}
|
||||
|
||||
/// Gets the current native window's close button state
|
||||
fn is_closable(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsClosable)
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> Result<bool> {
|
||||
window_getter!(self, WindowMessage::IsVisible)
|
||||
}
|
||||
@@ -1386,6 +1462,27 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
||||
)
|
||||
}
|
||||
|
||||
fn set_maximizable(&self, maximizable: bool) -> Result<()> {
|
||||
send_user_message(
|
||||
&self.context,
|
||||
Message::Window(self.window_id, WindowMessage::SetMaximizable(maximizable)),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_minimizable(&self, minimizable: bool) -> Result<()> {
|
||||
send_user_message(
|
||||
&self.context,
|
||||
Message::Window(self.window_id, WindowMessage::SetMinimizable(minimizable)),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_closable(&self, closable: bool) -> Result<()> {
|
||||
send_user_message(
|
||||
&self.context,
|
||||
Message::Window(self.window_id, WindowMessage::SetClosable(closable)),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_title<S: Into<String>>(&self, title: S) -> Result<()> {
|
||||
send_user_message(
|
||||
&self.context,
|
||||
@@ -1586,6 +1683,21 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
|
||||
// use a channel so the EvaluateScript task uses the current span as parent
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::Webview(
|
||||
self.window_id,
|
||||
WebviewMessage::EvaluateScript(script.into(), tx, tracing::Span::current()),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
|
||||
send_user_message(
|
||||
&self.context,
|
||||
@@ -1607,7 +1719,7 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
||||
#[derive(Clone)]
|
||||
enum WindowHandle {
|
||||
Webview {
|
||||
inner: Arc<WebView>,
|
||||
inner: Rc<WebView>,
|
||||
context_store: WebContextStore,
|
||||
// the key of the WebContext if it's not shared
|
||||
context_key: Option<PathBuf>,
|
||||
@@ -1623,7 +1735,7 @@ impl Drop for WindowHandle {
|
||||
context_key,
|
||||
} = self
|
||||
{
|
||||
if Arc::get_mut(inner).is_some() {
|
||||
if Rc::get_mut(inner).is_some() {
|
||||
context_store.lock().unwrap().remove(context_key);
|
||||
}
|
||||
}
|
||||
@@ -1718,7 +1830,7 @@ pub struct Wry<T: UserEvent> {
|
||||
global_shortcut_manager_handle: GlobalShortcutManagerHandle<T>,
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager_handle: ClipboardManagerWrapper<T>,
|
||||
clipboard_manager_handle: ClipboardManagerWrapper,
|
||||
|
||||
event_loop: EventLoop<Message<T>>,
|
||||
}
|
||||
@@ -1749,11 +1861,7 @@ impl<T: UserEvent> fmt::Debug for Wry<T> {
|
||||
);
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
d.field(
|
||||
"clipboard_manager",
|
||||
&self.context.main_thread.clipboard_manager,
|
||||
)
|
||||
.field("clipboard_manager_handle", &self.clipboard_manager_handle);
|
||||
d.field("clipboard_manager_handle", &self.clipboard_manager_handle);
|
||||
|
||||
d.finish()
|
||||
}
|
||||
@@ -1872,12 +1980,10 @@ impl<T: UserEvent> Wry<T> {
|
||||
let web_context = WebContextStore::default();
|
||||
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
|
||||
let global_shortcut_manager = Rc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
|
||||
let windows = Arc::new(WindowsStore(RefCell::new(BTreeMap::default())));
|
||||
|
||||
let windows = Arc::new(RefCell::new(HashMap::default()));
|
||||
let webview_id_map = WebviewIdStore::default();
|
||||
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
@@ -1892,11 +1998,11 @@ impl<T: UserEvent> Wry<T> {
|
||||
web_context,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager,
|
||||
windows,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager,
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans: Default::default(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1910,7 +2016,7 @@ impl<T: UserEvent> Wry<T> {
|
||||
#[cfg(feature = "clipboard")]
|
||||
#[allow(clippy::redundant_clone)]
|
||||
let clipboard_manager_handle = ClipboardManagerWrapper {
|
||||
context: context.clone(),
|
||||
clipboard: Arc::new(Mutex::new(Clipboard::new())),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@@ -1943,7 +2049,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
type GlobalShortcutManager = GlobalShortcutManagerHandle<T>;
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
type ClipboardManager = ClipboardManagerWrapper<T>;
|
||||
type ClipboardManager = ClipboardManagerWrapper;
|
||||
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
type TrayHandler = SystemTrayHandle<T>;
|
||||
@@ -1987,7 +2093,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
|
||||
fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>> {
|
||||
let label = pending.label.clone();
|
||||
let current_url = pending.current_url.clone();
|
||||
let menu_ids = pending.menu_ids.clone();
|
||||
let js_event_listeners = pending.js_event_listeners.clone();
|
||||
let window_id = rand::random();
|
||||
@@ -2009,12 +2114,12 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
.context
|
||||
.main_thread
|
||||
.windows
|
||||
.0
|
||||
.borrow_mut()
|
||||
.insert(window_id, webview);
|
||||
|
||||
Ok(DetachedWindow {
|
||||
label,
|
||||
current_url,
|
||||
dispatcher,
|
||||
menu_ids,
|
||||
js_event_listeners,
|
||||
@@ -2026,7 +2131,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
let id = system_tray.id;
|
||||
let mut listeners = Vec::new();
|
||||
if let Some(l) = system_tray.on_event.take() {
|
||||
listeners.push(Arc::new(l));
|
||||
listeners.push(Rc::new(l));
|
||||
}
|
||||
let (tray, items) = create_tray(WryTrayId(id), system_tray, &self.event_loop)?;
|
||||
self
|
||||
@@ -2039,9 +2144,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
.insert(
|
||||
id,
|
||||
TrayContext {
|
||||
tray: Arc::new(Mutex::new(Some(tray))),
|
||||
listeners: Arc::new(Mutex::new(listeners)),
|
||||
items: Arc::new(Mutex::new(items)),
|
||||
tray: Rc::new(RefCell::new(Some(tray))),
|
||||
listeners: Rc::new(RefCell::new(listeners)),
|
||||
items: Rc::new(RefCell::new(items)),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -2102,13 +2207,14 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
let system_tray_manager = self.context.main_thread.system_tray_manager.clone();
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
|
||||
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
let global_shortcut_manager = self.context.main_thread.global_shortcut_manager.clone();
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
|
||||
let mut iteration = RunIteration::default();
|
||||
|
||||
let proxy = self.event_loop.create_proxy();
|
||||
@@ -2135,10 +2241,10 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager_handle: &global_shortcut_manager_handle,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: system_tray_manager.clone(),
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans: active_tracing_spans.clone(),
|
||||
},
|
||||
web_context,
|
||||
);
|
||||
@@ -2159,10 +2265,10 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager_handle: &global_shortcut_manager_handle,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: system_tray_manager.clone(),
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans: active_tracing_spans.clone(),
|
||||
},
|
||||
web_context,
|
||||
);
|
||||
@@ -2177,6 +2283,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
let web_context = self.context.main_thread.web_context;
|
||||
let mut plugins = self.plugins;
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
|
||||
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
let system_tray_manager = self.context.main_thread.system_tray_manager;
|
||||
|
||||
@@ -2185,9 +2294,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
|
||||
|
||||
let proxy = self.event_loop.create_proxy();
|
||||
|
||||
self.event_loop.run(move |event, event_loop, control_flow| {
|
||||
@@ -2205,10 +2311,10 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager_handle: &global_shortcut_manager_handle,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: system_tray_manager.clone(),
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans: active_tracing_spans.clone(),
|
||||
},
|
||||
&web_context,
|
||||
);
|
||||
@@ -2228,10 +2334,10 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager_handle: &global_shortcut_manager_handle,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: system_tray_manager.clone(),
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans: active_tracing_spans.clone(),
|
||||
},
|
||||
&web_context,
|
||||
);
|
||||
@@ -2242,24 +2348,22 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
pub struct EventLoopIterationContext<'a, T: UserEvent> {
|
||||
pub callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
|
||||
pub webview_id_map: WebviewIdStore,
|
||||
pub windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
|
||||
pub windows: Arc<WindowsStore>,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
||||
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
pub global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
|
||||
#[cfg(feature = "clipboard")]
|
||||
pub clipboard_manager: Arc<Mutex<Clipboard>>,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
pub system_tray_manager: SystemTrayManager,
|
||||
#[cfg(feature = "tracing")]
|
||||
pub active_tracing_spans: ActiveTraceSpanStore,
|
||||
}
|
||||
|
||||
struct UserMessageContext {
|
||||
windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
|
||||
windows: Arc<WindowsStore>,
|
||||
webview_id_map: WebviewIdStore,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager: Arc<Mutex<Clipboard>>,
|
||||
global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager: SystemTrayManager,
|
||||
}
|
||||
@@ -2274,8 +2378,6 @@ fn handle_user_message<T: UserEvent>(
|
||||
webview_id_map,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager,
|
||||
windows,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager,
|
||||
@@ -2293,7 +2395,12 @@ fn handle_user_message<T: UserEvent>(
|
||||
},
|
||||
Message::Window(id, window_message) => {
|
||||
if let WindowMessage::UpdateMenuItem(item_id, update) = window_message {
|
||||
if let Some(menu_items) = windows.borrow_mut().get_mut(&id).map(|w| &mut w.menu_items) {
|
||||
if let Some(menu_items) = windows
|
||||
.0
|
||||
.borrow_mut()
|
||||
.get_mut(&id)
|
||||
.map(|w| &mut w.menu_items)
|
||||
{
|
||||
if let Some(menu_items) = menu_items.as_mut() {
|
||||
let item = menu_items.get_mut(&item_id).expect("menu item not found");
|
||||
match update {
|
||||
@@ -2308,7 +2415,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let w = windows.borrow().get(&id).map(|w| {
|
||||
let w = windows.0.borrow().get(&id).map(|w| {
|
||||
(
|
||||
w.inner.clone(),
|
||||
w.window_event_listeners.clone(),
|
||||
@@ -2410,8 +2517,12 @@ fn handle_user_message<T: UserEvent>(
|
||||
WindowMessage::IsFullscreen(tx) => tx.send(window.fullscreen().is_some()).unwrap(),
|
||||
WindowMessage::IsMinimized(tx) => tx.send(window.is_minimized()).unwrap(),
|
||||
WindowMessage::IsMaximized(tx) => tx.send(window.is_maximized()).unwrap(),
|
||||
WindowMessage::IsFocused(tx) => tx.send(window.is_focused()).unwrap(),
|
||||
WindowMessage::IsDecorated(tx) => tx.send(window.is_decorated()).unwrap(),
|
||||
WindowMessage::IsResizable(tx) => tx.send(window.is_resizable()).unwrap(),
|
||||
WindowMessage::IsMaximizable(tx) => tx.send(window.is_maximizable()).unwrap(),
|
||||
WindowMessage::IsMinimizable(tx) => tx.send(window.is_minimizable()).unwrap(),
|
||||
WindowMessage::IsClosable(tx) => tx.send(window.is_closable()).unwrap(),
|
||||
WindowMessage::IsVisible(tx) => tx.send(window.is_visible()).unwrap(),
|
||||
WindowMessage::Title(tx) => tx.send(window.title()).unwrap(),
|
||||
WindowMessage::IsMenuVisible(tx) => tx.send(window.is_menu_visible()).unwrap(),
|
||||
@@ -2444,6 +2555,9 @@ fn handle_user_message<T: UserEvent>(
|
||||
window.request_user_attention(request_type.map(|r| r.0));
|
||||
}
|
||||
WindowMessage::SetResizable(resizable) => window.set_resizable(resizable),
|
||||
WindowMessage::SetMaximizable(maximizable) => window.set_maximizable(maximizable),
|
||||
WindowMessage::SetMinimizable(minimizable) => window.set_minimizable(minimizable),
|
||||
WindowMessage::SetClosable(closable) => window.set_closable(closable),
|
||||
WindowMessage::SetTitle(title) => window.set_title(&title),
|
||||
WindowMessage::Maximize => window.set_maximized(true),
|
||||
WindowMessage::Unmaximize => window.set_maximized(false),
|
||||
@@ -2520,9 +2634,22 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
}
|
||||
Message::Webview(id, webview_message) => match webview_message {
|
||||
#[cfg(feature = "tracing")]
|
||||
WebviewMessage::EvaluateScript(script, tx, span) => {
|
||||
let _span = span.entered();
|
||||
if let Some(WindowHandle::Webview { inner: webview, .. }) =
|
||||
windows.0.borrow().get(&id).and_then(|w| w.inner.as_ref())
|
||||
{
|
||||
if let Err(e) = webview.evaluate_script(&script) {
|
||||
debug_eprintln!("{}", e);
|
||||
}
|
||||
}
|
||||
tx.send(()).unwrap();
|
||||
}
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
WebviewMessage::EvaluateScript(script) => {
|
||||
if let Some(WindowHandle::Webview { inner: webview, .. }) =
|
||||
windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
|
||||
windows.0.borrow().get(&id).and_then(|w| w.inner.as_ref())
|
||||
{
|
||||
if let Err(e) = webview.evaluate_script(&script) {
|
||||
debug_eprintln!("{}", e);
|
||||
@@ -2531,7 +2658,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
WebviewMessage::Print => {
|
||||
if let Some(WindowHandle::Webview { inner: webview, .. }) =
|
||||
windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
|
||||
windows.0.borrow().get(&id).and_then(|w| w.inner.as_ref())
|
||||
{
|
||||
let _ = webview.print();
|
||||
}
|
||||
@@ -2540,7 +2667,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
},
|
||||
Message::CreateWebview(window_id, handler) => match handler(event_loop, web_context) {
|
||||
Ok(webview) => {
|
||||
windows.borrow_mut().insert(window_id, webview);
|
||||
windows.0.borrow_mut().insert(window_id, webview);
|
||||
}
|
||||
Err(e) => {
|
||||
debug_eprintln!("{}", e);
|
||||
@@ -2553,7 +2680,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
|
||||
let w = Arc::new(window);
|
||||
|
||||
windows.borrow_mut().insert(
|
||||
windows.0.borrow_mut().insert(
|
||||
window_id,
|
||||
WindowWrapper {
|
||||
label,
|
||||
@@ -2576,16 +2703,16 @@ fn handle_user_message<T: UserEvent>(
|
||||
if let TrayMessage::Create(mut tray, tx) = tray_message {
|
||||
let mut listeners = Vec::new();
|
||||
if let Some(l) = tray.on_event.take() {
|
||||
listeners.push(Arc::new(l));
|
||||
listeners.push(Rc::new(l));
|
||||
}
|
||||
match create_tray(WryTrayId(tray_id), tray, event_loop) {
|
||||
Ok((tray, items)) => {
|
||||
trays.insert(
|
||||
tray_id,
|
||||
TrayContext {
|
||||
tray: Arc::new(Mutex::new(Some(tray))),
|
||||
listeners: Arc::new(Mutex::new(listeners)),
|
||||
items: Arc::new(Mutex::new(items)),
|
||||
tray: Rc::new(RefCell::new(Some(tray))),
|
||||
listeners: Rc::new(RefCell::new(listeners)),
|
||||
items: Rc::new(RefCell::new(items)),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -2599,7 +2726,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
} else if let Some(tray_context) = trays.get(&tray_id) {
|
||||
match tray_message {
|
||||
TrayMessage::UpdateItem(menu_id, update) => {
|
||||
let mut tray = tray_context.items.as_ref().lock().unwrap();
|
||||
let mut tray = tray_context.items.as_ref().borrow_mut();
|
||||
let item = tray.get_mut(&menu_id).expect("menu item not found");
|
||||
match update {
|
||||
MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled),
|
||||
@@ -2612,14 +2739,14 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
}
|
||||
TrayMessage::UpdateMenu(menu) => {
|
||||
if let Some(tray) = &mut *tray_context.tray.lock().unwrap() {
|
||||
if let Some(tray) = &mut *tray_context.tray.borrow_mut() {
|
||||
let mut items = HashMap::new();
|
||||
tray.set_menu(&to_wry_context_menu(&mut items, menu));
|
||||
*tray_context.items.lock().unwrap() = items;
|
||||
*tray_context.items.borrow_mut() = items;
|
||||
}
|
||||
}
|
||||
TrayMessage::UpdateIcon(icon) => {
|
||||
if let Some(tray) = &mut *tray_context.tray.lock().unwrap() {
|
||||
if let Some(tray) = &mut *tray_context.tray.borrow_mut() {
|
||||
if let Ok(icon) = TrayIcon::try_from(icon) {
|
||||
tray.set_icon(icon.0);
|
||||
}
|
||||
@@ -2627,18 +2754,18 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
TrayMessage::UpdateIconAsTemplate(is_template) => {
|
||||
if let Some(tray) = &mut *tray_context.tray.lock().unwrap() {
|
||||
if let Some(tray) = &mut *tray_context.tray.borrow_mut() {
|
||||
tray.set_icon_as_template(is_template);
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
TrayMessage::UpdateTitle(title) => {
|
||||
if let Some(tray) = &mut *tray_context.tray.lock().unwrap() {
|
||||
if let Some(tray) = &mut *tray_context.tray.borrow_mut() {
|
||||
tray.set_title(&title);
|
||||
}
|
||||
}
|
||||
TrayMessage::UpdateTooltip(tooltip) => {
|
||||
if let Some(tray) = &mut *tray_context.tray.lock().unwrap() {
|
||||
if let Some(tray) = &mut *tray_context.tray.borrow_mut() {
|
||||
tray.set_tooltip(&tooltip);
|
||||
}
|
||||
}
|
||||
@@ -2646,9 +2773,9 @@ fn handle_user_message<T: UserEvent>(
|
||||
// already handled
|
||||
}
|
||||
TrayMessage::Destroy(tx) => {
|
||||
*tray_context.tray.lock().unwrap() = None;
|
||||
tray_context.listeners.lock().unwrap().clear();
|
||||
tray_context.items.lock().unwrap().clear();
|
||||
*tray_context.tray.borrow_mut() = None;
|
||||
tray_context.listeners.borrow_mut().clear();
|
||||
tray_context.items.borrow_mut().clear();
|
||||
tx.send(Ok(())).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -2658,13 +2785,11 @@ fn handle_user_message<T: UserEvent>(
|
||||
Message::GlobalShortcut(message) => {
|
||||
handle_global_shortcut_message(message, &global_shortcut_manager)
|
||||
}
|
||||
#[cfg(feature = "clipboard")]
|
||||
Message::Clipboard(message) => handle_clipboard_message(message, &clipboard_manager),
|
||||
Message::UserEvent(_) => (),
|
||||
}
|
||||
|
||||
let it = RunIteration {
|
||||
window_count: windows.borrow().len(),
|
||||
window_count: windows.0.borrow().len(),
|
||||
};
|
||||
it
|
||||
}
|
||||
@@ -2684,10 +2809,10 @@ fn handle_event_loop<T: UserEvent>(
|
||||
global_shortcut_manager,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager_handle,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager,
|
||||
#[cfg(feature = "tracing")]
|
||||
active_tracing_spans,
|
||||
} = context;
|
||||
if *control_flow != ControlFlow::Exit {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
@@ -2710,6 +2835,11 @@ fn handle_event_loop<T: UserEvent>(
|
||||
callback(RunEvent::Exit);
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
Event::RedrawEventsCleared => {
|
||||
active_tracing_spans.remove_window_draw();
|
||||
}
|
||||
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
Event::GlobalShortcutEvent(accelerator_id) => {
|
||||
for (id, handler) in &*global_shortcut_manager_handle.listeners.lock().unwrap() {
|
||||
@@ -2747,6 +2877,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
*webview_id_map.0.lock().unwrap().values().next().unwrap()
|
||||
};
|
||||
windows
|
||||
.0
|
||||
.borrow()
|
||||
.get(&window_id)
|
||||
.unwrap()
|
||||
@@ -2774,11 +2905,11 @@ fn handle_event_loop<T: UserEvent>(
|
||||
let (mut listeners, mut tray_id) = (None, 0);
|
||||
for (id, tray_context) in trays_iter {
|
||||
let has_menu = {
|
||||
let items = tray_context.items.lock().unwrap();
|
||||
let items = tray_context.items.borrow();
|
||||
items.contains_key(&menu_id.0)
|
||||
};
|
||||
if has_menu {
|
||||
listeners.replace(tray_context.listeners.lock().unwrap().clone());
|
||||
listeners.replace(tray_context.listeners.borrow().clone());
|
||||
tray_id = *id;
|
||||
break;
|
||||
}
|
||||
@@ -2817,7 +2948,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
};
|
||||
let trays = system_tray_manager.trays.lock().unwrap();
|
||||
if let Some(tray_context) = trays.get(&id.0) {
|
||||
let listeners = tray_context.listeners.lock().unwrap();
|
||||
let listeners = tray_context.listeners.borrow();
|
||||
let iter = listeners.iter();
|
||||
for handler in iter {
|
||||
handler(&event);
|
||||
@@ -2832,7 +2963,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
}
|
||||
Event::UserEvent(Message::Webview(id, WebviewMessage::WebviewEvent(event))) => {
|
||||
if let Some(event) = WindowEventWrapper::from(&event).0 {
|
||||
let windows = windows.borrow();
|
||||
let windows = windows.0.borrow();
|
||||
let window = windows.get(&id);
|
||||
if let Some(window) = window {
|
||||
callback(RunEvent::WindowEvent {
|
||||
@@ -2853,7 +2984,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
} => {
|
||||
if let Some(window_id) = webview_id_map.get(&window_id) {
|
||||
{
|
||||
let windows_ref = windows.borrow();
|
||||
let windows_ref = windows.0.borrow();
|
||||
if let Some(window) = windows_ref.get(&window_id) {
|
||||
if let Some(event) = WindowEventWrapper::parse(&window.inner, &event).0 {
|
||||
let label = window.label.clone();
|
||||
@@ -2877,7 +3008,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
match event {
|
||||
#[cfg(windows)]
|
||||
WryWindowEvent::ThemeChanged(theme) => {
|
||||
if let Some(window) = windows.borrow().get(&window_id) {
|
||||
if let Some(window) = windows.0.borrow().get(&window_id) {
|
||||
if let Some(WindowHandle::Webview { inner, .. }) = &window.inner {
|
||||
let theme = match theme {
|
||||
WryTheme::Dark => wry::webview::Theme::Dark,
|
||||
@@ -2892,9 +3023,9 @@ fn handle_event_loop<T: UserEvent>(
|
||||
on_close_requested(callback, window_id, windows.clone());
|
||||
}
|
||||
WryWindowEvent::Destroyed => {
|
||||
let removed = windows.borrow_mut().remove(&window_id).is_some();
|
||||
let removed = windows.0.borrow_mut().remove(&window_id).is_some();
|
||||
if removed {
|
||||
let is_empty = windows.borrow().is_empty();
|
||||
let is_empty = windows.0.borrow().is_empty();
|
||||
if is_empty {
|
||||
let (tx, rx) = channel();
|
||||
callback(RunEvent::ExitRequested { tx });
|
||||
@@ -2925,8 +3056,6 @@ fn handle_event_loop<T: UserEvent>(
|
||||
webview_id_map,
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
global_shortcut_manager,
|
||||
#[cfg(feature = "clipboard")]
|
||||
clipboard_manager,
|
||||
windows,
|
||||
#[cfg(all(desktop, feature = "system-tray"))]
|
||||
system_tray_manager,
|
||||
@@ -2939,7 +3068,7 @@ fn handle_event_loop<T: UserEvent>(
|
||||
}
|
||||
|
||||
let it = RunIteration {
|
||||
window_count: windows.borrow().len(),
|
||||
window_count: windows.0.borrow().len(),
|
||||
};
|
||||
it
|
||||
}
|
||||
@@ -2947,10 +3076,10 @@ fn handle_event_loop<T: UserEvent>(
|
||||
fn on_close_requested<'a, T: UserEvent>(
|
||||
callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
|
||||
window_id: WebviewId,
|
||||
windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
|
||||
windows: Arc<WindowsStore>,
|
||||
) {
|
||||
let (tx, rx) = channel();
|
||||
let windows_ref = windows.borrow();
|
||||
let windows_ref = windows.0.borrow();
|
||||
if let Some(w) = windows_ref.get(&window_id) {
|
||||
let label = w.label.clone();
|
||||
let window_event_listeners = w.window_event_listeners.clone();
|
||||
@@ -2975,8 +3104,8 @@ fn on_close_requested<'a, T: UserEvent>(
|
||||
}
|
||||
}
|
||||
|
||||
fn on_window_close(window_id: WebviewId, windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>) {
|
||||
if let Some(mut window_wrapper) = windows.borrow_mut().get_mut(&window_id) {
|
||||
fn on_window_close(window_id: WebviewId, windows: Arc<WindowsStore>) {
|
||||
if let Some(window_wrapper) = windows.0.borrow_mut().get_mut(&window_id) {
|
||||
window_wrapper.inner = None;
|
||||
}
|
||||
}
|
||||
@@ -3044,7 +3173,7 @@ fn create_webview<T: UserEvent>(
|
||||
mut window_builder,
|
||||
ipc_handler,
|
||||
label,
|
||||
current_url,
|
||||
url,
|
||||
menu_ids,
|
||||
js_event_listeners,
|
||||
..
|
||||
@@ -3053,6 +3182,14 @@ fn create_webview<T: UserEvent>(
|
||||
#[cfg(windows)]
|
||||
let proxy = context.proxy.clone();
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
let _webview_create_span = tracing::debug_span!("wry::webview::create").entered();
|
||||
#[cfg(feature = "tracing")]
|
||||
let window_draw_span = tracing::debug_span!("wry::window::draw").entered();
|
||||
#[cfg(feature = "tracing")]
|
||||
let window_create_span =
|
||||
tracing::debug_span!(parent: &window_draw_span, "wry::window::create").entered();
|
||||
|
||||
let window_event_listeners = WindowEventListeners::default();
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -3084,8 +3221,24 @@ fn create_webview<T: UserEvent>(
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let focused = window_builder.inner.window.focused;
|
||||
let window = window_builder.inner.build(event_loop).unwrap();
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
{
|
||||
drop(window_create_span);
|
||||
|
||||
context
|
||||
.main_thread
|
||||
.active_tracing_spans
|
||||
.0
|
||||
.borrow_mut()
|
||||
.push(ActiveTracingSpan::WindowDraw {
|
||||
id: window.id(),
|
||||
span: window_draw_span,
|
||||
});
|
||||
}
|
||||
|
||||
webview_id_map.insert(window.id(), window_id);
|
||||
|
||||
if window_builder.center {
|
||||
@@ -3093,7 +3246,8 @@ fn create_webview<T: UserEvent>(
|
||||
}
|
||||
let mut webview_builder = WebViewBuilder::new(window)
|
||||
.map_err(|e| Error::CreateWebview(Box::new(e)))?
|
||||
.with_url(current_url.lock().unwrap().as_str())
|
||||
.with_focused(focused)
|
||||
.with_url(&url)
|
||||
.unwrap() // safe to unwrap because we validate the URL beforehand
|
||||
.with_transparent(is_window_transparent)
|
||||
.with_accept_first_mouse(webview_attributes.accept_first_mouse);
|
||||
@@ -3124,11 +3278,15 @@ fn create_webview<T: UserEvent>(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
webview_builder = webview_builder.with_https_scheme(!pending.http_scheme);
|
||||
}
|
||||
|
||||
if let Some(handler) = ipc_handler {
|
||||
webview_builder = webview_builder.with_ipc_handler(create_ipc_handler(
|
||||
context,
|
||||
label.clone(),
|
||||
current_url,
|
||||
menu_ids,
|
||||
js_event_listeners,
|
||||
handler,
|
||||
@@ -3221,7 +3379,7 @@ fn create_webview<T: UserEvent>(
|
||||
Ok(WindowWrapper {
|
||||
label,
|
||||
inner: Some(WindowHandle::Webview {
|
||||
inner: Arc::new(webview),
|
||||
inner: Rc::new(webview),
|
||||
context_store: web_context_store.clone(),
|
||||
context_key: if automation_enabled {
|
||||
None
|
||||
@@ -3239,16 +3397,14 @@ fn create_webview<T: UserEvent>(
|
||||
fn create_ipc_handler<T: UserEvent>(
|
||||
context: Context<T>,
|
||||
label: String,
|
||||
current_url: Arc<Mutex<Url>>,
|
||||
menu_ids: Arc<Mutex<HashMap<MenuHash, MenuId>>>,
|
||||
js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u64>>>>,
|
||||
js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u32>>>>,
|
||||
handler: WebviewIpcHandler<T, Wry<T>>,
|
||||
) -> Box<IpcHandler> {
|
||||
Box::new(move |window, request| {
|
||||
let window_id = context.webview_id_map.get(&window.id()).unwrap();
|
||||
handler(
|
||||
DetachedWindow {
|
||||
current_url: current_url.clone(),
|
||||
dispatcher: WryDispatcher {
|
||||
window_id,
|
||||
context: context.clone(),
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pub use tauri_runtime::{
|
||||
menu::{
|
||||
Menu, MenuEntry, MenuItem, MenuUpdate, Submenu, SystemTrayMenu, SystemTrayMenuEntry,
|
||||
SystemTrayMenuItem, TrayHandle,
|
||||
},
|
||||
menu::{MenuUpdate, SystemTrayMenu, SystemTrayMenuEntry, SystemTrayMenuItem, TrayHandle},
|
||||
Icon, SystemTrayEvent,
|
||||
};
|
||||
use wry::application::event_loop::EventLoopWindowTarget;
|
||||
@@ -32,8 +29,10 @@ use crate::{send_user_message, Context, Error, Message, Result, TrayId, TrayMess
|
||||
use tauri_runtime::{menu::MenuHash, SystemTray, UserEvent};
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
@@ -41,12 +40,12 @@ pub type GlobalSystemTrayEventHandler = Box<dyn Fn(TrayId, &SystemTrayEvent) + S
|
||||
pub type GlobalSystemTrayEventListeners = Arc<Mutex<Vec<Arc<GlobalSystemTrayEventHandler>>>>;
|
||||
|
||||
pub type SystemTrayEventHandler = Box<dyn Fn(&SystemTrayEvent) + Send>;
|
||||
pub type SystemTrayEventListeners = Arc<Mutex<Vec<Arc<SystemTrayEventHandler>>>>;
|
||||
pub type SystemTrayItems = Arc<Mutex<HashMap<u16, WryCustomMenuItem>>>;
|
||||
pub type SystemTrayEventListeners = Rc<RefCell<Vec<Rc<SystemTrayEventHandler>>>>;
|
||||
pub type SystemTrayItems = Rc<RefCell<HashMap<u16, WryCustomMenuItem>>>;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct TrayContext {
|
||||
pub tray: Arc<Mutex<Option<WrySystemTray>>>,
|
||||
pub tray: Rc<RefCell<Option<WrySystemTray>>>,
|
||||
pub listeners: SystemTrayEventListeners,
|
||||
pub items: SystemTrayItems,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# Changelog
|
||||
|
||||
## \[0.14.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
|
||||
## \[0.14.2]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
|
||||
## \[0.14.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
|
||||
## \[0.14.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` methods to `WindowBuilder`.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added `set_maximizable`, `set_minimizable`, `set_closable`, `is_maximizable`, `is_minimizable` and `is_closable` methods to the `Dispatch` trait.
|
||||
- [`000104bc`](https://www.github.com/tauri-apps/tauri/commit/000104bc3bc0c9ff3d20558ab9cf2080f126e9e0)([#6472](https://www.github.com/tauri-apps/tauri/pull/6472)) Add `Window::is_focused` getter.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`2b487c94`](https://www.github.com/tauri-apps/tauri/commit/2b487c946737352187d7e042dd6142873e62a4ca)([#7012](https://www.github.com/tauri-apps/tauri/pull/7012)) Fixes typo in `CursorIcon` deserialization of the `ZoomIn` variant.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`076e1a81`](https://www.github.com/tauri-apps/tauri/commit/076e1a81a50468e3dfb34ae9ca7e77c5e1758daa)([#7119](https://www.github.com/tauri-apps/tauri/pull/7119)) Use `u32` instead of `u64` for js event listener ids
|
||||
- [`ff5e4dbb`](https://www.github.com/tauri-apps/tauri/commit/ff5e4dbbb01bf3fc9c5143df732c75eef6fd98cb)([#6794](https://www.github.com/tauri-apps/tauri/pull/6794)) impl `From<&WindowConfig>` for `WebviewAttributes`.
|
||||
|
||||
## \[0.13.0]
|
||||
|
||||
- Added the `additional_browser_args` option when creating a window.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-runtime"
|
||||
version = "0.13.0"
|
||||
version = "0.14.3"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
@@ -26,11 +26,11 @@ targets = [
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
serde_json = "1.0"
|
||||
thiserror = "1.0"
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
tauri-utils = { version = "1.5.4", path = "../tauri-utils" }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
http = "0.2.4"
|
||||
http-range = "0.1.4"
|
||||
raw-window-handle = "=0.5.0"
|
||||
raw-window-handle = "0.5"
|
||||
rand = "0.8"
|
||||
url = { version = "2" }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
|
||||
@@ -252,6 +252,9 @@ pub enum Error {
|
||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||
#[error(transparent)]
|
||||
GlobalShortcut(Box<dyn std::error::Error + Send + Sync>),
|
||||
#[cfg(all(desktop, feature = "clipboard"))]
|
||||
#[error(transparent)]
|
||||
Clipboard(Box<dyn std::error::Error + Send + Sync>),
|
||||
#[error("Invalid header name: {0}")]
|
||||
InvalidHeaderName(#[from] InvalidHeaderName),
|
||||
#[error("Invalid header value: {0}")]
|
||||
@@ -576,12 +579,36 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
|
||||
/// Gets the window's current maximized state.
|
||||
fn is_maximized(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window's current focus state.
|
||||
fn is_focused(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window’s current decoration state.
|
||||
fn is_decorated(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window’s current resizable state.
|
||||
fn is_resizable(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window's native maximize button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
fn is_maximizable(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window's native minize button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
fn is_minimizable(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window's native close button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
fn is_closable(&self) -> Result<bool>;
|
||||
|
||||
/// Gets the window's current visibility state.
|
||||
fn is_visible(&self) -> Result<bool>;
|
||||
/// Gets the window's current title.
|
||||
@@ -640,6 +667,30 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
|
||||
/// Updates the window resizable flag.
|
||||
fn set_resizable(&self, resizable: bool) -> Result<()>;
|
||||
|
||||
/// Updates the window's native maximize button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
fn set_maximizable(&self, maximizable: bool) -> Result<()>;
|
||||
|
||||
/// Updates the window's native minimize button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
fn set_minimizable(&self, minimizable: bool) -> Result<()>;
|
||||
|
||||
/// Updates the window's native close button state.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
|
||||
/// Depending on the system, this function may not have any effect when called on a window that is already visible"
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
fn set_closable(&self, closable: bool) -> Result<()>;
|
||||
|
||||
/// Updates the window title.
|
||||
fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
|
||||
|
||||
|
||||
@@ -335,6 +335,12 @@ impl Menu {
|
||||
}
|
||||
|
||||
/// Adds the custom menu item to the menu.
|
||||
///
|
||||
/// ## Platform-spcific:
|
||||
///
|
||||
/// - **macOS:** Only [`Submenu`] can be added to the menu
|
||||
///
|
||||
/// [`Submenu`]: crate::Submenu
|
||||
#[must_use]
|
||||
pub fn add_item(mut self, item: CustomMenuItem) -> Self {
|
||||
self.items.push(MenuEntry::CustomItem(item));
|
||||
|
||||
@@ -31,6 +31,23 @@ pub struct WebviewAttributes {
|
||||
pub additional_browser_args: Option<String>,
|
||||
}
|
||||
|
||||
impl From<&WindowConfig> for WebviewAttributes {
|
||||
fn from(config: &WindowConfig) -> Self {
|
||||
let mut builder = Self::new(config.url.clone());
|
||||
builder = builder.accept_first_mouse(config.accept_first_mouse);
|
||||
if !config.file_drop_enabled {
|
||||
builder = builder.disable_file_drop_handler();
|
||||
}
|
||||
if let Some(user_agent) = &config.user_agent {
|
||||
builder = builder.user_agent(user_agent);
|
||||
}
|
||||
if let Some(additional_browser_args) = &config.additional_browser_args {
|
||||
builder = builder.additional_browser_args(additional_browser_args);
|
||||
}
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
||||
impl WebviewAttributes {
|
||||
/// Initializes the default attributes for a webview.
|
||||
pub fn new(url: WindowUrl) -> Self {
|
||||
@@ -140,9 +157,38 @@ pub trait WindowBuilder: WindowBuilderBase {
|
||||
fn max_inner_size(self, max_width: f64, max_height: f64) -> Self;
|
||||
|
||||
/// Whether the window is resizable or not.
|
||||
/// When resizable is set to false, native window's maximize button is automatically disabled.
|
||||
#[must_use]
|
||||
fn resizable(self, resizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native maximize button is enabled or not.
|
||||
/// If resizable is set to false, this setting is ignored.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn maximizable(self, maximizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native minimize button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn minimizable(self, minimizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native close button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
|
||||
/// Depending on the system, this function may not have any effect when called on a window that is already visible"
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn closable(self, closable: bool) -> Self;
|
||||
|
||||
/// The title of the window in the title bar.
|
||||
#[must_use]
|
||||
fn title<S: Into<String>>(self, title: S) -> Self;
|
||||
|
||||
@@ -24,6 +24,8 @@ use std::{
|
||||
type UriSchemeProtocol =
|
||||
dyn Fn(&HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>> + Send + Sync + 'static;
|
||||
|
||||
type WebResourceRequestHandler = dyn Fn(&HttpRequest, &mut HttpResponse) + Send + Sync;
|
||||
|
||||
/// UI scaling utilities.
|
||||
pub mod dpi;
|
||||
|
||||
@@ -182,7 +184,7 @@ impl<'de> Deserialize<'de> for CursorIcon {
|
||||
"grab" => CursorIcon::Grab,
|
||||
"grabbing" => CursorIcon::Grabbing,
|
||||
"allscroll" => CursorIcon::AllScroll,
|
||||
"zoomun" => CursorIcon::ZoomIn,
|
||||
"zoomin" => CursorIcon::ZoomIn,
|
||||
"zoomout" => CursorIcon::ZoomOut,
|
||||
"eresize" => CursorIcon::EResize,
|
||||
"nresize" => CursorIcon::NResize,
|
||||
@@ -222,6 +224,9 @@ pub struct PendingWindow<T: UserEvent, R: Runtime<T>> {
|
||||
|
||||
pub uri_scheme_protocols: HashMap<String, Box<UriSchemeProtocol>>,
|
||||
|
||||
// Whether custom protocols on windows should use http://<scheme>.localhost/ instead of https://<scheme>.localhost/
|
||||
pub http_scheme: bool,
|
||||
|
||||
/// How to handle IPC calls on the webview window.
|
||||
pub ipc_handler: Option<WebviewIpcHandler<T, R>>,
|
||||
|
||||
@@ -229,13 +234,15 @@ pub struct PendingWindow<T: UserEvent, R: Runtime<T>> {
|
||||
pub menu_ids: Arc<Mutex<HashMap<MenuHash, MenuId>>>,
|
||||
|
||||
/// A HashMap mapping JS event names with associated listener ids.
|
||||
pub js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u64>>>>,
|
||||
pub js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u32>>>>,
|
||||
|
||||
/// A handler to decide if incoming url is allowed to navigate.
|
||||
pub navigation_handler: Option<Box<dyn Fn(Url) -> bool + Send>>,
|
||||
|
||||
/// The current webview URL.
|
||||
pub current_url: Arc<Mutex<Url>>,
|
||||
pub web_resource_request_handler: Option<Box<WebResourceRequestHandler>>,
|
||||
|
||||
/// The resolved URL to load on the webview.
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
pub fn is_label_valid(label: &str) -> bool {
|
||||
@@ -275,7 +282,9 @@ impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {
|
||||
menu_ids: Arc::new(Mutex::new(menu_ids)),
|
||||
js_event_listeners: Default::default(),
|
||||
navigation_handler: Default::default(),
|
||||
current_url: Arc::new(Mutex::new("tauri://localhost".parse().unwrap())),
|
||||
web_resource_request_handler: Default::default(),
|
||||
url: "tauri://localhost".to_string(),
|
||||
http_scheme: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -305,7 +314,9 @@ impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {
|
||||
menu_ids: Arc::new(Mutex::new(menu_ids)),
|
||||
js_event_listeners: Default::default(),
|
||||
navigation_handler: Default::default(),
|
||||
current_url: Arc::new(Mutex::new("tauri://localhost".parse().unwrap())),
|
||||
web_resource_request_handler: Default::default(),
|
||||
url: "tauri://localhost".to_string(),
|
||||
http_scheme: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -346,9 +357,6 @@ pub struct JsEventListenerKey {
|
||||
/// A webview window that is not yet managed by Tauri.
|
||||
#[derive(Debug)]
|
||||
pub struct DetachedWindow<T: UserEvent, R: Runtime<T>> {
|
||||
/// The current webview URL.
|
||||
pub current_url: Arc<Mutex<Url>>,
|
||||
|
||||
/// Name of the window
|
||||
pub label: String,
|
||||
|
||||
@@ -359,13 +367,12 @@ pub struct DetachedWindow<T: UserEvent, R: Runtime<T>> {
|
||||
pub menu_ids: Arc<Mutex<HashMap<MenuHash, MenuId>>>,
|
||||
|
||||
/// A HashMap mapping JS event names with associated listener ids.
|
||||
pub js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u64>>>>,
|
||||
pub js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u32>>>>,
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindow<T, R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
current_url: self.current_url.clone(),
|
||||
label: self.label.clone(),
|
||||
dispatcher: self.dispatcher.clone(),
|
||||
menu_ids: self.menu_ids.clone(),
|
||||
|
||||
@@ -1,5 +1,60 @@
|
||||
# Changelog
|
||||
|
||||
## \[1.5.4]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`5ee5ed4dc`](https://www.github.com/tauri-apps/tauri/commit/5ee5ed4dc668aa8b60741b57ffe616a5a7aefd88)([#9680](https://www.github.com/tauri-apps/tauri/pull/9680)) Fixes `schemars` compilation issue.
|
||||
|
||||
## \[1.5.3]
|
||||
|
||||
### New features
|
||||
|
||||
- [`7aa30dec`](https://www.github.com/tauri-apps/tauri/commit/7aa30dec85a17c3d3faaf3841b93e10991b991b0)([#8620](https://www.github.com/tauri-apps/tauri/pull/8620)) Add `priority`, `section` and `changelog` options in Debian config.
|
||||
|
||||
## \[1.5.2]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`9b230de7`](https://www.github.com/tauri-apps/tauri/commit/9b230de7bc6690c2733f5324d50b999af1f7a6ef)([#8407](https://www.github.com/tauri-apps/tauri/pull/8407)) Fix compile error when parsing config that includes float values.
|
||||
|
||||
## \[1.5.3]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`b3e53e72`](https://www.github.com/tauri-apps/tauri/commit/b3e53e7243311a2659b7569dddc20c56ac9f9d8e)([#8288](https://www.github.com/tauri-apps/tauri/pull/8288)) Added `Assets::iter` to iterate on all embedded assets.
|
||||
|
||||
## \[1.5.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`4dd4893d`](https://www.github.com/tauri-apps/tauri/commit/4dd4893d7d166ac3a3b6dc2e3bd2540326352a78)([#5950](https://www.github.com/tauri-apps/tauri/pull/5950)) Allow specifying resources as a map specifying source and target paths.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`a6b52e44`](https://www.github.com/tauri-apps/tauri/commit/a6b52e44f22844009e273fb0250368d7a463f095)([#6519](https://www.github.com/tauri-apps/tauri/pull/6519)) Fix `io::read_line` not including the new line character `\n`.
|
||||
|
||||
### Security fixes
|
||||
|
||||
- [`eeff1784`](https://www.github.com/tauri-apps/tauri/commit/eeff1784e1ffa568e4ba024e17dd611f8e086784)([#7367](https://www.github.com/tauri-apps/tauri/pull/7367)) Changed HTML implementation from unmaintained `kuchiki` to `kuchikiki`.
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`acc36fe1`](https://www.github.com/tauri-apps/tauri/commit/acc36fe1176cc8aa9063bde932abeb94796c5c72)([#6158](https://www.github.com/tauri-apps/tauri/pull/6158)) Add option to configure `require_literal_leading_dot` on `fs` and `asset` protcol scopes.
|
||||
- [`35cd751a`](https://www.github.com/tauri-apps/tauri/commit/35cd751adc6fef1f792696fa0cfb471b0bf99374)([#5176](https://www.github.com/tauri-apps/tauri/pull/5176)) Added the `desktop_template` option on `tauri.conf.json > tauri > bundle > deb`.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` options to the window configuration.
|
||||
- [`3cb7a3e6`](https://www.github.com/tauri-apps/tauri/commit/3cb7a3e642bb10ee90dc1d24daa48b8c8c15c9ce)([#6997](https://www.github.com/tauri-apps/tauri/pull/6997)) Add `MimeType::parse_with_fallback` and `MimeType::parse_from_uri_with_fallback`
|
||||
- [`29488205`](https://www.github.com/tauri-apps/tauri/commit/2948820579d20dfaa0861c2f0a58bd7737a7ffd1)([#6867](https://www.github.com/tauri-apps/tauri/pull/6867)) Allow specifying custom language files of Tauri's custom messages for the NSIS installer
|
||||
- [`e092f799`](https://www.github.com/tauri-apps/tauri/commit/e092f799469ff32c7d1595d0f07d06fd2dab5c29)([#6887](https://www.github.com/tauri-apps/tauri/pull/6887)) Add `nsis > template` option to specify custom NSIS installer template.
|
||||
- [`cd3846c8`](https://www.github.com/tauri-apps/tauri/commit/cd3846c8ce61ab2879b3911e831525e6242aaab2)([#6955](https://www.github.com/tauri-apps/tauri/pull/6955)) Add `WindowsUpdateInstallMode::nsis_args`
|
||||
- [`85e77fb7`](https://www.github.com/tauri-apps/tauri/commit/85e77fb797ec17882f55d0944578d929fc6c9c1f)([#6762](https://www.github.com/tauri-apps/tauri/pull/6762)) Correctly determine MIME type of `.txt` files.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Added the `additional_browser_args` option to the window configuration.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-utils"
|
||||
version = "1.3.0"
|
||||
version = "1.5.4"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
@@ -15,40 +15,35 @@ readme = "README.md"
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_json = "1"
|
||||
thiserror = "1"
|
||||
phf = { version = "0.10", features = [ "macros" ] }
|
||||
phf = { version = "0.11", features = [ "macros" ] }
|
||||
brotli = { version = "3", optional = true, default-features = false, features = [ "std" ] }
|
||||
url = { version = "2", features = [ "serde" ] }
|
||||
kuchiki = "0.8"
|
||||
html5ever = "0.25"
|
||||
html5ever = "0.26"
|
||||
kuchiki = { package = "kuchikiki", version = "0.8" }
|
||||
proc-macro2 = { version = "1", optional = true }
|
||||
quote = { version = "1", optional = true }
|
||||
schemars = { version = "0.8", features = [ "url" ], optional = true }
|
||||
serde_with = "2"
|
||||
schemars = { version = "0.8.18", features = [ "url" ], optional = true }
|
||||
serde_with = "3"
|
||||
aes-gcm = { version = "0.10", optional = true }
|
||||
getrandom = { version = "0.2", optional = true, features = [ "std" ] }
|
||||
serialize-to-javascript = { version = "=0.1.1", optional = true }
|
||||
ctor = "0.1"
|
||||
ctor = "0.2"
|
||||
json5 = { version = "0.4", optional = true }
|
||||
toml = { version = "0.5", optional = true }
|
||||
json-patch = "1.0"
|
||||
toml = { version = "0.7", optional = true }
|
||||
json-patch = "1.2"
|
||||
glob = { version = "0.3", optional = true }
|
||||
walkdir = { version = "2", optional = true }
|
||||
memchr = "2"
|
||||
semver = "1"
|
||||
infer = "0.12"
|
||||
infer = "0.13"
|
||||
dunce = "1"
|
||||
log = "0.4.20"
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
heck = "0.4"
|
||||
heck = "0.5"
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.39.0"
|
||||
features = [
|
||||
"implement",
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_SystemInformation"
|
||||
]
|
||||
[target."cfg(windows)".dependencies]
|
||||
windows-version = "0.1"
|
||||
|
||||
[features]
|
||||
build = [ "proc-macro2", "quote" ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
@@ -109,6 +109,9 @@ pub trait Assets: Send + Sync + 'static {
|
||||
/// Get the content of the passed [`AssetKey`].
|
||||
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>>;
|
||||
|
||||
/// Iterator for the assets.
|
||||
fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_>;
|
||||
|
||||
/// Gets the hashes for the CSP tag of the HTML on the given path.
|
||||
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_>;
|
||||
}
|
||||
@@ -163,6 +166,10 @@ impl Assets for EmbeddedAssets {
|
||||
.map(|a| Cow::Owned(a.to_vec()))
|
||||
}
|
||||
|
||||
fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
|
||||
Box::new(self.assets.into_iter())
|
||||
}
|
||||
|
||||
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
|
||||
Box::new(
|
||||
self
|
||||
|
||||
@@ -38,6 +38,10 @@ use crate::TitleBarStyle;
|
||||
|
||||
pub use self::parse::parse;
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// An URL to open on a Tauri webview window.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
@@ -162,19 +166,13 @@ impl schemars::JsonSchema for BundleTarget {
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
schemars::_private::apply_metadata(
|
||||
schemars::_private::metadata::add_description(
|
||||
gen.subschema_for::<Vec<BundleType>>(),
|
||||
schemars::schema::Metadata {
|
||||
description: Some("A list of bundle targets.".to_owned()),
|
||||
..Default::default()
|
||||
},
|
||||
"A list of bundle targets.",
|
||||
),
|
||||
schemars::_private::apply_metadata(
|
||||
schemars::_private::metadata::add_description(
|
||||
gen.subschema_for::<BundleType>(),
|
||||
schemars::schema::Metadata {
|
||||
description: Some("A single bundle target.".to_owned()),
|
||||
..Default::default()
|
||||
},
|
||||
"A single bundle target.",
|
||||
),
|
||||
];
|
||||
|
||||
@@ -272,6 +270,18 @@ pub struct DebConfig {
|
||||
/// The files to include on the package.
|
||||
#[serde(default)]
|
||||
pub files: HashMap<PathBuf, PathBuf>,
|
||||
/// Path to a custom desktop file Handlebars template.
|
||||
///
|
||||
/// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
|
||||
pub desktop_template: Option<PathBuf>,
|
||||
/// Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
|
||||
pub section: Option<String>,
|
||||
/// Change the priority of the Debian Package. By default, it is set to `optional`.
|
||||
/// Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`
|
||||
pub priority: Option<String>,
|
||||
/// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See
|
||||
/// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
|
||||
pub changelog: Option<PathBuf>,
|
||||
}
|
||||
|
||||
fn de_minimum_system_version<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||
@@ -430,11 +440,28 @@ pub struct WixConfig {
|
||||
pub dialog_image_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Compression algorithms used in the NSIS installer.
|
||||
///
|
||||
/// See <https://nsis.sourceforge.io/Reference/SetCompressor>
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub enum NsisCompression {
|
||||
/// ZLIB uses the deflate algorithm, it is a quick and simple method. With the default compression level it uses about 300 KB of memory.
|
||||
Zlib,
|
||||
/// BZIP2 usually gives better compression ratios than ZLIB, but it is a bit slower and uses more memory. With the default compression level it uses about 4 MB of memory.
|
||||
Bzip2,
|
||||
/// LZMA (default) is a new compression method that gives very good compression ratios. The decompression speed is high (10-20 MB/s on a 2 GHz CPU), the compression speed is lower. The memory size that will be used for decompression is the dictionary size plus a few KBs, the default is 8 MB.
|
||||
Lzma,
|
||||
}
|
||||
|
||||
/// Configuration for the Installer bundle using NSIS.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct NsisConfig {
|
||||
/// A custom .nsi template to use.
|
||||
pub template: Option<PathBuf>,
|
||||
/// The path to the license file to render on the installer.
|
||||
pub license: Option<PathBuf>,
|
||||
/// The path to a bitmap file to display on the header of installers pages.
|
||||
@@ -459,10 +486,21 @@ pub struct NsisConfig {
|
||||
///
|
||||
/// See <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files> for the complete list of languages.
|
||||
pub languages: Option<Vec<String>>,
|
||||
/// A key-value pair where the key is the language and the
|
||||
/// value is the path to a custom `.nsh` file that holds the translated text for tauri's custom messages.
|
||||
///
|
||||
/// See <https://github.com/tauri-apps/tauri/blob/dev/tooling/bundler/src/bundle/windows/templates/nsis-languages/English.nsh> for an example `.nsh` file.
|
||||
///
|
||||
/// **Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`] languages array,
|
||||
pub custom_language_files: Option<HashMap<String, PathBuf>>,
|
||||
/// Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not.
|
||||
/// By default the OS language is selected, with a fallback to the first language in the `languages` array.
|
||||
#[serde(default, alias = "display-language-selector")]
|
||||
pub display_language_selector: bool,
|
||||
/// Set the compression algorithm used to compress files in the installer.
|
||||
///
|
||||
/// See <https://nsis.sourceforge.io/Reference/SetCompressor>
|
||||
pub compression: Option<NsisCompression>,
|
||||
}
|
||||
|
||||
/// Install Modes for the NSIS installer.
|
||||
@@ -510,7 +548,7 @@ pub enum WebviewInstallMode {
|
||||
/// Results in a smaller installer size, but is not recommended on Windows 7.
|
||||
DownloadBootstrapper {
|
||||
/// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed the bootstrapper and run it.
|
||||
@@ -518,7 +556,7 @@ pub enum WebviewInstallMode {
|
||||
/// Increases the installer size by around 1.8MB, but offers better support on Windows 7.
|
||||
EmbedBootstrapper {
|
||||
/// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed the offline installer and run it.
|
||||
@@ -526,7 +564,7 @@ pub enum WebviewInstallMode {
|
||||
/// Increases the installer size by around 127MB.
|
||||
OfflineInstaller {
|
||||
/// Instructs the installer to run the installer in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed a fixed webview2 version and use it at runtime.
|
||||
@@ -540,15 +578,9 @@ pub enum WebviewInstallMode {
|
||||
},
|
||||
}
|
||||
|
||||
fn default_webview_install_silent() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Default for WebviewInstallMode {
|
||||
fn default() -> Self {
|
||||
Self::DownloadBootstrapper {
|
||||
silent: default_webview_install_silent(),
|
||||
}
|
||||
Self::DownloadBootstrapper { silent: true }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,7 +621,7 @@ pub struct WindowsConfig {
|
||||
/// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
|
||||
///
|
||||
/// The default value of this flag is `true`.
|
||||
#[serde(default = "default_allow_downgrades", alias = "allow-downgrades")]
|
||||
#[serde(default = "default_true", alias = "allow-downgrades")]
|
||||
pub allow_downgrades: bool,
|
||||
/// Configuration for the MSI generated with WiX.
|
||||
pub wix: Option<WixConfig>,
|
||||
@@ -606,15 +638,36 @@ impl Default for WindowsConfig {
|
||||
tsp: false,
|
||||
webview_install_mode: Default::default(),
|
||||
webview_fixed_runtime_path: None,
|
||||
allow_downgrades: default_allow_downgrades(),
|
||||
allow_downgrades: true,
|
||||
wix: None,
|
||||
nsis: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_allow_downgrades() -> bool {
|
||||
true
|
||||
/// Definition for bundle resources.
|
||||
/// Can be either a list of paths to include or a map of source to target paths.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields, untagged)]
|
||||
pub enum BundleResources {
|
||||
/// A list of paths to include.
|
||||
List(Vec<String>),
|
||||
/// A map of source to target paths.
|
||||
Map(HashMap<String, String>),
|
||||
}
|
||||
|
||||
impl BundleResources {
|
||||
/// Adds a path to the resource collection.
|
||||
pub fn push(&mut self, path: impl Into<String>) {
|
||||
match self {
|
||||
Self::List(l) => l.push(path.into()),
|
||||
Self::Map(l) => {
|
||||
let path = path.into();
|
||||
l.insert(path.clone(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for tauri-bundler.
|
||||
@@ -646,7 +699,7 @@ pub struct BundleConfig {
|
||||
/// App resources to bundle.
|
||||
/// Each resource is a path to a file or directory.
|
||||
/// Glob patterns are supported.
|
||||
pub resources: Option<Vec<String>>,
|
||||
pub resources: Option<BundleResources>,
|
||||
/// A copyright string associated with your application.
|
||||
pub copyright: Option<String>,
|
||||
/// The application kind.
|
||||
@@ -892,7 +945,7 @@ pub struct WindowConfig {
|
||||
/// Whether the file drop is enabled or not on the webview. By default it is enabled.
|
||||
///
|
||||
/// Disabling it is required to use drag and drop on the frontend on Windows.
|
||||
#[serde(default = "default_file_drop_enabled", alias = "file-drop-enabled")]
|
||||
#[serde(default = "default_true", alias = "file-drop-enabled")]
|
||||
pub file_drop_enabled: bool,
|
||||
/// Whether or not the window starts centered or not.
|
||||
#[serde(default)]
|
||||
@@ -919,9 +972,34 @@ pub struct WindowConfig {
|
||||
/// The max window height.
|
||||
#[serde(alias = "max-height")]
|
||||
pub max_height: Option<f64>,
|
||||
/// Whether the window is resizable or not.
|
||||
#[serde(default = "default_resizable")]
|
||||
/// Whether the window is resizable or not. When resizable is set to false, native window's maximize button is automatically disabled.
|
||||
#[serde(default = "default_true")]
|
||||
pub resizable: bool,
|
||||
/// Whether the window's native maximize button is enabled or not.
|
||||
/// If resizable is set to false, this setting is ignored.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[serde(default = "default_true")]
|
||||
pub maximizable: bool,
|
||||
/// Whether the window's native minimize button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[serde(default = "default_true")]
|
||||
pub minimizable: bool,
|
||||
/// Whether the window's native close button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
|
||||
/// Depending on the system, this function may not have any effect when called on a window that is already visible"
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
#[serde(default = "default_true")]
|
||||
pub closable: bool,
|
||||
/// The window title.
|
||||
#[serde(default = "default_title")]
|
||||
pub title: String,
|
||||
@@ -929,7 +1007,7 @@ pub struct WindowConfig {
|
||||
#[serde(default)]
|
||||
pub fullscreen: bool,
|
||||
/// Whether the window will be initially focused or not.
|
||||
#[serde(default = "default_focus")]
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
/// Whether the window is transparent or not.
|
||||
///
|
||||
@@ -941,10 +1019,10 @@ pub struct WindowConfig {
|
||||
#[serde(default)]
|
||||
pub maximized: bool,
|
||||
/// Whether the window is visible or not.
|
||||
#[serde(default = "default_visible")]
|
||||
#[serde(default = "default_true")]
|
||||
pub visible: bool,
|
||||
/// Whether the window should have borders and bars.
|
||||
#[serde(default = "default_decorations")]
|
||||
#[serde(default = "default_true")]
|
||||
pub decorations: bool,
|
||||
/// Whether the window should always be on top of other windows.
|
||||
#[serde(default, alias = "always-on-top")]
|
||||
@@ -986,7 +1064,7 @@ impl Default for WindowConfig {
|
||||
label: default_window_label(),
|
||||
url: WindowUrl::default(),
|
||||
user_agent: None,
|
||||
file_drop_enabled: default_file_drop_enabled(),
|
||||
file_drop_enabled: true,
|
||||
center: false,
|
||||
x: None,
|
||||
y: None,
|
||||
@@ -996,14 +1074,17 @@ impl Default for WindowConfig {
|
||||
min_height: None,
|
||||
max_width: None,
|
||||
max_height: None,
|
||||
resizable: default_resizable(),
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
minimizable: true,
|
||||
closable: true,
|
||||
title: default_title(),
|
||||
fullscreen: false,
|
||||
focus: false,
|
||||
transparent: false,
|
||||
maximized: false,
|
||||
visible: default_visible(),
|
||||
decorations: default_decorations(),
|
||||
visible: true,
|
||||
decorations: true,
|
||||
always_on_top: false,
|
||||
content_protected: false,
|
||||
skip_taskbar: false,
|
||||
@@ -1029,30 +1110,10 @@ fn default_height() -> f64 {
|
||||
600f64
|
||||
}
|
||||
|
||||
fn default_resizable() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_title() -> String {
|
||||
"Tauri App".to_string()
|
||||
}
|
||||
|
||||
fn default_focus() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_visible() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_decorations() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_file_drop_enabled() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// A Content-Security-Policy directive source list.
|
||||
/// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
@@ -1208,6 +1269,7 @@ pub struct RemoteDomainAccessScope {
|
||||
/// The list of window labels this scope applies to.
|
||||
pub windows: Vec<String>,
|
||||
/// The list of plugins that are allowed in this scope.
|
||||
/// The names should be without the `tauri-plugin-` prefix, for example `"store"` for `tauri-plugin-store`.
|
||||
#[serde(default)]
|
||||
pub plugins: Vec<String>,
|
||||
/// Enables access to the Tauri API.
|
||||
@@ -1266,6 +1328,11 @@ pub struct SecurityConfig {
|
||||
/// vulnerable to dangerous Tauri command related attacks otherwise.
|
||||
#[serde(default, alias = "dangerous-remote-domain-ipc-access")]
|
||||
pub dangerous_remote_domain_ipc_access: Vec<RemoteDomainAccessScope>,
|
||||
/// Sets whether the custom protocols should use `http://<scheme>.localhost` instead of the default `https://<scheme>.localhost` on Windows.
|
||||
///
|
||||
/// **WARNING:** Using a `http` scheme will allow mixed content when trying to fetch `http` endpoints and is therefore less secure but will match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
|
||||
#[serde(default, alias = "dangerous-use-http-scheme")]
|
||||
pub dangerous_use_http_scheme: bool,
|
||||
}
|
||||
|
||||
/// Defines an allowlist type.
|
||||
@@ -1293,12 +1360,13 @@ macro_rules! check_feature {
|
||||
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
|
||||
/// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
pub enum FsAllowlistScope {
|
||||
/// A list of paths that are allowed by this scope.
|
||||
AllowedPaths(Vec<PathBuf>),
|
||||
/// A complete scope configuration.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Scope {
|
||||
/// A list of paths that are allowed by this scope.
|
||||
#[serde(default)]
|
||||
@@ -1307,6 +1375,16 @@ pub enum FsAllowlistScope {
|
||||
/// This gets precedence over the [`Self::Scope::allow`] list.
|
||||
#[serde(default)]
|
||||
deny: Vec<PathBuf>,
|
||||
/// Whether or not paths that contain components that start with a `.`
|
||||
/// will require that `.` appears literally in the pattern; `*`, `?`, `**`,
|
||||
/// or `[...]` will not match. This is useful because such files are
|
||||
/// conventionally considered hidden on Unix systems and it might be
|
||||
/// desirable to skip them when listing files.
|
||||
///
|
||||
/// Defaults to `true` on Unix systems and `false` on Windows
|
||||
// dotfiles are not supposed to be exposed by default on unix
|
||||
#[serde(alias = "require-literal-leading-dot")]
|
||||
require_literal_leading_dot: Option<bool>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1437,6 +1515,15 @@ pub struct WindowAllowlistConfig {
|
||||
/// Allows setting the resizable flag of the window.
|
||||
#[serde(default, alias = "set-resizable")]
|
||||
pub set_resizable: bool,
|
||||
/// Allows setting whether the window's native maximize button is enabled or not.
|
||||
#[serde(default, alias = "set-maximizable")]
|
||||
pub set_maximizable: bool,
|
||||
/// Allows setting whether the window's native minimize button is enabled or not.
|
||||
#[serde(default, alias = "set-minimizable")]
|
||||
pub set_minimizable: bool,
|
||||
/// Allows setting whether the window's native close button is enabled or not.
|
||||
#[serde(default, alias = "set-closable")]
|
||||
pub set_closable: bool,
|
||||
/// Allows changing the window title.
|
||||
#[serde(default, alias = "set-title")]
|
||||
pub set_title: bool,
|
||||
@@ -1525,6 +1612,9 @@ impl Allowlist for WindowAllowlistConfig {
|
||||
center: true,
|
||||
request_user_attention: true,
|
||||
set_resizable: true,
|
||||
set_maximizable: true,
|
||||
set_minimizable: true,
|
||||
set_closable: true,
|
||||
set_title: true,
|
||||
maximize: true,
|
||||
unmaximize: true,
|
||||
@@ -1571,6 +1661,9 @@ impl Allowlist for WindowAllowlistConfig {
|
||||
"window-request-user-attention"
|
||||
);
|
||||
check_feature!(self, features, set_resizable, "window-set-resizable");
|
||||
check_feature!(self, features, set_maximizable, "window-set-maximizable");
|
||||
check_feature!(self, features, set_minimizable, "window-set-minimizable");
|
||||
check_feature!(self, features, set_closable, "window-set-closable");
|
||||
check_feature!(self, features, set_title, "window-set-title");
|
||||
check_feature!(self, features, maximize, "window-maximize");
|
||||
check_feature!(self, features, unmaximize, "window-unmaximize");
|
||||
@@ -1883,11 +1976,13 @@ impl Allowlist for DialogAllowlistConfig {
|
||||
/// The scoped URL is matched against the request URL using a glob pattern.
|
||||
///
|
||||
/// Examples:
|
||||
/// - "https://**": allows all HTTPS urls
|
||||
/// - "https://*": allows all HTTPS urls
|
||||
/// - "https://*.github.com/tauri-apps/tauri": allows any subdomain of "github.com" with the "tauri-apps/api" path
|
||||
/// - "https://myapi.service.com/users/*": allows access to any URLs that begins with "https://myapi.service.com/users/"
|
||||
#[allow(rustdoc::bare_urls)]
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
// TODO: in v2, parse into a String or a custom type that perserves the
|
||||
// glob string because Url type will add a trailing slash
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
pub struct HttpAllowlistScope(pub Vec<Url>);
|
||||
|
||||
@@ -2391,7 +2486,6 @@ pub struct TauriConfig {
|
||||
|
||||
impl TauriConfig {
|
||||
/// Returns all Cargo features.
|
||||
#[allow(dead_code)]
|
||||
pub fn all_features() -> Vec<&'static str> {
|
||||
let mut features = AllowlistConfig::all_features();
|
||||
features.extend(vec![
|
||||
@@ -2405,7 +2499,6 @@ impl TauriConfig {
|
||||
}
|
||||
|
||||
/// Returns the enabled Cargo features.
|
||||
#[allow(dead_code)]
|
||||
pub fn features(&self) -> Vec<&str> {
|
||||
let mut features = self.allowlist.to_features();
|
||||
if self.cli.is_some() {
|
||||
@@ -2468,7 +2561,7 @@ pub enum WindowsUpdateInstallMode {
|
||||
/// Specifies there's a basic UI during the installation process, including a final dialog box at the end.
|
||||
BasicUi,
|
||||
/// The quiet mode means there's no user interaction required.
|
||||
/// Requires admin privileges if the installer does (WiX).
|
||||
/// Requires admin privileges if the installer does.
|
||||
Quiet,
|
||||
/// Specifies unattended mode, which means the installation only shows a progress bar.
|
||||
Passive,
|
||||
@@ -2485,6 +2578,18 @@ impl WindowsUpdateInstallMode {
|
||||
Self::Passive => &["/passive"],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the associated nsis arguments.
|
||||
///
|
||||
/// [WindowsUpdateInstallMode::Passive] will return `["/P", "/R"]`
|
||||
/// [WindowsUpdateInstallMode::Quiet] will return `["/S", "/R"]`
|
||||
pub fn nsis_args(&self) -> &'static [&'static str] {
|
||||
match self {
|
||||
Self::Passive => &["/P", "/R"],
|
||||
Self::Quiet => &["/S", "/R"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for WindowsUpdateInstallMode {
|
||||
@@ -2561,7 +2666,7 @@ pub struct UpdaterConfig {
|
||||
#[serde(default)]
|
||||
pub active: bool,
|
||||
/// Display built-in dialog or use event system if disabled.
|
||||
#[serde(default = "default_dialog")]
|
||||
#[serde(default = "default_true")]
|
||||
pub dialog: bool,
|
||||
/// The updater endpoints. TLS is enforced on production.
|
||||
///
|
||||
@@ -2592,7 +2697,7 @@ impl<'de> Deserialize<'de> for UpdaterConfig {
|
||||
struct InnerUpdaterConfig {
|
||||
#[serde(default)]
|
||||
active: bool,
|
||||
#[serde(default = "default_dialog")]
|
||||
#[serde(default = "default_true")]
|
||||
dialog: bool,
|
||||
endpoints: Option<Vec<UpdaterEndpoint>>,
|
||||
pubkey: Option<String>,
|
||||
@@ -2622,7 +2727,7 @@ impl Default for UpdaterConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
active: false,
|
||||
dialog: default_dialog(),
|
||||
dialog: true,
|
||||
endpoints: None,
|
||||
pubkey: "".into(),
|
||||
windows: Default::default(),
|
||||
@@ -2645,26 +2750,12 @@ pub struct SystemTrayConfig {
|
||||
#[serde(default, alias = "icon-as-template")]
|
||||
pub icon_as_template: bool,
|
||||
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
|
||||
#[serde(
|
||||
default = "default_tray_menu_on_left_click",
|
||||
alias = "menu-on-left-click"
|
||||
)]
|
||||
#[serde(default = "default_true", alias = "menu-on-left-click")]
|
||||
pub menu_on_left_click: bool,
|
||||
/// Title for MacOS tray
|
||||
pub title: Option<String>,
|
||||
}
|
||||
|
||||
fn default_tray_menu_on_left_click() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// We enable the unnecessary_wraps because we need
|
||||
// to use an Option for dialog otherwise the CLI schema will mark
|
||||
// the dialog as a required field which is not as we default it to true.
|
||||
fn default_dialog() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Defines the URL or assets to embed in the application.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
@@ -2867,7 +2958,7 @@ pub struct PackageConfig {
|
||||
#[serde(alias = "product-name")]
|
||||
#[cfg_attr(feature = "schema", validate(regex(pattern = "^[^/\\:*?\"<>|]+$")))]
|
||||
pub product_name: Option<String>,
|
||||
/// App version. It is a semver version number or a path to a `package.json` file containing the `version` field.
|
||||
/// App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.
|
||||
#[serde(deserialize_with = "version_deserializer", default)]
|
||||
pub version: Option<String>,
|
||||
}
|
||||
@@ -3128,7 +3219,7 @@ mod build {
|
||||
} else if num.is_f64() {
|
||||
// guaranteed f64
|
||||
let num = num.as_f64().unwrap();
|
||||
quote! { #prefix::Number(#num.into()) }
|
||||
quote! { #prefix::Number(::serde_json::Number::from_f64(#num).unwrap(/* safe to unwrap, guaranteed f64 */)) }
|
||||
} else {
|
||||
// invalid number
|
||||
quote! { #prefix::Null }
|
||||
@@ -3227,6 +3318,9 @@ mod build {
|
||||
let max_width = opt_lit(self.max_width.as_ref());
|
||||
let max_height = opt_lit(self.max_height.as_ref());
|
||||
let resizable = self.resizable;
|
||||
let maximizable = self.maximizable;
|
||||
let minimizable = self.minimizable;
|
||||
let closable = self.closable;
|
||||
let title = str_lit(&self.title);
|
||||
let fullscreen = self.fullscreen;
|
||||
let focus = self.focus;
|
||||
@@ -3261,6 +3355,9 @@ mod build {
|
||||
max_width,
|
||||
max_height,
|
||||
resizable,
|
||||
maximizable,
|
||||
minimizable,
|
||||
closable,
|
||||
title,
|
||||
fullscreen,
|
||||
focus,
|
||||
@@ -3649,6 +3746,7 @@ mod build {
|
||||
let dev_csp = opt_lit(self.dev_csp.as_ref());
|
||||
let freeze_prototype = self.freeze_prototype;
|
||||
let dangerous_disable_asset_csp_modification = &self.dangerous_disable_asset_csp_modification;
|
||||
let dangerous_use_http_scheme = &self.dangerous_use_http_scheme;
|
||||
let dangerous_remote_domain_ipc_access =
|
||||
vec_lit(&self.dangerous_remote_domain_ipc_access, identity);
|
||||
|
||||
@@ -3659,7 +3757,8 @@ mod build {
|
||||
dev_csp,
|
||||
freeze_prototype,
|
||||
dangerous_disable_asset_csp_modification,
|
||||
dangerous_remote_domain_ipc_access
|
||||
dangerous_remote_domain_ipc_access,
|
||||
dangerous_use_http_scheme
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3690,10 +3789,11 @@ mod build {
|
||||
let allowed_paths = vec_lit(allow, path_buf_lit);
|
||||
quote! { #prefix::AllowedPaths(#allowed_paths) }
|
||||
}
|
||||
Self::Scope { allow, deny } => {
|
||||
Self::Scope { allow, deny , require_literal_leading_dot} => {
|
||||
let allow = vec_lit(allow, path_buf_lit);
|
||||
let deny = vec_lit(deny, path_buf_lit);
|
||||
quote! { #prefix::Scope { allow: #allow, deny: #deny } }
|
||||
let require_literal_leading_dot = opt_lit(require_literal_leading_dot.as_ref());
|
||||
quote! { #prefix::Scope { allow: #allow, deny: #deny, require_literal_leading_dot: #require_literal_leading_dot } }
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3925,6 +4025,7 @@ mod test {
|
||||
freeze_prototype: false,
|
||||
dangerous_disable_asset_csp_modification: DisabledCspModificationKind::Flag(false),
|
||||
dangerous_remote_domain_ipc_access: Vec::new(),
|
||||
dangerous_use_http_scheme: false,
|
||||
},
|
||||
allowlist: AllowlistConfig::default(),
|
||||
system_tray: None,
|
||||
|
||||
@@ -302,7 +302,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
document.to_string(),
|
||||
format!(
|
||||
r#"<html><head><meta content="{}" http-equiv="Content-Security-Policy"></head><body></body></html>"#,
|
||||
r#"<html><head><meta http-equiv="Content-Security-Policy" content="{}"></head><body></body></html>"#,
|
||||
super::CSP_TOKEN
|
||||
)
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use std::io::BufRead;
|
||||
|
||||
/// Read a line breaking in both \n and \r.
|
||||
/// Read all bytes until a newline (the `0xA` byte) or a carriage return (`\r`) is reached, and append them to the provided buffer.
|
||||
///
|
||||
/// Adapted from <https://doc.rust-lang.org/std/io/trait.BufRead.html#method.read_line>.
|
||||
pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::Result<usize> {
|
||||
@@ -16,6 +16,7 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
|
||||
let available = match r.fill_buf() {
|
||||
Ok(n) => n,
|
||||
Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
|
||||
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
match memchr::memchr(b'\n', available) {
|
||||
@@ -40,9 +41,6 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
|
||||
r.consume(used);
|
||||
read += used;
|
||||
if done || used == 0 {
|
||||
if buf.ends_with(&[b'\n']) {
|
||||
buf.pop();
|
||||
}
|
||||
return Ok(read);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ use std::{
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use log::warn;
|
||||
|
||||
pub mod assets;
|
||||
pub mod config;
|
||||
pub mod html;
|
||||
@@ -202,7 +204,7 @@ impl Default for Env {
|
||||
.unwrap_or(true);
|
||||
|
||||
if !is_temp {
|
||||
panic!("`APPDIR` or `APPIMAGE` environment variable found but this application was not detected as an AppImage; this might be a security issue.");
|
||||
warn!("`APPDIR` or `APPIMAGE` environment variable found but this application was not detected as an AppImage; this might be a security issue.");
|
||||
}
|
||||
}
|
||||
env
|
||||
@@ -298,11 +300,9 @@ macro_rules! debug_eprintln {
|
||||
};
|
||||
}
|
||||
|
||||
/// Reconstructs a path from its components using the platform separator then converts it to String
|
||||
/// Reconstructs a path from its components using the platform separator then converts it to String and removes UNC prefixes on Windows if it exists.
|
||||
pub fn display_path<P: AsRef<Path>>(p: P) -> String {
|
||||
p.as_ref()
|
||||
.components()
|
||||
.collect::<PathBuf>()
|
||||
dunce::simplified(&p.as_ref().components().collect::<PathBuf>())
|
||||
.display()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
@@ -18,10 +18,11 @@ pub enum MimeType {
|
||||
Js,
|
||||
Json,
|
||||
Jsonld,
|
||||
Mp4,
|
||||
OctetStream,
|
||||
Rtf,
|
||||
Svg,
|
||||
Mp4,
|
||||
Txt,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MimeType {
|
||||
@@ -34,10 +35,11 @@ impl std::fmt::Display for MimeType {
|
||||
MimeType::Js => "text/javascript",
|
||||
MimeType::Json => "application/json",
|
||||
MimeType::Jsonld => "application/ld+json",
|
||||
MimeType::Mp4 => "video/mp4",
|
||||
MimeType::OctetStream => "application/octet-stream",
|
||||
MimeType::Rtf => "application/rtf",
|
||||
MimeType::Svg => "image/svg+xml",
|
||||
MimeType::Mp4 => "video/mp4",
|
||||
MimeType::Txt => MIMETYPE_PLAIN,
|
||||
};
|
||||
write!(f, "{mime}")
|
||||
}
|
||||
@@ -46,6 +48,11 @@ impl std::fmt::Display for MimeType {
|
||||
impl MimeType {
|
||||
/// parse a URI suffix to convert text/plain mimeType to their actual web compatible mimeType.
|
||||
pub fn parse_from_uri(uri: &str) -> MimeType {
|
||||
Self::parse_from_uri_with_fallback(uri, Self::Html)
|
||||
}
|
||||
|
||||
/// parse a URI suffix to convert text/plain mimeType to their actual web compatible mimeType with specified fallback for unknown file extensions.
|
||||
pub fn parse_from_uri_with_fallback(uri: &str, fallback: MimeType) -> MimeType {
|
||||
let suffix = uri.split('.').last();
|
||||
match suffix {
|
||||
Some("bin") => Self::OctetStream,
|
||||
@@ -57,19 +64,24 @@ impl MimeType {
|
||||
Some("json") => Self::Json,
|
||||
Some("jsonld") => Self::Jsonld,
|
||||
Some("mjs") => Self::Js,
|
||||
Some("mp4") => Self::Mp4,
|
||||
Some("rtf") => Self::Rtf,
|
||||
Some("svg") => Self::Svg,
|
||||
Some("mp4") => Self::Mp4,
|
||||
Some("txt") => Self::Txt,
|
||||
// Assume HTML when a TLD is found for eg. `wry:://tauri.app` | `wry://hello.com`
|
||||
Some(_) => Self::Html,
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
Some(_) => fallback,
|
||||
// using octet stream according to this:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
None => Self::OctetStream,
|
||||
}
|
||||
}
|
||||
|
||||
/// infer mimetype from content (or) URI if needed.
|
||||
pub fn parse(content: &[u8], uri: &str) -> String {
|
||||
Self::parse_with_fallback(content, uri, Self::Html)
|
||||
}
|
||||
/// infer mimetype from content (or) URI if needed with specified fallback for unknown file extensions.
|
||||
pub fn parse_with_fallback(content: &[u8], uri: &str, fallback: MimeType) -> String {
|
||||
let mime = if uri.ends_with(".svg") {
|
||||
// when reading svg, we can't use `infer`
|
||||
None
|
||||
@@ -78,8 +90,10 @@ impl MimeType {
|
||||
};
|
||||
|
||||
match mime {
|
||||
Some(mime) if mime == MIMETYPE_PLAIN => Self::parse_from_uri(uri).to_string(),
|
||||
None => Self::parse_from_uri(uri).to_string(),
|
||||
Some(mime) if mime == MIMETYPE_PLAIN => {
|
||||
Self::parse_from_uri_with_fallback(uri, fallback).to_string()
|
||||
}
|
||||
None => Self::parse_from_uri_with_fallback(uri, fallback).to_string(),
|
||||
Some(mime) => mime.to_string(),
|
||||
}
|
||||
}
|
||||
@@ -122,14 +136,17 @@ mod tests {
|
||||
let mjs: String = MimeType::parse_from_uri("https://example.com/bundled.mjs").to_string();
|
||||
assert_eq!(mjs, String::from("text/javascript"));
|
||||
|
||||
let mp4: String = MimeType::parse_from_uri("https://example.com/video.mp4").to_string();
|
||||
assert_eq!(mp4, String::from("video/mp4"));
|
||||
|
||||
let rtf: String = MimeType::parse_from_uri("https://example.com/document.rtf").to_string();
|
||||
assert_eq!(rtf, String::from("application/rtf"));
|
||||
|
||||
let svg: String = MimeType::parse_from_uri("https://example.com/picture.svg").to_string();
|
||||
assert_eq!(svg, String::from("image/svg+xml"));
|
||||
|
||||
let mp4: String = MimeType::parse_from_uri("https://example.com/video.mp4").to_string();
|
||||
assert_eq!(mp4, String::from("video/mp4"));
|
||||
let txt: String = MimeType::parse_from_uri("https://example.com/file.txt").to_string();
|
||||
assert_eq!(txt, String::from("text/plain"));
|
||||
|
||||
let custom_scheme = MimeType::parse_from_uri("wry://tauri.app").to_string();
|
||||
assert_eq!(custom_scheme, String::from("text/html"));
|
||||
|
||||
@@ -208,81 +208,16 @@ pub use windows_platform::{is_windows_7, windows_version};
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows_platform {
|
||||
use std::{iter::once, os::windows::prelude::OsStrExt};
|
||||
use windows::{
|
||||
core::{PCSTR, PCWSTR},
|
||||
Win32::{
|
||||
Foundation::FARPROC,
|
||||
System::{
|
||||
LibraryLoader::{GetProcAddress, LoadLibraryW},
|
||||
SystemInformation::OSVERSIONINFOW,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/// Checks if we're running on Windows 7.
|
||||
pub fn is_windows_7() -> bool {
|
||||
if let Some(v) = windows_version() {
|
||||
// windows 7 is 6.1
|
||||
if v.0 == 6 && v.1 == 1 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn encode_wide(string: impl AsRef<std::ffi::OsStr>) -> Vec<u16> {
|
||||
string.as_ref().encode_wide().chain(once(0)).collect()
|
||||
}
|
||||
|
||||
// Helper function to dynamically load function pointer.
|
||||
// `library` and `function` must be zero-terminated.
|
||||
fn get_function_impl(library: &str, function: &str) -> Option<FARPROC> {
|
||||
let library = encode_wide(library);
|
||||
assert_eq!(function.chars().last(), Some('\0'));
|
||||
let function = PCSTR::from_raw(function.as_ptr());
|
||||
|
||||
// Library names we will use are ASCII so we can use the A version to avoid string conversion.
|
||||
let module = unsafe { LoadLibraryW(PCWSTR::from_raw(library.as_ptr())) }.unwrap_or_default();
|
||||
if module.is_invalid() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { GetProcAddress(module, function) })
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! get_function {
|
||||
($lib:expr, $func:ident) => {
|
||||
get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0'))
|
||||
.map(|f| unsafe { std::mem::transmute::<windows::Win32::Foundation::FARPROC, $func>(f) })
|
||||
};
|
||||
windows_version()
|
||||
.map(|v| v.0 == 6 && v.1 == 1)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Returns a tuple of (major, minor, buildnumber) for the Windows version.
|
||||
pub fn windows_version() -> Option<(u32, u32, u32)> {
|
||||
type RtlGetVersion = unsafe extern "system" fn(*mut OSVERSIONINFOW) -> i32;
|
||||
let handle = get_function!("ntdll.dll", RtlGetVersion);
|
||||
if let Some(rtl_get_version) = handle {
|
||||
unsafe {
|
||||
let mut vi = OSVERSIONINFOW {
|
||||
dwOSVersionInfoSize: 0,
|
||||
dwMajorVersion: 0,
|
||||
dwMinorVersion: 0,
|
||||
dwBuildNumber: 0,
|
||||
dwPlatformId: 0,
|
||||
szCSDVersion: [0; 128],
|
||||
};
|
||||
|
||||
let status = (rtl_get_version)(&mut vi as _);
|
||||
|
||||
if status >= 0 {
|
||||
Some((vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let v = windows_version::OsVersion::current();
|
||||
Some((v.major, v.minor, v.build))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ impl StartingBinary {
|
||||
///
|
||||
/// Because [`Error`] is not clone-able, it is recreated instead.
|
||||
pub(super) fn cloned(&self) -> Result<PathBuf> {
|
||||
// false positive
|
||||
#[allow(clippy::useless_asref)]
|
||||
self
|
||||
.0
|
||||
.as_ref()
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Component, Path, PathBuf},
|
||||
};
|
||||
|
||||
/// Given a path (absolute or relative) to a resource file, returns the
|
||||
/// relative path from the bundle resources directory where that resource
|
||||
@@ -39,10 +42,58 @@ pub fn external_binaries(external_binaries: &[String], target_triple: &str) -> V
|
||||
paths
|
||||
}
|
||||
|
||||
enum PatternIter<'a> {
|
||||
Slice(std::slice::Iter<'a, String>),
|
||||
Map(std::collections::hash_map::Iter<'a, String, String>),
|
||||
}
|
||||
|
||||
/// A helper to iterate through resources.
|
||||
pub struct ResourcePaths<'a> {
|
||||
iter: ResourcePathsIter<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ResourcePaths<'a> {
|
||||
/// Creates a new ResourcePaths from a slice of patterns to iterate
|
||||
pub fn new(patterns: &'a [String], allow_walk: bool) -> ResourcePaths<'a> {
|
||||
ResourcePaths {
|
||||
iter: ResourcePathsIter {
|
||||
pattern_iter: PatternIter::Slice(patterns.iter()),
|
||||
glob_iter: None,
|
||||
walk_iter: None,
|
||||
allow_walk,
|
||||
current_pattern: None,
|
||||
current_pattern_is_valid: false,
|
||||
current_dest: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ResourcePaths from a slice of patterns to iterate
|
||||
pub fn from_map(patterns: &'a HashMap<String, String>, allow_walk: bool) -> ResourcePaths<'a> {
|
||||
ResourcePaths {
|
||||
iter: ResourcePathsIter {
|
||||
pattern_iter: PatternIter::Map(patterns.iter()),
|
||||
glob_iter: None,
|
||||
walk_iter: None,
|
||||
allow_walk,
|
||||
current_pattern: None,
|
||||
current_pattern_is_valid: false,
|
||||
current_dest: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the resource iterator that yields the source and target paths.
|
||||
/// Needed when using [`Self::from_map`].
|
||||
pub fn iter(self) -> ResourcePathsIter<'a> {
|
||||
self.iter
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator of a [`ResourcePaths`].
|
||||
pub struct ResourcePathsIter<'a> {
|
||||
/// the patterns to iterate.
|
||||
pattern_iter: std::slice::Iter<'a, String>,
|
||||
pattern_iter: PatternIter<'a>,
|
||||
/// the glob iterator if the path from the current iteration is a glob pattern.
|
||||
glob_iter: Option<glob::Paths>,
|
||||
/// the walkdir iterator if the path from the current iteration is a directory.
|
||||
@@ -50,22 +101,28 @@ pub struct ResourcePaths<'a> {
|
||||
/// whether the resource paths allows directories or not.
|
||||
allow_walk: bool,
|
||||
/// the pattern of the current iteration.
|
||||
current_pattern: Option<String>,
|
||||
current_pattern: Option<(String, PathBuf)>,
|
||||
/// whether the current pattern is valid or not.
|
||||
current_pattern_is_valid: bool,
|
||||
/// Current destination path. Only set when the iterator comes from a Map.
|
||||
current_dest: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> ResourcePaths<'a> {
|
||||
/// Creates a new ResourcePaths from a slice of patterns to iterate
|
||||
pub fn new(patterns: &'a [String], allow_walk: bool) -> ResourcePaths<'a> {
|
||||
ResourcePaths {
|
||||
pattern_iter: patterns.iter(),
|
||||
glob_iter: None,
|
||||
walk_iter: None,
|
||||
allow_walk,
|
||||
current_pattern: None,
|
||||
current_pattern_is_valid: false,
|
||||
}
|
||||
/// Information for a resource.
|
||||
pub struct Resource {
|
||||
path: PathBuf,
|
||||
target: PathBuf,
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
/// The path of the resource.
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
/// The target location of the resource.
|
||||
pub fn target(&self) -> &Path {
|
||||
&self.target
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +130,28 @@ impl<'a> Iterator for ResourcePaths<'a> {
|
||||
type Item = crate::Result<PathBuf>;
|
||||
|
||||
fn next(&mut self) -> Option<crate::Result<PathBuf>> {
|
||||
self.iter.next().map(|r| r.map(|res| res.path))
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize(path: &Path) -> PathBuf {
|
||||
let mut dest = PathBuf::new();
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::Prefix(_) => {}
|
||||
Component::RootDir => dest.push("/"),
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => dest.push(".."),
|
||||
Component::Normal(string) => dest.push(string),
|
||||
}
|
||||
}
|
||||
dest
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ResourcePathsIter<'a> {
|
||||
type Item = crate::Result<Resource>;
|
||||
|
||||
fn next(&mut self) -> Option<crate::Result<Resource>> {
|
||||
loop {
|
||||
if let Some(ref mut walk_entries) = self.walk_iter {
|
||||
if let Some(entry) = walk_entries.next() {
|
||||
@@ -85,7 +164,20 @@ impl<'a> Iterator for ResourcePaths<'a> {
|
||||
continue;
|
||||
}
|
||||
self.current_pattern_is_valid = true;
|
||||
return Some(Ok(path.to_path_buf()));
|
||||
return Some(Ok(Resource {
|
||||
target: if let (Some(current_dest), Some(current_pattern)) =
|
||||
(&self.current_dest, &self.current_pattern)
|
||||
{
|
||||
if current_pattern.0.contains('*') {
|
||||
current_dest.join(path.file_name().unwrap())
|
||||
} else {
|
||||
current_dest.join(path.strip_prefix(¤t_pattern.1).unwrap())
|
||||
}
|
||||
} else {
|
||||
resource_relpath(path)
|
||||
},
|
||||
path: path.to_path_buf(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
self.walk_iter = None;
|
||||
@@ -105,24 +197,51 @@ impl<'a> Iterator for ResourcePaths<'a> {
|
||||
}
|
||||
}
|
||||
self.current_pattern_is_valid = true;
|
||||
return Some(Ok(path));
|
||||
return Some(Ok(Resource {
|
||||
target: if let Some(current_dest) = &self.current_dest {
|
||||
current_dest.join(path.file_name().unwrap())
|
||||
} else {
|
||||
resource_relpath(&path)
|
||||
},
|
||||
path,
|
||||
}));
|
||||
} else if let Some(current_path) = &self.current_pattern {
|
||||
if !self.current_pattern_is_valid {
|
||||
self.glob_iter = None;
|
||||
return Some(Err(crate::Error::GlobPathNotFound(current_path.clone())));
|
||||
return Some(Err(crate::Error::GlobPathNotFound(current_path.0.clone())));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.glob_iter = None;
|
||||
if let Some(pattern) = self.pattern_iter.next() {
|
||||
self.current_pattern = Some(pattern.to_string());
|
||||
self.current_pattern_is_valid = false;
|
||||
let glob = match glob::glob(pattern) {
|
||||
Ok(glob) => glob,
|
||||
Err(error) => return Some(Err(error.into())),
|
||||
};
|
||||
self.glob_iter = Some(glob);
|
||||
continue;
|
||||
self.current_dest = None;
|
||||
match &mut self.pattern_iter {
|
||||
PatternIter::Slice(iter) => {
|
||||
if let Some(pattern) = iter.next() {
|
||||
self.current_pattern = Some((pattern.to_string(), normalize(Path::new(pattern))));
|
||||
self.current_pattern_is_valid = false;
|
||||
let glob = match glob::glob(pattern) {
|
||||
Ok(glob) => glob,
|
||||
Err(error) => return Some(Err(error.into())),
|
||||
};
|
||||
self.glob_iter = Some(glob);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PatternIter::Map(iter) => {
|
||||
if let Some((pattern, dest)) = iter.next() {
|
||||
self.current_pattern = Some((pattern.to_string(), normalize(Path::new(pattern))));
|
||||
self.current_pattern_is_valid = false;
|
||||
let glob = match glob::glob(pattern) {
|
||||
Ok(glob) => glob,
|
||||
Err(error) => return Some(Err(error.into())),
|
||||
};
|
||||
self
|
||||
.current_dest
|
||||
.replace(resource_relpath(&PathBuf::from(dest)));
|
||||
self.glob_iter = Some(glob);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,198 @@
|
||||
# Changelog
|
||||
|
||||
## \[1.6.6]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`704260bb3`](https://www.github.com/tauri-apps/tauri/commit/704260bb3c2bc54c149f2fe508bff09535b083ad)([#9784](https://www.github.com/tauri-apps/tauri/pull/9784)) Fix dialog crash on macOS when the `default_path` value is empty.
|
||||
- [`3b69c1384`](https://www.github.com/tauri-apps/tauri/commit/3b69c1384bd089ad5dcff0c1b12fbfadeb585c6a)([#9792](https://www.github.com/tauri-apps/tauri/pull/9792)) Revert [#9706](https://github.com/tauri-apps/tauri/pull/9706) which broke compatability between `tauri` crate and the JS `@tauri-apps/api` npm package in a patch release where it should've been in a minor release.
|
||||
|
||||
## \[1.6.5]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`ef35a793c`](https://www.github.com/tauri-apps/tauri/commit/ef35a793c5d923d55e338b51e04e6c280f7c810d)([#9729](https://www.github.com/tauri-apps/tauri/pull/9729)) Fix compilation error when `shell-execute` or `shell-sidecar` features are not active
|
||||
|
||||
## \[1.6.4]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`7f885bd5e`](https://www.github.com/tauri-apps/tauri/commit/7f885bd5edf3e179ddf0b674c3ea7a96e26ce39e)([#9706](https://www.github.com/tauri-apps/tauri/pull/9706)) Enhance the speed of The JS `Command.execute` API from `shell` module.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@0.14.7`
|
||||
|
||||
## \[1.6.3]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`3e98145ac`](https://www.github.com/tauri-apps/tauri/commit/3e98145ac3f45d37230661e136e4afc08b072285)([#9570](https://www.github.com/tauri-apps/tauri/pull/9570)) Run each plugin initialization script on its own context so they do not interfere with each other or the Tauri init script.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.4`
|
||||
- Upgraded to `tauri-runtime@0.14.3`
|
||||
- Upgraded to `tauri-runtime-wry@0.14.6`
|
||||
- Upgraded to `tauri-macros@1.4.4`
|
||||
|
||||
## \[1.6.2]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`e3b6d38d2`](https://www.github.com/tauri-apps/tauri/commit/e3b6d38d26d27b292f98d6c0e8603a15265a5b43)([#9166](https://www.github.com/tauri-apps/tauri/pull/9166)) Fix `basename(path, 'ext')` JS API when removing all occurances of `ext` where it should only remove the last one.
|
||||
- [`705da977a`](https://www.github.com/tauri-apps/tauri/commit/705da977a9c941a4b2d90219b34925498f507ab2)([#9529](https://www.github.com/tauri-apps/tauri/pull/9529)) Do not use JS optional chaining to prevent script errors on older webviews such as macOS 10.14.
|
||||
|
||||
## \[1.6.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@0.14.5`
|
||||
|
||||
## \[1.6.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`6e488378`](https://www.github.com/tauri-apps/tauri/commit/6e48837860203582d2ef8e59d4524f98511a14c0)([#8474](https://www.github.com/tauri-apps/tauri/pull/8474)) Re-export `Url` type.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`8ce51cec`](https://www.github.com/tauri-apps/tauri/commit/8ce51cec3baf4ed88d80c59bf3bbe96fd369c7a0)([#7718](https://www.github.com/tauri-apps/tauri/pull/7718)) On Windows, retain command line args when relaunching the app after an update. Supports NSIS and WiX (without elevated update task).
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`cc3d8e77`](https://www.github.com/tauri-apps/tauri/commit/cc3d8e77313672f25520e278bbe8fae1b275a735)([#8539](https://www.github.com/tauri-apps/tauri/pull/8539)) Fixes a deadlock when reading a stdout or stderr line returns an error.
|
||||
- [`b546b42d`](https://www.github.com/tauri-apps/tauri/commit/b546b42db7e75a59232367dd6212fe3b75bb4c6d)([#8577](https://www.github.com/tauri-apps/tauri/pull/8577)) Preserve the order of JS object/map keys in IPC calls. This also fixes issues with the JS `http` module when calling to servers that required a specific order of `FormBody` contents.
|
||||
- [`8f8729d9`](https://www.github.com/tauri-apps/tauri/commit/8f8729d91843acd2bd2a24731db865d690dd9ab1)([#8312](https://www.github.com/tauri-apps/tauri/pull/8312)) On macOS, allow cancelling maximization when doubleclick happens on `data-tauri-drag-region` by simply keeping the left moust button pressed and then moving the mouse away of the starting position of the click, which is consistent with the native behavior of macOS.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@0.14.4`
|
||||
|
||||
## \[1.5.4]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`3c371aa8`](https://www.github.com/tauri-apps/tauri/commit/3c371aa8ee4032998f859b570702e81e26e77c6c)([#8228](https://www.github.com/tauri-apps/tauri/pull/8228)) Added `test::get_ipc_response`.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`50a3d170`](https://www.github.com/tauri-apps/tauri/commit/50a3d170f242178d41fe7e8a3adf964541f6fe9c)([#8408](https://www.github.com/tauri-apps/tauri/pull/8408)) On Windows, fix `open` dialog `defaultPath`, when invoked from JS, not working if the path uses forward slash (`/`)
|
||||
- [`645e1dcc`](https://www.github.com/tauri-apps/tauri/commit/645e1dcc6e113564e2ddaacf9cb8338aed1a0bd0)([#8404](https://www.github.com/tauri-apps/tauri/pull/8404)) Fix NSIS updater failing to launch when using `basicUi` mode.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@0.14.3`
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
- Upgraded to `tauri-runtime@0.14.2`
|
||||
- Upgraded to `tauri-macros@1.4.3`
|
||||
|
||||
## \[1.5.3]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`b3e53e72`](https://www.github.com/tauri-apps/tauri/commit/b3e53e7243311a2659b7569dddc20c56ac9f9d8e)([#8288](https://www.github.com/tauri-apps/tauri/pull/8288)) Added `AssetResolver::iter` to iterate on all embedded assets.
|
||||
- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`2ba88563`](https://www.github.com/tauri-apps/tauri/commit/2ba8856343e284ed022f28cff6d16db15ad4645f)([#8095](https://www.github.com/tauri-apps/tauri/pull/8095)) Fix docs.rs build for `x86_64-apple-darwin`.
|
||||
- [`4b6a602a`](https://www.github.com/tauri-apps/tauri/commit/4b6a602a89b36f24d34d6ccd8e3c9b7ce202c9eb)([#8234](https://www.github.com/tauri-apps/tauri/pull/8234)) Escape path of the updater msi to avoid crashing on installers with spaces.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@0.14.2`
|
||||
- Upgraded to `tauri-macros@1.4.2`
|
||||
|
||||
## \[1.5.2]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`21cdbb41`](https://www.github.com/tauri-apps/tauri/commit/21cdbb41a38f465148bbeb82feb3e7886c320182)([#7982](https://www.github.com/tauri-apps/tauri/pull/7982)) Set the correct `truncate` option on `OpenOptions` so that `write_file` can completely overwrite existing files.
|
||||
|
||||
## \[1.5.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`3671edbc`](https://www.github.com/tauri-apps/tauri/commit/3671edbcff37447c95382ab4c9fd1c36a460a037)([#7937](https://www.github.com/tauri-apps/tauri/pull/7937)) Fix devtools not toggling on `ctrl+shift+i` or `cmd+alt+i` shortcuts.
|
||||
|
||||
## \[1.5.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`eeb6be54`](https://www.github.com/tauri-apps/tauri/commit/eeb6be54228f3e5463a28c68956abb06a694c010)([#7512](https://www.github.com/tauri-apps/tauri/pull/7512)) Add `tauri::Manager::emit_filter` and only serialize once when emitting to multiple windows.
|
||||
- [`6c408b73`](https://www.github.com/tauri-apps/tauri/commit/6c408b736c7aa2a0a91f0a40d45a2b7a7dedfe78)([#7269](https://www.github.com/tauri-apps/tauri/pull/7269)) Add option to specify notification sound.
|
||||
- [`fdaee9a5`](https://www.github.com/tauri-apps/tauri/commit/fdaee9a5ce988c448dd035c2050c339d275e8d15)([#7350](https://www.github.com/tauri-apps/tauri/pull/7350)) Add `tauri::plugin::Builder::register_uri_scheme_protocol`
|
||||
- [`10e362d0`](https://www.github.com/tauri-apps/tauri/commit/10e362d098c9bed48f832bad471fb2fab83ab0bb)([#7432](https://www.github.com/tauri-apps/tauri/pull/7432)) Added `UpdateBuilder::endpoints` to add request endpoints at runtime.
|
||||
- [`10e362d0`](https://www.github.com/tauri-apps/tauri/commit/10e362d098c9bed48f832bad471fb2fab83ab0bb)([#7432](https://www.github.com/tauri-apps/tauri/pull/7432)) Added `UpdateResponse::header` and `UpdateResponse::remove_header` to modify the update download request headers.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`757e959e`](https://www.github.com/tauri-apps/tauri/commit/757e959eb276ed535cfddb0dea8897c56441c644)([#7344](https://www.github.com/tauri-apps/tauri/pull/7344)) Open links externally when `<base target="_blank" />` exists
|
||||
- [`c9827338`](https://www.github.com/tauri-apps/tauri/commit/c98273387c0ffbb8d0de78ce17006411a1f503ee)([#7416](https://www.github.com/tauri-apps/tauri/pull/7416)) Enhance `readDir` API error with path information.
|
||||
- [`58d6b899`](https://www.github.com/tauri-apps/tauri/commit/58d6b899e21d37bb42810890d289deb57f2273bd)([#7636](https://www.github.com/tauri-apps/tauri/pull/7636)) Add `append` option to `FsOptions` in the `fs` JS module, used in `writeTextFile` and `writeBinaryFile`, to be able to append to existing files instead of overwriting it.
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`4bf1e85e`](https://www.github.com/tauri-apps/tauri/commit/4bf1e85e6bf85a7ec92d50c8465bc0588a6399d8)([#7722](https://www.github.com/tauri-apps/tauri/pull/7722)) Properly respect the `focused` option when creating the webview.
|
||||
- [`0797a002`](https://www.github.com/tauri-apps/tauri/commit/0797a002caad29cd8bedccf01f64bf3b45a5e528)([#7746](https://www.github.com/tauri-apps/tauri/pull/7746)) On macOS, fixed tapping on custom title bar doesn't maximize the window.
|
||||
- [`1a3dcdb8`](https://www.github.com/tauri-apps/tauri/commit/1a3dcdb8302fad511f2c1cd418fbc4cff0bd62ac)([#7185](https://www.github.com/tauri-apps/tauri/pull/7185)) On Windows, fix NSIS installers requiring administrator rights failing to be launched by updater.
|
||||
- [`fa7f9b77`](https://www.github.com/tauri-apps/tauri/commit/fa7f9b77ab8f0c890e9d7b120901610e0d3e4c46)([#7341](https://www.github.com/tauri-apps/tauri/pull/7341)) Fix updater not following endpoint redirects.
|
||||
- [`6fbd6dba`](https://www.github.com/tauri-apps/tauri/commit/6fbd6dba5290dc017ab0ba5a44cf4358b022836f)([#17](https://www.github.com/tauri-apps/tauri/pull/17)) Fix the validation of `std::env::current_exe` warn the user if AppImage is not mounted instead of panicking
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-runtime-wry@0.14.1`
|
||||
- Upgraded to `tauri-runtime@0.14.1`
|
||||
- Upgraded to `tauri-macros@1.4.1`
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`6afd3472`](https://www.github.com/tauri-apps/tauri/commit/6afd34727f153b32dbc568d169dbb17fb8dc3539)([#6680](https://www.github.com/tauri-apps/tauri/pull/6680)) Revert [#6680](https://github.com/tauri-apps/tauri/pull/6680) which added a default sound for notifications on Windows. This introduced inconsistency with other platforms that has silent notifications by default. In the upcoming releases, we will add support for modifying the notification sound across all platforms.
|
||||
|
||||
### Security fixes
|
||||
|
||||
- [`066c09a6`](https://www.github.com/tauri-apps/tauri/commit/066c09a6ea06f42f550d090715e06beb65cd5564)([#7227](https://www.github.com/tauri-apps/tauri/pull/7227)) Fix regression in `1.4` where the default behavior of the file system scope was changed to allow reading hidden files and directories by default.
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`7c237209`](https://www.github.com/tauri-apps/tauri/commit/7c237209207cd2938df660b6fd87d3b7d728bd03)([#6546](https://www.github.com/tauri-apps/tauri/pull/6546)) Added `tauri::VERSION` const to get Tauri's version from Rust.
|
||||
- [`4c39e46a`](https://www.github.com/tauri-apps/tauri/commit/4c39e46a3b438d007f139166ab2a0ba34291a10a)([#7026](https://www.github.com/tauri-apps/tauri/pull/7026)) Added `tauri::webview_version` , to get webview version.
|
||||
- [`359058ce`](https://www.github.com/tauri-apps/tauri/commit/359058cecca44a9c30b65140c44a8bb3a6dd3be8)([#5939](https://www.github.com/tauri-apps/tauri/pull/5939)) Add `tauri::api::os::locale` function to get the system locale.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` options to the window builder.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `set_maximizable`, `set_minimizable`, `set_closable`, `is_maximizable`, `is_minimizable` and `is_closable` methods on `Window`.
|
||||
- [`1d99f8a3`](https://www.github.com/tauri-apps/tauri/commit/1d99f8a3c2f989d1a5ba4d805e3a40b07a3ca8a5)([#4752](https://www.github.com/tauri-apps/tauri/pull/4752)) Expose the `test` module behind the `test` Cargo feature.
|
||||
- [`000104bc`](https://www.github.com/tauri-apps/tauri/commit/000104bc3bc0c9ff3d20558ab9cf2080f126e9e0)([#6472](https://www.github.com/tauri-apps/tauri/pull/6472)) Add `Window::is_focused` and `Manager::get_focused_window` getters.
|
||||
- [`441f9646`](https://www.github.com/tauri-apps/tauri/commit/441f96465488a4f8a5731cc51b8ac97b685898c7)([#5491](https://www.github.com/tauri-apps/tauri/pull/5491)) Add `MenuHandle::try_get_item` and `SystemTrayHandle::try_get_item` which returns a `Option` instead of panicking.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`45330e38`](https://www.github.com/tauri-apps/tauri/commit/45330e38193d0b2a01aa926aec433acc6b8f6597)([#6375](https://www.github.com/tauri-apps/tauri/pull/6375)) Enhance the `asset` protocol to support streaming of large files.
|
||||
- [`df89ccc1`](https://www.github.com/tauri-apps/tauri/commit/df89ccc1912db6b81d43d56c9e6d66980ece2e8d)([#6955](https://www.github.com/tauri-apps/tauri/pull/6955)) Support `passive` mode for NSIS updater.
|
||||
- [`cd3846c8`](https://www.github.com/tauri-apps/tauri/commit/cd3846c8ce61ab2879b3911e831525e6242aaab2)([#6955](https://www.github.com/tauri-apps/tauri/pull/6955)) Restart the app after the NSIS updater is finished.
|
||||
- [`db7c5fbf`](https://www.github.com/tauri-apps/tauri/commit/db7c5fbf2e86f3694720f65834eb2c258b7c1291)([#7143](https://www.github.com/tauri-apps/tauri/pull/7143)) Remove `attohttpc` in favor of `reqwest`.
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
- [`5d85d099`](https://www.github.com/tauri-apps/tauri/commit/5d85d0990cd13a1446953a58633edc24eda55afe)([#7128](https://www.github.com/tauri-apps/tauri/pull/7128)) Send updater status events even if default dialog is enabled.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`82169e69`](https://www.github.com/tauri-apps/tauri/commit/82169e69fc904d2c7980534c4479bb6f38259fb4)([#5208](https://www.github.com/tauri-apps/tauri/pull/5208)) Fix parsing `allowlist > http > scope` urls that added a trailing slash which broke matching the incoming requests url.
|
||||
- [`b41b57eb`](https://www.github.com/tauri-apps/tauri/commit/b41b57ebb27befd366db5befaafb6043c18fdfef)([#7105](https://www.github.com/tauri-apps/tauri/pull/7105)) Fix panics when registering an invalid global shortcuts or checking it is registered and return proper errors instead.
|
||||
- [`aecf1469`](https://www.github.com/tauri-apps/tauri/commit/aecf14690947d109745b4ad823a3e8f4338de47a)([#6889](https://www.github.com/tauri-apps/tauri/pull/6889)) Fix IPC failing after a failed navigation to an external URL.
|
||||
- [`076e1a81`](https://www.github.com/tauri-apps/tauri/commit/076e1a81a50468e3dfb34ae9ca7e77c5e1758daa)([#7119](https://www.github.com/tauri-apps/tauri/pull/7119)) Fix unlistening to window events failing sometimes.
|
||||
- [`3f35b452`](https://www.github.com/tauri-apps/tauri/commit/3f35b452637ef1c794a423f1eda62a15d2ddaf42)([#4080](https://www.github.com/tauri-apps/tauri/pull/4080)) Fix `WindowBuilder::on_navigation` handler not registered properly.
|
||||
- [`0503eb69`](https://www.github.com/tauri-apps/tauri/commit/0503eb69ce7df6b4ed8f5249fdb519b86cd57d8d)([#7078](https://www.github.com/tauri-apps/tauri/pull/7078)) On macOS and Linux, fix app crashing when creating a window with `data:` uri.
|
||||
- [`3700793a`](https://www.github.com/tauri-apps/tauri/commit/3700793a2f1ea3686b1889c345d73007bb622a29)([#6934](https://www.github.com/tauri-apps/tauri/pull/6934)) Emit `UPTODATE` update status to javascript when the updater server returns status code `204`
|
||||
- [`ff5e4dbb`](https://www.github.com/tauri-apps/tauri/commit/ff5e4dbbb01bf3fc9c5143df732c75eef6fd98cb)([#6794](https://www.github.com/tauri-apps/tauri/pull/6794)) Fix some configurations not applied when creating the window through Javascript.
|
||||
- [`65fd674f`](https://www.github.com/tauri-apps/tauri/commit/65fd674f50ba0395d5cea23daf9d2f49f95647fe)([#6652](https://www.github.com/tauri-apps/tauri/pull/6652)) Play a sound when showing a notification on Windows.
|
||||
- [`696d77c3`](https://www.github.com/tauri-apps/tauri/commit/696d77c3ce480f4a3b4c1c57dae64ff2bb7842ce)([#4493](https://www.github.com/tauri-apps/tauri/pull/4493)) Fixes global events not being received on window-specific event listeners.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Added the `additional_browser_args` option when creating a window.
|
||||
|
||||
@@ -10,14 +10,13 @@ license = "Apache-2.0 OR MIT"
|
||||
name = "tauri"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/tauri-apps/tauri"
|
||||
version = "1.3.0"
|
||||
version = "1.6.6"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
no-default-features = true
|
||||
features = [
|
||||
"wry",
|
||||
"custom-protocol",
|
||||
"api-all",
|
||||
"windows7-compat",
|
||||
"cli",
|
||||
"updater",
|
||||
@@ -26,7 +25,17 @@ features = [
|
||||
"devtools",
|
||||
"http-multipart",
|
||||
"icon-png",
|
||||
"dox"
|
||||
"test",
|
||||
"dox",
|
||||
"dialog",
|
||||
"global-shortcut",
|
||||
"http-request",
|
||||
"os-api",
|
||||
"process-relaunch",
|
||||
"process-exit",
|
||||
"protocol-asset",
|
||||
"process-command-api",
|
||||
"shell-open"
|
||||
]
|
||||
rustdoc-args = [ "--cfg", "doc_cfg" ]
|
||||
default-target = "x86_64-unknown-linux-gnu"
|
||||
@@ -37,10 +46,10 @@ targets = [
|
||||
]
|
||||
|
||||
[package.metadata.cargo-udeps.ignore]
|
||||
normal = [ "attohttpc", "reqwest" ]
|
||||
normal = [ "reqwest", "nix" ]
|
||||
|
||||
[dependencies]
|
||||
serde_json = { version = "1.0", features = [ "raw_value" ] }
|
||||
serde_json = { version = "1.0", features = [ "raw_value", "preserve_order" ] }
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
tokio = { version = "1", features = [ "rt", "rt-multi-thread", "sync", "fs", "io-util" ] }
|
||||
futures-util = "0.3"
|
||||
@@ -49,10 +58,10 @@ url = { version = "2.3" }
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
once_cell = "1"
|
||||
tauri-runtime = { version = "0.13.0", path = "../tauri-runtime" }
|
||||
tauri-macros = { version = "1.3.0", path = "../tauri-macros" }
|
||||
tauri-utils = { version = "1.3.0", features = [ "resources" ], path = "../tauri-utils" }
|
||||
tauri-runtime-wry = { version = "0.13.0", path = "../tauri-runtime-wry", optional = true }
|
||||
tauri-runtime = { version = "0.14.3", path = "../tauri-runtime" }
|
||||
tauri-macros = { version = "1.4.4", path = "../tauri-macros" }
|
||||
tauri-utils = { version = "1.5.4", features = [ "resources" ], path = "../tauri-utils" }
|
||||
tauri-runtime-wry = { version = "0.14.7", path = "../tauri-runtime-wry", optional = true }
|
||||
rand = "0.8"
|
||||
semver = { version = "1.0", features = [ "serde" ] }
|
||||
serde_repr = "0.1"
|
||||
@@ -60,7 +69,7 @@ state = "0.5"
|
||||
tar = "0.4.38"
|
||||
tempfile = "3"
|
||||
zip = { version = "0.6", default-features = false, optional = true }
|
||||
ignore = "=0.4.18"
|
||||
ignore = "0.4"
|
||||
flate2 = "1.0"
|
||||
http = "0.2"
|
||||
dirs-next = "2.0"
|
||||
@@ -69,15 +78,14 @@ base64 = { version = "0.21", optional = true }
|
||||
clap = { version = "3", optional = true }
|
||||
reqwest = { version = "0.11", features = [ "json", "stream" ], optional = true }
|
||||
bytes = { version = "1", features = [ "serde" ], optional = true }
|
||||
attohttpc = { version = "0.22", features = [ "compress", "json", "form" ], optional = true }
|
||||
open = { version = "3.2", optional = true }
|
||||
shared_child = { version = "1.0", optional = true }
|
||||
os_pipe = { version = "1.0", optional = true }
|
||||
raw-window-handle = "=0.5.0"
|
||||
raw-window-handle = "0.5"
|
||||
minisign-verify = { version = "0.2", optional = true }
|
||||
time = { version = "=0.3.15", features = [ "parsing", "formatting" ], optional = true }
|
||||
time = { version = "0.3", features = [ "parsing", "formatting" ], optional = true }
|
||||
os_info = { version = "3", optional = true }
|
||||
regex = { version = "1.6.0", optional = true }
|
||||
regex = { version = "1", optional = true }
|
||||
glob = "0.3"
|
||||
data-url = { version = "0.2", optional = true }
|
||||
serialize-to-javascript = "=0.1.1"
|
||||
@@ -85,6 +93,9 @@ infer = { version = "0.9", optional = true }
|
||||
png = { version = "0.17", optional = true }
|
||||
ico = { version = "0.2.0", optional = true }
|
||||
encoding_rs = "0.8.31"
|
||||
sys-locale = { version = "0.2.3", optional = true }
|
||||
tracing = { version = "0.1", optional = true }
|
||||
indexmap = { version = "1", features = [ "std", "serde" ], optional = true }
|
||||
|
||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
rfd = { version = "0.10", optional = true, features = [ "gtk3", "common-controls-v6" ] }
|
||||
@@ -94,6 +105,7 @@ notify-rust = { version = "4.5", optional = true }
|
||||
gtk = { version = "0.15", features = [ "v3_20" ] }
|
||||
glib = "0.15"
|
||||
webkit2gtk = { version = "0.18.2", features = [ "v2_22" ] }
|
||||
nix = { version = "0.26.0", default-features = false, features = [ "user", "socket", "uio" ], optional = true }
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
embed_plist = "1.2"
|
||||
@@ -101,15 +113,16 @@ cocoa = "0.24"
|
||||
objc = "0.2"
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
dunce = "1"
|
||||
webview2-com = "0.19.1"
|
||||
win7-notifications = { version = "0.3.1", optional = true }
|
||||
win7-notifications = { version = "0.4", optional = true }
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.39.0"
|
||||
features = [ "Win32_Foundation" ]
|
||||
|
||||
[build-dependencies]
|
||||
heck = "0.4"
|
||||
heck = "0.5"
|
||||
once_cell = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -123,10 +136,15 @@ tauri = { path = ".", default-features = false, features = [ "wry" ] }
|
||||
tokio-test = "0.4.2"
|
||||
tokio = { version = "1", features = [ "full" ] }
|
||||
cargo_toml = "0.11"
|
||||
winnow = "=0.4.1"
|
||||
|
||||
[features]
|
||||
default = [ "wry", "compression", "objc-exception" ]
|
||||
tracing = [
|
||||
"dep:tracing",
|
||||
"tauri-macros/tracing",
|
||||
"tauri-runtime-wry/tracing"
|
||||
]
|
||||
test = [ ]
|
||||
compression = [ "tauri-macros/compression", "tauri-utils/compression" ]
|
||||
wry = [ "tauri-runtime-wry" ]
|
||||
objc-exception = [ "tauri-runtime-wry/objc-exception" ]
|
||||
@@ -141,13 +159,14 @@ updater = [
|
||||
"dialog-ask",
|
||||
"fs-extract-api"
|
||||
]
|
||||
http-api = [ "attohttpc" ]
|
||||
http-multipart = [ "attohttpc/multipart-form", "reqwest/multipart" ]
|
||||
http-api = [ "reqwest", "bytes", "indexmap" ]
|
||||
http-multipart = [ "reqwest/multipart" ]
|
||||
os-api = [ "sys-locale" ]
|
||||
shell-open-api = [ "open", "regex", "tauri-macros/shell-scope" ]
|
||||
fs-extract-api = [ "zip" ]
|
||||
reqwest-client = [ "reqwest", "bytes" ]
|
||||
reqwest-native-tls-vendored = [ "reqwest-client", "reqwest/native-tls-vendored" ]
|
||||
native-tls-vendored = [ "attohttpc/tls-vendored" ]
|
||||
reqwest-client = [ "http-api" ]
|
||||
reqwest-native-tls-vendored = [ "native-tls-vendored" ]
|
||||
native-tls-vendored = [ "reqwest/native-tls-vendored" ]
|
||||
process-command-api = [ "shared_child", "os_pipe" ]
|
||||
global-shortcut = [
|
||||
"tauri-runtime/global-shortcut",
|
||||
@@ -155,7 +174,7 @@ global-shortcut = [
|
||||
]
|
||||
clipboard = [ "tauri-runtime/clipboard", "tauri-runtime-wry/clipboard" ]
|
||||
dialog = [ "rfd" ]
|
||||
notification = [ "notify-rust" ]
|
||||
notification = [ "notify-rust", "nix" ]
|
||||
cli = [ "clap" ]
|
||||
system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ]
|
||||
devtools = [ "tauri-runtime/devtools", "tauri-runtime-wry/devtools" ]
|
||||
@@ -214,7 +233,7 @@ global-shortcut-all = [ "global-shortcut" ]
|
||||
http-all = [ "http-request" ]
|
||||
http-request = [ "http-api" ]
|
||||
notification-all = [ "notification", "dialog-ask" ]
|
||||
os-all = [ "os_info" ]
|
||||
os-all = [ "os_info", "os-api" ]
|
||||
path-all = [ ]
|
||||
process-all = [ "process-relaunch", "process-exit" ]
|
||||
process-exit = [ ]
|
||||
@@ -231,6 +250,9 @@ window-all = [
|
||||
"window-center",
|
||||
"window-request-user-attention",
|
||||
"window-set-resizable",
|
||||
"window-set-maximizable",
|
||||
"window-set-minimizable",
|
||||
"window-set-closable",
|
||||
"window-set-title",
|
||||
"window-maximize",
|
||||
"window-unmaximize",
|
||||
@@ -262,6 +284,9 @@ window-create = [ ]
|
||||
window-center = [ ]
|
||||
window-request-user-attention = [ ]
|
||||
window-set-resizable = [ ]
|
||||
window-set-maximizable = [ ]
|
||||
window-set-minimizable = [ ]
|
||||
window-set-closable = [ ]
|
||||
window-set-title = [ ]
|
||||
window-maximize = [ ]
|
||||
window-unmaximize = [ ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
@@ -71,6 +71,9 @@ fn main() {
|
||||
"center",
|
||||
"request-user-attention",
|
||||
"set-resizable",
|
||||
"set-maximizable",
|
||||
"set-minimizable",
|
||||
"set-closable",
|
||||
"set-title",
|
||||
"maximize",
|
||||
"unmaximize",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -13,12 +13,22 @@
|
||||
})
|
||||
}
|
||||
|
||||
const osName = __TEMPLATE_os_name__
|
||||
const protocolScheme = __TEMPLATE_protocol_scheme__
|
||||
|
||||
window.__TAURI__.convertFileSrc = function convertFileSrc(filePath, protocol = 'asset') {
|
||||
const path = encodeURIComponent(filePath)
|
||||
return osName === 'windows'
|
||||
? `${protocolScheme}://${protocol}.localhost/${path}`
|
||||
: `${protocol}://localhost/${path}`
|
||||
}
|
||||
|
||||
window.__TAURI__.transformCallback = function transformCallback(
|
||||
callback,
|
||||
once
|
||||
) {
|
||||
var identifier = uid()
|
||||
var prop = `_${identifier}`
|
||||
const identifier = uid()
|
||||
const prop = `_${identifier}`
|
||||
|
||||
Object.defineProperty(window, prop, {
|
||||
value: (result) => {
|
||||
@@ -50,11 +60,11 @@
|
||||
|
||||
window.__TAURI_INVOKE__ = function invoke(cmd, args = {}) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var callback = window.__TAURI__.transformCallback(function (r) {
|
||||
const callback = window.__TAURI__.transformCallback(function (r) {
|
||||
resolve(r)
|
||||
delete window[`_${error}`]
|
||||
}, true)
|
||||
var error = window.__TAURI__.transformCallback(function (e) {
|
||||
const error = window.__TAURI__.transformCallback(function (e) {
|
||||
reject(e)
|
||||
delete window[`_${callback}`]
|
||||
}, true)
|
||||
@@ -91,13 +101,15 @@
|
||||
document.querySelector('body').addEventListener(
|
||||
'click',
|
||||
function (e) {
|
||||
var target = e.target
|
||||
let target = e.target
|
||||
const base = document.querySelector('head base')
|
||||
const baseTarget = base ? base.target : null
|
||||
while (target != null) {
|
||||
if (target.matches('a')) {
|
||||
if (
|
||||
target.href &&
|
||||
(['http://', 'https://', 'mailto:', 'tel:'].some(v => target.href.startsWith(v))) &&
|
||||
target.target === '_blank'
|
||||
(target.target === '_blank' || (!target.target && baseTarget === "_blank"))
|
||||
) {
|
||||
window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Shell',
|
||||
@@ -131,16 +143,40 @@
|
||||
)
|
||||
}
|
||||
|
||||
// drag region
|
||||
//-----------------------//
|
||||
// data-tauri-drag-region
|
||||
//
|
||||
// drag on mousedown and maximize on double click on Windows and Linux
|
||||
// while macOS macos maximization should be on mouseup and if the mouse
|
||||
// moves after the double click, it should be cancelled (see https://github.com/tauri-apps/tauri/issues/8306)
|
||||
//-----------------------//
|
||||
const TAURI_DRAG_REGION_ATTR = 'data-tauri-drag-region';
|
||||
let x = 0, y = 0;
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (e.target.hasAttribute('data-tauri-drag-region') && e.buttons === 1) {
|
||||
if (
|
||||
// element has the magic data attribute
|
||||
e.target.hasAttribute(TAURI_DRAG_REGION_ATTR) &&
|
||||
// and was left mouse button
|
||||
e.button === 0 &&
|
||||
// and was normal click to drag or double click to maximize
|
||||
(e.detail === 1 || e.detail === 2)
|
||||
) {
|
||||
|
||||
// macOS maximization happens on `mouseup`,
|
||||
// so we save needed state and early return
|
||||
if (osName === 'macos' && e.detail == 2) {
|
||||
x = e.clientX
|
||||
y = e.clientY
|
||||
return
|
||||
}
|
||||
|
||||
// prevents text cursor
|
||||
e.preventDefault()
|
||||
|
||||
// fix #2549: double click on drag region edge causes content to maximize without window sizing change
|
||||
// https://github.com/tauri-apps/tauri/issues/2549#issuecomment-1250036908
|
||||
e.stopImmediatePropagation()
|
||||
|
||||
// start dragging if the element has a `tauri-drag-region` data attribute and maximize on double-clicking it
|
||||
window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
@@ -154,6 +190,34 @@
|
||||
})
|
||||
}
|
||||
})
|
||||
// on macOS we maximze on mouseup instead, to match the system behavior where maximization can be canceled
|
||||
// if the mouse moves outside the data-tauri-drag-region
|
||||
if (osName === "macos") {
|
||||
document.addEventListener('mouseup', (e) => {
|
||||
if (
|
||||
// element has the magic data attribute
|
||||
e.target.hasAttribute(TAURI_DRAG_REGION_ATTR) &&
|
||||
// and was left mouse button
|
||||
e.button === 0 &&
|
||||
// and was double click
|
||||
e.detail === 2 &&
|
||||
// and the cursor hasn't moved from initial mousedown
|
||||
e.clientX === x && e.clientY === y
|
||||
) {
|
||||
window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'manage',
|
||||
data: {
|
||||
cmd: {
|
||||
type: '__toggleMaximize'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let permissionSettable = false
|
||||
let permissionValue = 'default'
|
||||
@@ -210,7 +274,7 @@
|
||||
}
|
||||
|
||||
window.Notification = function (title, options) {
|
||||
var opts = options || {}
|
||||
const opts = options || {}
|
||||
sendNotification(
|
||||
Object.assign(opts, {
|
||||
title: title
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,6 +29,4 @@
|
||||
window.__TAURI_INVOKE__('__initialized', { url: window.location.href })
|
||||
})
|
||||
}
|
||||
|
||||
__RAW_plugin_initialization_script__
|
||||
})()
|
||||
|
||||
38
core/tauri/scripts/toggle-devtools.js
Normal file
38
core/tauri/scripts/toggle-devtools.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
(function () {
|
||||
const osName = __TEMPLATE_os_name__
|
||||
|
||||
function toggleDevtoolsHotkey() {
|
||||
const isHotkey = osName === 'macos' ?
|
||||
(event) => event.metaKey && event.altKey && event.code === "KeyI" :
|
||||
(event) => event.ctrlKey && event.shiftKey && event.code === "KeyI";
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (isHotkey(event)) {
|
||||
window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'manage',
|
||||
data: {
|
||||
cmd: {
|
||||
type: '__toggleDevtools'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
document.readyState === "complete" ||
|
||||
document.readyState === "interactive"
|
||||
) {
|
||||
toggleDevtoolsHotkey();
|
||||
} else {
|
||||
window.addEventListener("DOMContentLoaded", toggleDevtoolsHotkey, true);
|
||||
}
|
||||
})();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user