Skip to content

Commit 58fe2e8

Browse files
fix: improvements and ipc fixes for loading window content using custom protocol (#8670)
* fix: improvements and ipc fixes for loading window content using custom protocol closes #5478 * Discard changes to tooling/cli/Cargo.lock * clippy * fix tests * typo * fix webviewurl deserialize * resolve todo, fixes * fmt --------- Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 00e1567 commit 58fe2e8

43 files changed

Lines changed: 8701 additions & 574 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri': 'patch:enhance'
3+
---
4+
5+
Allow IPC calls when window origin is a defined custom protocol.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri-utils': 'patch:breaking'
3+
---
4+
5+
Changed `dist_dir` and `dev_path` config options to be optional.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri-utils': 'patch:feat'
3+
---
4+
5+
Add `WebviewUrl::CustomProtocol` enum variant.

core/tauri-build/src/codegen/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ impl CodegenContext {
8888
&config.build.dist_dir
8989
};
9090
match app_url {
91-
AppUrl::Url(WebviewUrl::App(p)) => {
91+
Some(AppUrl::Url(WebviewUrl::App(p))) => {
9292
println!("cargo:rerun-if-changed={}", config_parent.join(p).display());
9393
}
94-
AppUrl::Files(files) => {
94+
Some(AppUrl::Files(files)) => {
9595
for path in files {
9696
println!(
9797
"cargo:rerun-if-changed={}",

core/tauri-codegen/src/context.rs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -164,36 +164,33 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
164164
};
165165

166166
let assets = match app_url {
167-
AppUrl::Url(url) => match url {
168-
WebviewUrl::External(_) => Default::default(),
169-
WebviewUrl::App(path) => {
170-
if path.components().count() == 0 {
171-
panic!(
172-
"The `{}` configuration cannot be empty",
173-
if dev { "devPath" } else { "distDir" }
174-
)
175-
}
176-
let assets_path = config_parent.join(path);
177-
if !assets_path.exists() {
178-
panic!(
179-
"The `{}` configuration is set to `{:?}` but this path doesn't exist",
180-
if dev { "devPath" } else { "distDir" },
181-
path
182-
)
167+
Some(url) => match url {
168+
AppUrl::Url(url) => match url {
169+
WebviewUrl::External(_) | WebviewUrl::CustomProtocol(_) => Default::default(),
170+
WebviewUrl::App(path) => {
171+
let assets_path = config_parent.join(path);
172+
if !assets_path.exists() {
173+
panic!(
174+
"The `{}` configuration is set to `{:?}` but this path doesn't exist",
175+
if dev { "devPath" } else { "distDir" },
176+
path
177+
)
178+
}
179+
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
183180
}
184-
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
185-
}
181+
_ => unimplemented!(),
182+
},
183+
AppUrl::Files(files) => EmbeddedAssets::new(
184+
files
185+
.iter()
186+
.map(|p| config_parent.join(p))
187+
.collect::<Vec<_>>(),
188+
&options,
189+
map_core_assets(&options, target),
190+
)?,
186191
_ => unimplemented!(),
187192
},
188-
AppUrl::Files(files) => EmbeddedAssets::new(
189-
files
190-
.iter()
191-
.map(|p| config_parent.join(p))
192-
.collect::<Vec<_>>(),
193-
&options,
194-
map_core_assets(&options, target),
195-
)?,
196-
_ => unimplemented!(),
193+
None => Default::default(),
197194
};
198195

199196
let out_dir = {
@@ -398,7 +395,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
398395
Default::default()
399396
};
400397

401-
let resolved_act = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");
398+
let resolved_acl = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");
402399

403400
Ok(quote!({
404401
#[allow(unused_mut, clippy::let_and_return)]
@@ -410,7 +407,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
410407
#package_info,
411408
#info_plist,
412409
#pattern,
413-
#resolved_act
410+
#resolved_acl
414411
);
415412
#with_tray_icon_code
416413
context

core/tauri-config-schema/schema.json

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@
109109
"build": {
110110
"description": "The build configuration.",
111111
"default": {
112-
"devPath": "http://localhost:8080/",
113-
"distDir": "../dist",
114112
"withGlobalTauri": false
115113
},
116114
"allOf": [
@@ -575,13 +573,18 @@
575573
"description": "An URL to open on a Tauri webview window.",
576574
"anyOf": [
577575
{
578-
"description": "An external URL.",
576+
"description": "An external URL. Must use either the `http` or `https` schemes.",
579577
"type": "string",
580578
"format": "uri"
581579
},
582580
{
583581
"description": "The path portion of an app URL. For instance, to load `tauri://localhost/users/john`, you can simply provide `users/john` in this configuration.",
584582
"type": "string"
583+
},
584+
{
585+
"description": "A custom protocol url, for example, `doom://index.html`",
586+
"type": "string",
587+
"format": "uri"
585588
}
586589
]
587590
},
@@ -2408,19 +2411,23 @@
24082411
},
24092412
"devPath": {
24102413
"description": "The path to the application assets or URL to load in development.\n\nThis is usually an URL to a dev server, which serves your application assets with live reloading. Most modern JavaScript bundlers provides a way to start a dev server by default.\n\nSee [vite](https://vitejs.dev/guide/), [Webpack DevServer](https://webpack.js.org/configuration/dev-server/) and [sirv](https://github.com/lukeed/sirv) for examples on how to set up a dev server.",
2411-
"default": "http://localhost:8080/",
2412-
"allOf": [
2414+
"anyOf": [
24132415
{
24142416
"$ref": "#/definitions/AppUrl"
2417+
},
2418+
{
2419+
"type": "null"
24152420
}
24162421
]
24172422
},
24182423
"distDir": {
24192424
"description": "The path to the application assets or URL to load in production.\n\nWhen a path relative to the configuration file is provided, it is read recursively and all files are embedded in the application binary. Tauri then looks for an `index.html` file unless you provide a custom window URL.\n\nYou can also provide a list of paths to be embedded, which allows granular control over what files are added to the binary. In this case, all files are added to the root and you must reference it that way in your HTML files.\n\nWhen an URL is provided, the application won't have bundled assets and the application will load that URL by default.",
2420-
"default": "../dist",
2421-
"allOf": [
2425+
"anyOf": [
24222426
{
24232427
"$ref": "#/definitions/AppUrl"
2428+
},
2429+
{
2430+
"type": "null"
24242431
}
24252432
]
24262433
},

core/tauri-utils/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146

147147
### New Features
148148

149-
- [`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.
149+
- [`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` protocol scopes.
150150
- [`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`.
151151
- [`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.
152152
- [`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`

core/tauri-utils/src/acl/resolved.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use super::{
2121
};
2222

2323
/// A key for a scope, used to link a [`ResolvedCommand#structfield.scope`] to the store [`Resolved#structfield.scopes`].
24-
pub type ScopeKey = usize;
24+
pub type ScopeKey = u64;
2525

2626
/// Metadata for what referenced a [`ResolvedCommand`].
2727
#[cfg(debug_assertions)]
@@ -206,7 +206,7 @@ impl Resolved {
206206

207207
let mut hasher = DefaultHasher::new();
208208
allowed.scope.hash(&mut hasher);
209-
let hash = hasher.finish() as usize;
209+
let hash = hasher.finish();
210210

211211
allowed.resolved_scope_key.replace(hash);
212212

@@ -297,15 +297,15 @@ struct ResolvedCommandTemp {
297297
#[cfg(debug_assertions)]
298298
pub referenced_by: Vec<ResolvedCommandReference>,
299299
pub windows: HashSet<String>,
300-
pub scope: Vec<usize>,
301-
pub resolved_scope_key: Option<usize>,
300+
pub scope: Vec<ScopeKey>,
301+
pub resolved_scope_key: Option<ScopeKey>,
302302
}
303303

304304
fn resolve_command(
305305
commands: &mut BTreeMap<CommandKey, ResolvedCommandTemp>,
306306
command: String,
307307
capability: &Capability,
308-
scope_id: Option<usize>,
308+
scope_id: Option<ScopeKey>,
309309
#[cfg(debug_assertions)] permission: &Permission,
310310
) {
311311
let contexts = match &capability.context {

core/tauri-utils/src/config.rs

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,50 @@ fn default_true() -> bool {
4343
}
4444

4545
/// An URL to open on a Tauri webview window.
46-
#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
46+
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
4747
#[cfg_attr(feature = "schema", derive(JsonSchema))]
4848
#[serde(untagged)]
4949
#[non_exhaustive]
5050
pub enum WebviewUrl {
51-
/// An external URL.
51+
/// An external URL. Must use either the `http` or `https` schemes.
5252
External(Url),
5353
/// The path portion of an app URL.
5454
/// For instance, to load `tauri://localhost/users/john`,
5555
/// you can simply provide `users/john` in this configuration.
5656
App(PathBuf),
57+
/// A custom protocol url, for example, `doom://index.html`
58+
CustomProtocol(Url),
59+
}
60+
61+
impl<'de> Deserialize<'de> for WebviewUrl {
62+
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
63+
where
64+
D: Deserializer<'de>,
65+
{
66+
#[derive(Deserialize)]
67+
#[serde(untagged)]
68+
enum WebviewUrlDeserializer {
69+
Url(Url),
70+
Path(PathBuf),
71+
}
72+
73+
match WebviewUrlDeserializer::deserialize(deserializer)? {
74+
WebviewUrlDeserializer::Url(u) => {
75+
if u.scheme() == "https" || u.scheme() == "http" {
76+
Ok(Self::External(u))
77+
} else {
78+
Ok(Self::CustomProtocol(u))
79+
}
80+
}
81+
WebviewUrlDeserializer::Path(p) => Ok(Self::App(p)),
82+
}
83+
}
5784
}
5885

5986
impl fmt::Display for WebviewUrl {
6087
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6188
match self {
62-
Self::External(url) => write!(f, "{url}"),
89+
Self::External(url) | Self::CustomProtocol(url) => write!(f, "{url}"),
6390
Self::App(path) => write!(f, "{}", path.display()),
6491
}
6592
}
@@ -1858,7 +1885,7 @@ pub enum HookCommand {
18581885
///
18591886
/// See more: <https://tauri.app/v1/api/config#buildconfig>
18601887
#[skip_serializing_none]
1861-
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
1888+
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
18621889
#[cfg_attr(feature = "schema", derive(JsonSchema))]
18631890
#[serde(rename_all = "camelCase", deny_unknown_fields)]
18641891
pub struct BuildConfig {
@@ -1871,8 +1898,8 @@ pub struct BuildConfig {
18711898
///
18721899
/// See [vite](https://vitejs.dev/guide/), [Webpack DevServer](https://webpack.js.org/configuration/dev-server/) and [sirv](https://github.com/lukeed/sirv)
18731900
/// for examples on how to set up a dev server.
1874-
#[serde(default = "default_dev_path", alias = "dev-path")]
1875-
pub dev_path: AppUrl,
1901+
#[serde(alias = "dev-path")]
1902+
pub dev_path: Option<AppUrl>,
18761903
/// The path to the application assets or URL to load in production.
18771904
///
18781905
/// When a path relative to the configuration file is provided,
@@ -1884,8 +1911,8 @@ pub struct BuildConfig {
18841911
///
18851912
/// When an URL is provided, the application won't have bundled assets
18861913
/// and the application will load that URL by default.
1887-
#[serde(default = "default_dist_dir", alias = "dist-dir")]
1888-
pub dist_dir: AppUrl,
1914+
#[serde(alias = "dist-dir")]
1915+
pub dist_dir: Option<AppUrl>,
18891916
/// A shell command to run before `tauri dev` kicks in.
18901917
///
18911918
/// The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
@@ -1908,31 +1935,6 @@ pub struct BuildConfig {
19081935
pub with_global_tauri: bool,
19091936
}
19101937

1911-
impl Default for BuildConfig {
1912-
fn default() -> Self {
1913-
Self {
1914-
runner: None,
1915-
dev_path: default_dev_path(),
1916-
dist_dir: default_dist_dir(),
1917-
before_dev_command: None,
1918-
before_build_command: None,
1919-
before_bundle_command: None,
1920-
features: None,
1921-
with_global_tauri: false,
1922-
}
1923-
}
1924-
}
1925-
1926-
fn default_dev_path() -> AppUrl {
1927-
AppUrl::Url(WebviewUrl::External(
1928-
Url::parse("http://localhost:8080").unwrap(),
1929-
))
1930-
}
1931-
1932-
fn default_dist_dir() -> AppUrl {
1933-
AppUrl::Url(WebviewUrl::App("../dist".into()))
1934-
}
1935-
19361938
#[derive(Debug, PartialEq, Eq)]
19371939
struct PackageVersion(String);
19381940

@@ -2123,8 +2125,8 @@ pub struct PluginConfig(pub HashMap<String, JsonValue>);
21232125
fn default_build() -> BuildConfig {
21242126
BuildConfig {
21252127
runner: None,
2126-
dev_path: default_dev_path(),
2127-
dist_dir: default_dist_dir(),
2128+
dev_path: None,
2129+
dist_dir: None,
21282130
before_dev_command: None,
21292131
before_build_command: None,
21302132
before_bundle_command: None,
@@ -2159,6 +2161,10 @@ mod build {
21592161
let url = url_lit(url);
21602162
quote! { #prefix::External(#url) }
21612163
}
2164+
Self::CustomProtocol(url) => {
2165+
let url = url_lit(url);
2166+
quote! { #prefix::CustomProtocol(#url) }
2167+
}
21622168
})
21632169
}
21642170
}
@@ -2489,8 +2495,8 @@ mod build {
24892495

24902496
impl ToTokens for BuildConfig {
24912497
fn to_tokens(&self, tokens: &mut TokenStream) {
2492-
let dev_path = &self.dev_path;
2493-
let dist_dir = &self.dist_dir;
2498+
let dev_path = opt_lit(self.dev_path.as_ref());
2499+
let dist_dir = opt_lit(self.dist_dir.as_ref());
24942500
let with_global_tauri = self.with_global_tauri;
24952501
let runner = quote!(None);
24962502
let before_dev_command = quote!(None);
@@ -2758,8 +2764,6 @@ mod test {
27582764
let t_config = TauriConfig::default();
27592765
// get default build config
27602766
let b_config = BuildConfig::default();
2761-
// get default dev path
2762-
let d_path = default_dev_path();
27632767
// get default window
27642768
let d_windows: Vec<WindowConfig> = vec![];
27652769
// get default bundle
@@ -2806,10 +2810,8 @@ mod test {
28062810
// create a build config
28072811
let build = BuildConfig {
28082812
runner: None,
2809-
dev_path: AppUrl::Url(WebviewUrl::External(
2810-
Url::parse("http://localhost:8080").unwrap(),
2811-
)),
2812-
dist_dir: AppUrl::Url(WebviewUrl::App("../dist".into())),
2813+
dev_path: None,
2814+
dist_dir: None,
28132815
before_dev_command: None,
28142816
before_build_command: None,
28152817
before_bundle_command: None,
@@ -2821,12 +2823,6 @@ mod test {
28212823
assert_eq!(t_config, tauri);
28222824
assert_eq!(b_config, build);
28232825
assert_eq!(d_bundle, tauri.bundle);
2824-
assert_eq!(
2825-
d_path,
2826-
AppUrl::Url(WebviewUrl::External(
2827-
Url::parse("http://localhost:8080").unwrap()
2828-
))
2829-
);
28302826
assert_eq!(d_windows, tauri.windows);
28312827
}
28322828
}

0 commit comments

Comments
 (0)