mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-11 07:55:34 +03:00
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com> Co-authored-by: Lucas Nogueira <lucas@tauri.studio> Co-authored-by: Raphii <iam@raphii.co> Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de> Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
parent
84c4159754
commit
3b98141aa2
5
.changes/file-associations-config.md
Normal file
5
.changes/file-associations-config.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"tauri-utils": minor:feat
|
||||||
|
---
|
||||||
|
|
||||||
|
Add a configuration object for file associations under `BundleConfig`.
|
5
.changes/file-associations.md
Normal file
5
.changes/file-associations.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"tauri": minor:feat
|
||||||
|
---
|
||||||
|
|
||||||
|
Added support to file associations.
|
6
.changes/runtime-opened-event.md
Normal file
6
.changes/runtime-opened-event.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"tauri-runtime": minor:feat
|
||||||
|
"tauri-runtime-wry": minor:feat
|
||||||
|
---
|
||||||
|
|
||||||
|
Added the `Opened` variant to `RunEvent`.
|
@ -121,7 +121,7 @@ jobs:
|
|||||||
steps.covector.outputs.successfulPublish == 'true' &&
|
steps.covector.outputs.successfulPublish == 'true' &&
|
||||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||||
run: |
|
run: |
|
||||||
echo '${{ steps.covector.outputs }}' > output.json
|
echo '${{ toJSON(steps.covector.outputs) }}' > output.json
|
||||||
id=$(jq '.["-tauri-apps-cli-releaseId"]' < output.json)
|
id=$(jq '.["-tauri-apps-cli-releaseId"]' < output.json)
|
||||||
rm output.json
|
rm output.json
|
||||||
echo "cliReleaseId=$id" >> "$GITHUB_OUTPUT"
|
echo "cliReleaseId=$id" >> "$GITHUB_OUTPUT"
|
||||||
|
@ -20,6 +20,7 @@ exclude = [
|
|||||||
"examples/resources/src-tauri",
|
"examples/resources/src-tauri",
|
||||||
"examples/sidecar/src-tauri",
|
"examples/sidecar/src-tauri",
|
||||||
"examples/web/core",
|
"examples/web/core",
|
||||||
|
"examples/file-associations/src-tauri",
|
||||||
"examples/workspace",
|
"examples/workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -925,6 +925,16 @@
|
|||||||
"null"
|
"null"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"fileAssociations": {
|
||||||
|
"description": "File associations to application.",
|
||||||
|
"type": [
|
||||||
|
"array",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/FileAssociation"
|
||||||
|
}
|
||||||
|
},
|
||||||
"shortDescription": {
|
"shortDescription": {
|
||||||
"description": "A short description of your application.",
|
"description": "A short description of your application.",
|
||||||
"type": [
|
"type": [
|
||||||
@ -1122,6 +1132,97 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"FileAssociation": {
|
||||||
|
"description": "File association",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ext"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"ext": {
|
||||||
|
"description": "File extensions to associate with this app. e.g. 'png'",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/AssociationExt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "The name. Maps to `CFBundleTypeName` on macOS. Default to ext[0]",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"description": "The association description. Windows-only. It is displayed on the `Type` column on Windows Explorer.",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"description": "The app’s role with respect to the type. Maps to `CFBundleTypeRole` on macOS.",
|
||||||
|
"default": "Editor",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/BundleTypeRole"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mimeType": {
|
||||||
|
"description": "The mime-type e.g. 'image/png' or 'text/plain'. Linux-only.",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"AssociationExt": {
|
||||||
|
"description": "An extension for a [`FileAssociation`].\n\nA leading `.` is automatically stripped.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"BundleTypeRole": {
|
||||||
|
"description": "macOS-only. Corresponds to CFBundleTypeRole",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Editor. Files can be read and edited.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Editor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Viewer. Files can be read.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Viewer"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Shell",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Shell"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.QLGenerator",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"QLGenerator"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.None",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"None"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"AppImageConfig": {
|
"AppImageConfig": {
|
||||||
"description": "Configuration for AppImage bundles.\n\nSee more: https://tauri.app/v1/api/config#appimageconfig",
|
"description": "Configuration for AppImage bundles.\n\nSee more: https://tauri.app/v1/api/config#appimageconfig",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -13,7 +13,7 @@ edition = { workspace = true }
|
|||||||
rust-version = { workspace = true }
|
rust-version = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wry = { version = "0.28.3", default-features = false, features = [ "file-drop", "protocol" ] }
|
wry = { version = "0.30", default-features = false, features = [ "file-drop", "protocol" ] }
|
||||||
tauri-runtime = { version = "0.13.0-alpha.6", path = "../tauri-runtime" }
|
tauri-runtime = { version = "0.13.0-alpha.6", path = "../tauri-runtime" }
|
||||||
tauri-utils = { version = "2.0.0-alpha.6", path = "../tauri-utils" }
|
tauri-utils = { version = "2.0.0-alpha.6", path = "../tauri-utils" }
|
||||||
uuid = { version = "1", features = [ "v4" ] }
|
uuid = { version = "1", features = [ "v4" ] }
|
||||||
@ -21,15 +21,15 @@ rand = "0.8"
|
|||||||
raw-window-handle = "0.5"
|
raw-window-handle = "0.5"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
webview2-com = "0.22"
|
webview2-com = "0.25"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies.windows]
|
[target."cfg(windows)".dependencies.windows]
|
||||||
version = "0.44"
|
version = "0.48"
|
||||||
features = [ "Win32_Foundation" ]
|
features = [ "Win32_Foundation" ]
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||||
gtk = { version = "0.16", features = [ "v3_24" ] }
|
gtk = { version = "0.16", features = [ "v3_24" ] }
|
||||||
webkit2gtk = { version = "0.19.1", features = [ "v2_38" ] }
|
webkit2gtk = { version = "1.1", features = [ "v2_38" ] }
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
|
[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
|
||||||
@ -48,4 +48,4 @@ macos-private-api = [
|
|||||||
"tauri-runtime/macos-private-api"
|
"tauri-runtime/macos-private-api"
|
||||||
]
|
]
|
||||||
objc-exception = [ "wry/objc-exception" ]
|
objc-exception = [ "wry/objc-exception" ]
|
||||||
linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]
|
linux-headers = [ ]
|
||||||
|
@ -2952,6 +2952,10 @@ fn handle_event_loop<T: UserEvent>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
Event::Opened { urls } => {
|
||||||
|
callback(RunEvent::Opened { urls });
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ rand = "0.8"
|
|||||||
url = { version = "2" }
|
url = { version = "2" }
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies.windows]
|
[target."cfg(windows)".dependencies.windows]
|
||||||
version = "0.44"
|
version = "0.48"
|
||||||
features = [ "Win32_Foundation" ]
|
features = [ "Win32_Foundation" ]
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||||
@ -44,6 +44,9 @@ gtk = { version = "0.16", features = [ "v3_24" ] }
|
|||||||
[target."cfg(target_os = \"android\")".dependencies]
|
[target."cfg(target_os = \"android\")".dependencies]
|
||||||
jni = "0.20"
|
jni = "0.20"
|
||||||
|
|
||||||
|
[target."cfg(target_os = \"macos\")".dependencies]
|
||||||
|
url = "2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
devtools = [ ]
|
devtools = [ ]
|
||||||
system-tray = [ ]
|
system-tray = [ ]
|
||||||
|
@ -290,6 +290,7 @@ pub trait UserEvent: Debug + Clone + Send + 'static {}
|
|||||||
impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
|
impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
|
||||||
|
|
||||||
/// Event triggered on the event loop run.
|
/// Event triggered on the event loop run.
|
||||||
|
#[derive(Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum RunEvent<T: UserEvent> {
|
pub enum RunEvent<T: UserEvent> {
|
||||||
/// Event loop is exiting.
|
/// Event loop is exiting.
|
||||||
@ -313,6 +314,9 @@ pub enum RunEvent<T: UserEvent> {
|
|||||||
///
|
///
|
||||||
/// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the “main body” of your event loop.
|
/// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the “main body” of your event loop.
|
||||||
MainEventsCleared,
|
MainEventsCleared,
|
||||||
|
/// Emitted when the user wants to open the specified resource with the app.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
Opened { urls: Vec<url::Url> },
|
||||||
/// A custom event defined by the user.
|
/// A custom event defined by the user.
|
||||||
UserEvent(T),
|
UserEvent(T),
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ dunce = "1"
|
|||||||
heck = "0.4"
|
heck = "0.4"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies.windows]
|
[target."cfg(windows)".dependencies.windows]
|
||||||
version = "0.44.0"
|
version = "0.48.0"
|
||||||
features = [
|
features = [
|
||||||
"implement",
|
"implement",
|
||||||
"Win32_Foundation",
|
"Win32_Foundation",
|
||||||
|
@ -624,6 +624,78 @@ impl Default for WindowsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// macOS-only. Corresponds to CFBundleTypeRole
|
||||||
|
#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
|
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||||
|
pub enum BundleTypeRole {
|
||||||
|
/// CFBundleTypeRole.Editor. Files can be read and edited.
|
||||||
|
#[default]
|
||||||
|
Editor,
|
||||||
|
/// CFBundleTypeRole.Viewer. Files can be read.
|
||||||
|
Viewer,
|
||||||
|
/// CFBundleTypeRole.Shell
|
||||||
|
Shell,
|
||||||
|
/// CFBundleTypeRole.QLGenerator
|
||||||
|
QLGenerator,
|
||||||
|
/// CFBundleTypeRole.None
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for BundleTypeRole {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Editor => write!(f, "Editor"),
|
||||||
|
Self::Viewer => write!(f, "Viewer"),
|
||||||
|
Self::Shell => write!(f, "Shell"),
|
||||||
|
Self::QLGenerator => write!(f, "QLGenerator"),
|
||||||
|
Self::None => write!(f, "None"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An extension for a [`FileAssociation`].
|
||||||
|
///
|
||||||
|
/// A leading `.` is automatically stripped.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
|
||||||
|
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||||
|
pub struct AssociationExt(pub String);
|
||||||
|
|
||||||
|
impl fmt::Display for AssociationExt {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> serde::Deserialize<'d> for AssociationExt {
|
||||||
|
fn deserialize<D: Deserializer<'d>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
|
let ext = String::deserialize(deserializer)?;
|
||||||
|
if let Some(ext) = ext.strip_prefix('.') {
|
||||||
|
Ok(AssociationExt(ext.into()))
|
||||||
|
} else {
|
||||||
|
Ok(AssociationExt(ext))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// File association
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
|
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||||
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
|
pub struct FileAssociation {
|
||||||
|
/// File extensions to associate with this app. e.g. 'png'
|
||||||
|
pub ext: Vec<AssociationExt>,
|
||||||
|
/// The name. Maps to `CFBundleTypeName` on macOS. Default to ext[0]
|
||||||
|
pub name: Option<String>,
|
||||||
|
/// The association description. Windows-only. It is displayed on the `Type` column on Windows Explorer.
|
||||||
|
pub description: Option<String>,
|
||||||
|
/// The app’s role with respect to the type. Maps to `CFBundleTypeRole` on macOS.
|
||||||
|
#[serde(default)]
|
||||||
|
pub role: BundleTypeRole,
|
||||||
|
/// The mime-type e.g. 'image/png' or 'text/plain'. Linux-only.
|
||||||
|
#[serde(alias = "mime-type")]
|
||||||
|
pub mime_type: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The Updater configuration object.
|
/// The Updater configuration object.
|
||||||
///
|
///
|
||||||
/// See more: https://tauri.app/v1/api/config#updaterconfig
|
/// See more: https://tauri.app/v1/api/config#updaterconfig
|
||||||
@ -720,6 +792,8 @@ pub struct BundleConfig {
|
|||||||
/// Should be one of the following:
|
/// Should be one of the following:
|
||||||
/// Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather.
|
/// Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather.
|
||||||
pub category: Option<String>,
|
pub category: Option<String>,
|
||||||
|
/// File associations to application.
|
||||||
|
pub file_associations: Option<Vec<FileAssociation>>,
|
||||||
/// A short description of your application.
|
/// A short description of your application.
|
||||||
#[serde(alias = "short-description")]
|
#[serde(alias = "short-description")]
|
||||||
pub short_description: Option<String>,
|
pub short_description: Option<String>,
|
||||||
@ -1668,7 +1742,7 @@ fn default_dist_dir() -> AppUrl {
|
|||||||
struct PackageVersion(String);
|
struct PackageVersion(String);
|
||||||
|
|
||||||
impl<'d> serde::Deserialize<'d> for PackageVersion {
|
impl<'d> serde::Deserialize<'d> for PackageVersion {
|
||||||
fn deserialize<D: Deserializer<'d>>(deserializer: D) -> Result<PackageVersion, D::Error> {
|
fn deserialize<D: Deserializer<'d>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
struct PackageVersionVisitor;
|
struct PackageVersionVisitor;
|
||||||
|
|
||||||
impl<'d> Visitor<'d> for PackageVersionVisitor {
|
impl<'d> Visitor<'d> for PackageVersionVisitor {
|
||||||
@ -2291,6 +2365,7 @@ mod build {
|
|||||||
let resources = quote!(None);
|
let resources = quote!(None);
|
||||||
let copyright = quote!(None);
|
let copyright = quote!(None);
|
||||||
let category = quote!(None);
|
let category = quote!(None);
|
||||||
|
let file_associations = quote!(None);
|
||||||
let short_description = quote!(None);
|
let short_description = quote!(None);
|
||||||
let long_description = quote!(None);
|
let long_description = quote!(None);
|
||||||
let appimage = quote!(Default::default());
|
let appimage = quote!(Default::default());
|
||||||
@ -2313,6 +2388,7 @@ mod build {
|
|||||||
resources,
|
resources,
|
||||||
copyright,
|
copyright,
|
||||||
category,
|
category,
|
||||||
|
file_associations,
|
||||||
short_description,
|
short_description,
|
||||||
long_description,
|
long_description,
|
||||||
appimage,
|
appimage,
|
||||||
@ -2616,6 +2692,7 @@ mod test {
|
|||||||
resources: None,
|
resources: None,
|
||||||
copyright: None,
|
copyright: None,
|
||||||
category: None,
|
category: None,
|
||||||
|
file_associations: None,
|
||||||
short_description: None,
|
short_description: None,
|
||||||
long_description: None,
|
long_description: None,
|
||||||
appimage: Default::default(),
|
appimage: Default::default(),
|
||||||
|
@ -70,7 +70,7 @@ ico = { version = "0.2.0", optional = true }
|
|||||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||||
gtk = { version = "0.16", features = [ "v3_24" ] }
|
gtk = { version = "0.16", features = [ "v3_24" ] }
|
||||||
glib = "0.16"
|
glib = "0.16"
|
||||||
webkit2gtk = { version = "0.19.1", features = [ "v2_38" ] }
|
webkit2gtk = { version = "1.1", features = [ "v2_38" ] }
|
||||||
|
|
||||||
[target."cfg(target_os = \"macos\")".dependencies]
|
[target."cfg(target_os = \"macos\")".dependencies]
|
||||||
embed_plist = "1.2"
|
embed_plist = "1.2"
|
||||||
@ -78,10 +78,10 @@ cocoa = "0.24"
|
|||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
webview2-com = "0.22"
|
webview2-com = "0.25"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies.windows]
|
[target."cfg(windows)".dependencies.windows]
|
||||||
version = "0.44"
|
version = "0.48"
|
||||||
features = [ "Win32_Foundation" ]
|
features = [ "Win32_Foundation" ]
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
|
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
|
||||||
|
@ -177,6 +177,12 @@ pub enum RunEvent {
|
|||||||
///
|
///
|
||||||
/// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the “main body” of your event loop.
|
/// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the “main body” of your event loop.
|
||||||
MainEventsCleared,
|
MainEventsCleared,
|
||||||
|
/// Emitted when the user wants to open the specified resource with the app.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
Opened {
|
||||||
|
/// The URL of the resources that is being open.
|
||||||
|
urls: Vec<url::Url>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<EventLoopMessage> for RunEvent {
|
impl From<EventLoopMessage> for RunEvent {
|
||||||
@ -1008,6 +1014,7 @@ impl<R: Runtime> Builder<R> {
|
|||||||
/// [`State`](crate::State) guard. In particular, if a value of type `T`
|
/// [`State`](crate::State) guard. In particular, if a value of type `T`
|
||||||
/// is managed by Tauri, adding `State<T>` to the list of arguments in a
|
/// is managed by Tauri, adding `State<T>` to the list of arguments in a
|
||||||
/// command handler instructs Tauri to retrieve the managed value.
|
/// command handler instructs Tauri to retrieve the managed value.
|
||||||
|
/// Additionally, [`state`](crate::Manager#method.state) can be used to retrieve the value manually.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -1516,6 +1523,8 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
|
|||||||
RuntimeRunEvent::Resumed => RunEvent::Resumed,
|
RuntimeRunEvent::Resumed => RunEvent::Resumed,
|
||||||
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
|
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
|
||||||
RuntimeRunEvent::UserEvent(t) => t.into(),
|
RuntimeRunEvent::UserEvent(t) => t.into(),
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
RuntimeRunEvent::Opened { urls } => RunEvent::Opened { urls },
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -680,18 +680,13 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
|
|||||||
|
|
||||||
/// Add `state` to the state managed by the application.
|
/// Add `state` to the state managed by the application.
|
||||||
///
|
///
|
||||||
/// This method can be called any number of times as long as each call
|
/// If the state for the `T` type has previously been set, the state is unchanged and false is returned. Otherwise true is returned.
|
||||||
/// refers to a different `T`.
|
|
||||||
/// If a state for `T` is already managed, the function returns false and the value is ignored.
|
|
||||||
///
|
///
|
||||||
/// Managed state can be retrieved by any command handler via the
|
/// Managed state can be retrieved by any command handler via the
|
||||||
/// [`State`](crate::State) guard. In particular, if a value of type `T`
|
/// [`State`](crate::State) guard. In particular, if a value of type `T`
|
||||||
/// is managed by Tauri, adding `State<T>` to the list of arguments in a
|
/// is managed by Tauri, adding `State<T>` to the list of arguments in a
|
||||||
/// command handler instructs Tauri to retrieve the managed value.
|
/// command handler instructs Tauri to retrieve the managed value.
|
||||||
///
|
/// Additionally, [`state`](Self#method.state) can be used to retrieve the value manually.
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if state of type `T` is already being managed.
|
|
||||||
///
|
///
|
||||||
/// # Mutability
|
/// # Mutability
|
||||||
///
|
///
|
||||||
|
@ -1054,8 +1054,8 @@ impl<R: Runtime> Window<R> {
|
|||||||
/// });
|
/// });
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(all(feature = "wry"))]
|
#[cfg(feature = "wry")]
|
||||||
#[cfg_attr(doc_cfg, doc(all(feature = "wry")))]
|
#[cfg_attr(doc_cfg, doc(feature = "wry"))]
|
||||||
pub fn with_webview<F: FnOnce(PlatformWebview) + Send + 'static>(
|
pub fn with_webview<F: FnOnce(PlatformWebview) + Send + 'static>(
|
||||||
&self,
|
&self,
|
||||||
f: F,
|
f: F,
|
||||||
|
657
examples/api/src-tauri/Cargo.lock
generated
657
examples/api/src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
11
examples/file-associations/README.md
Normal file
11
examples/file-associations/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# File Associations Example
|
||||||
|
|
||||||
|
This example demonstrates how to make associations between the application and certain file types.
|
||||||
|
|
||||||
|
This feature is commonly used for functionality such as previewing or editing files.
|
||||||
|
|
||||||
|
## Running the example
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo build --example file-associations
|
||||||
|
```
|
26
examples/file-associations/index.html
Normal file
26
examples/file-associations/index.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>File Associations</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>File Associations</h1>
|
||||||
|
<div id="files"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const d = document.getElementById('files')
|
||||||
|
d.textContent = window.openedUrls
|
||||||
|
|
||||||
|
window.onFileOpen = (files) => {
|
||||||
|
console.log(files)
|
||||||
|
d.textContent = files
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
15
examples/file-associations/package.json
Normal file
15
examples/file-associations/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "file-associations",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"pkg": {
|
||||||
|
"assets": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"tauri": "node ../../tooling/cli/node/tauri.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
4
examples/file-associations/src-tauri/.gitignore
vendored
Normal file
4
examples/file-associations/src-tauri/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
WixTools
|
3
examples/file-associations/src-tauri/.license_template
Normal file
3
examples/file-associations/src-tauri/.license_template
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Copyright {20\d{2}(-20\d{2})?} Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
4069
examples/file-associations/src-tauri/Cargo.lock
generated
Normal file
4069
examples/file-associations/src-tauri/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
examples/file-associations/src-tauri/Cargo.toml
Normal file
19
examples/file-associations/src-tauri/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "tauri-file-associations-demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A Tauri application that associate file types"
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.57"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { path = "../../../core/tauri-build", features = ["codegen"] }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde = { version = "1.0", features = [ "derive" ] }
|
||||||
|
tauri = { path = "../../../core/tauri", features = [] }
|
||||||
|
url = "2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "custom-protocol" ]
|
||||||
|
custom-protocol = [ "tauri/custom-protocol" ]
|
21
examples/file-associations/src-tauri/Info.plist
Normal file
21
examples/file-associations/src-tauri/Info.plist
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!-- Add this file next to your tauri.conf.json file -->
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<!-- Obviously needs to be replaced with your app's bundle identifier -->
|
||||||
|
<string>com.tauri.dev-file-associations-demo</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<!-- register the myapp:// and myscheme:// schemes -->
|
||||||
|
<string>myapp</string>
|
||||||
|
<string>myscheme</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
7
examples/file-associations/src-tauri/build.rs
Normal file
7
examples/file-associations/src-tauri/build.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
69
examples/file-associations/src-tauri/src/main.rs
Normal file
69
examples/file-associations/src-tauri/src/main.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#![cfg_attr(
|
||||||
|
all(not(debug_assertions), target_os = "windows"),
|
||||||
|
windows_subsystem = "windows"
|
||||||
|
)]
|
||||||
|
|
||||||
|
use std::{env, sync::Mutex};
|
||||||
|
use tauri::Manager;
|
||||||
|
|
||||||
|
struct OpenedUrls(Mutex<Option<Vec<url::Url>>>);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
tauri::Builder::default()
|
||||||
|
.manage(OpenedUrls(Default::default()))
|
||||||
|
.setup(|app| {
|
||||||
|
#[cfg(any(windows, target_os = "linux"))]
|
||||||
|
{
|
||||||
|
// NOTICE: `args` may include URL protocol (`your-app-protocol://`) or arguments (`--`) if app supports them.
|
||||||
|
let mut urls = Vec::new();
|
||||||
|
for arg in env::args().skip(1) {
|
||||||
|
if let Ok(url) = url::Url::parse(&arg) {
|
||||||
|
urls.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !urls.is_empty() {
|
||||||
|
app.state::<OpenedUrls>().0.lock().unwrap().replace(urls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let opened_urls = if let Some(urls) = &*app.state::<OpenedUrls>().0.lock().unwrap() {
|
||||||
|
urls
|
||||||
|
.iter()
|
||||||
|
.map(|u| u.as_str().replace("\\", "\\\\"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
} else {
|
||||||
|
"".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
tauri::WindowBuilder::new(app, "main", Default::default())
|
||||||
|
.initialization_script(&format!("window.openedUrls = `{opened_urls}`"))
|
||||||
|
.initialization_script(&format!("console.log(`{opened_urls}`)"))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application")
|
||||||
|
.run(|app, event| {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
if let tauri::RunEvent::Opened { urls } = event {
|
||||||
|
if let Some(w) = app.get_window("main") {
|
||||||
|
let urls = urls
|
||||||
|
.iter()
|
||||||
|
.map(|u| u.as_str())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",");
|
||||||
|
let _ = w.eval(&format!("window.onFileOpen(`{urls}`)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
app.state::<OpenedUrls>().0.lock().unwrap().replace(urls);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
58
examples/file-associations/src-tauri/tauri.conf.json
Normal file
58
examples/file-associations/src-tauri/tauri.conf.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../tooling/cli/schema.json",
|
||||||
|
"build": {
|
||||||
|
"distDir": [
|
||||||
|
"../index.html"
|
||||||
|
],
|
||||||
|
"devPath": [
|
||||||
|
"../index.html"
|
||||||
|
],
|
||||||
|
"beforeDevCommand": "",
|
||||||
|
"beforeBuildCommand": ""
|
||||||
|
},
|
||||||
|
"tauri": {
|
||||||
|
"bundle": {
|
||||||
|
"active": true,
|
||||||
|
"targets": "all",
|
||||||
|
"identifier": "com.tauri.dev-file-associations-demo",
|
||||||
|
"icon": [
|
||||||
|
"../../.icons/32x32.png",
|
||||||
|
"../../.icons/128x128.png",
|
||||||
|
"../../.icons/128x128@2x.png",
|
||||||
|
"../../.icons/icon.icns",
|
||||||
|
"../../.icons/icon.ico"
|
||||||
|
],
|
||||||
|
"resources": [],
|
||||||
|
"externalBin": [],
|
||||||
|
"copyright": "",
|
||||||
|
"category": "DeveloperTool",
|
||||||
|
"fileAssociations": [
|
||||||
|
{
|
||||||
|
"ext": ["png"],
|
||||||
|
"mimeType": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ext": ["jpg", "jpeg"],
|
||||||
|
"mimeType": "image/jpeg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ext": ["gif"],
|
||||||
|
"mimeType": "image/gif"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shortDescription": "",
|
||||||
|
"longDescription": "",
|
||||||
|
"deb": {
|
||||||
|
"depends": []
|
||||||
|
},
|
||||||
|
"macOS": {
|
||||||
|
"frameworks": [],
|
||||||
|
"exceptionDomain": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"windows": [],
|
||||||
|
"security": {
|
||||||
|
"csp": "default-src 'self'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
examples/file-associations/yarn.lock
Normal file
4
examples/file-associations/yarn.lock
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ tauri-build = { path = "../../../../core/tauri-build", features = [] }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
api = { path = "../api" }
|
api = { path = "../api" }
|
||||||
tauri = { path = "../../../../core/tauri", features = ["dialog"] }
|
tauri = { path = "../../../../core/tauri" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
custom-protocol = [ "tauri/custom-protocol" ]
|
custom-protocol = [ "tauri/custom-protocol" ]
|
||||||
|
@ -167,8 +167,20 @@ fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<
|
|||||||
exec: &'a str,
|
exec: &'a str,
|
||||||
icon: &'a str,
|
icon: &'a str,
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
|
mime_type: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mime_type = if let Some(associations) = settings.file_associations() {
|
||||||
|
let mime_types: Vec<&str> = associations
|
||||||
|
.iter()
|
||||||
|
.filter_map(|association| association.mime_type.as_ref())
|
||||||
|
.map(|s| s.as_str())
|
||||||
|
.collect();
|
||||||
|
Some(mime_types.join(";"))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
handlebars.render_to_write(
|
handlebars.render_to_write(
|
||||||
"main.desktop",
|
"main.desktop",
|
||||||
&DesktopTemplateParams {
|
&DesktopTemplateParams {
|
||||||
@ -184,6 +196,7 @@ fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<
|
|||||||
exec: bin_name,
|
exec: bin_name,
|
||||||
icon: bin_name,
|
icon: bin_name,
|
||||||
name: settings.product_name(),
|
name: settings.product_name(),
|
||||||
|
mime_type,
|
||||||
},
|
},
|
||||||
file,
|
file,
|
||||||
)?;
|
)?;
|
||||||
|
@ -8,3 +8,6 @@ Icon={{icon}}
|
|||||||
Name={{name}}
|
Name={{name}}
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
|
{{#if mime_type}}
|
||||||
|
MimeType={{mime_type}}
|
||||||
|
{{/if}}
|
||||||
|
@ -31,6 +31,7 @@ use crate::Settings;
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use tauri_utils::config::BundleTypeRole;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
@ -163,6 +164,45 @@ fn create_info_plist(
|
|||||||
if let Some(version) = settings.macos().minimum_system_version.clone() {
|
if let Some(version) = settings.macos().minimum_system_version.clone() {
|
||||||
plist.insert("LSMinimumSystemVersion".into(), version.into());
|
plist.insert("LSMinimumSystemVersion".into(), version.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(associations) = settings.file_associations() {
|
||||||
|
plist.insert(
|
||||||
|
"CFBundleDocumentTypes".into(),
|
||||||
|
plist::Value::Array(
|
||||||
|
associations
|
||||||
|
.iter()
|
||||||
|
.map(|association| {
|
||||||
|
let mut dict = plist::Dictionary::new();
|
||||||
|
dict.insert(
|
||||||
|
"CFBundleTypeExtensions".into(),
|
||||||
|
plist::Value::Array(
|
||||||
|
association
|
||||||
|
.ext
|
||||||
|
.iter()
|
||||||
|
.map(|ext| ext.to_string().into())
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"CFBundleTypeName".into(),
|
||||||
|
association
|
||||||
|
.name
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&association.ext[0].0)
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"CFBundleTypeRole".into(),
|
||||||
|
association.role.to_string().into(),
|
||||||
|
);
|
||||||
|
plist::Value::Dictionary(dict)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
plist.insert("LSRequiresCarbon".into(), true.into());
|
plist.insert("LSRequiresCarbon".into(), true.into());
|
||||||
plist.insert("NSHighResolutionCapable".into(), true.into());
|
plist.insert("NSHighResolutionCapable".into(), true.into());
|
||||||
if let Some(copyright) = settings.copyright_string() {
|
if let Some(copyright) = settings.copyright_string() {
|
||||||
|
@ -7,7 +7,7 @@ use super::category::AppCategory;
|
|||||||
use crate::bundle::{common, platform::target_triple};
|
use crate::bundle::{common, platform::target_triple};
|
||||||
pub use tauri_utils::config::WebviewInstallMode;
|
pub use tauri_utils::config::WebviewInstallMode;
|
||||||
use tauri_utils::{
|
use tauri_utils::{
|
||||||
config::{BundleType, NSISInstallerMode},
|
config::{BundleType, FileAssociation, NSISInstallerMode},
|
||||||
resources::{external_binaries, ResourcePaths},
|
resources::{external_binaries, ResourcePaths},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -362,6 +362,8 @@ pub struct BundleSettings {
|
|||||||
pub copyright: Option<String>,
|
pub copyright: Option<String>,
|
||||||
/// the app's category.
|
/// the app's category.
|
||||||
pub category: Option<AppCategory>,
|
pub category: Option<AppCategory>,
|
||||||
|
/// the file associations
|
||||||
|
pub file_associations: Option<Vec<FileAssociation>>,
|
||||||
/// the app's short description.
|
/// the app's short description.
|
||||||
pub short_description: Option<String>,
|
pub short_description: Option<String>,
|
||||||
/// the app's long description.
|
/// the app's long description.
|
||||||
@ -786,6 +788,11 @@ impl Settings {
|
|||||||
self.bundle_settings.category
|
self.bundle_settings.category
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return file associations.
|
||||||
|
pub fn file_associations(&self) -> &Option<Vec<FileAssociation>> {
|
||||||
|
&self.bundle_settings.file_associations
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the app's short description.
|
/// Returns the app's short description.
|
||||||
pub fn short_description(&self) -> &str {
|
pub fn short_description(&self) -> &str {
|
||||||
self
|
self
|
||||||
|
@ -646,6 +646,10 @@ pub fn build_wix_app_installer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(file_associations) = &settings.file_associations() {
|
||||||
|
data.insert("file_associations", to_json(file_associations));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(path) = custom_template_path {
|
if let Some(path) = custom_template_path {
|
||||||
handlebars
|
handlebars
|
||||||
.register_template_string("main.wxs", read_to_string(path)?)
|
.register_template_string("main.wxs", read_to_string(path)?)
|
||||||
|
@ -301,6 +301,10 @@ fn build_nsis_app_installer(
|
|||||||
let binaries = generate_binaries_data(settings)?;
|
let binaries = generate_binaries_data(settings)?;
|
||||||
data.insert("binaries", to_json(binaries));
|
data.insert("binaries", to_json(binaries));
|
||||||
|
|
||||||
|
if let Some(file_associations) = &settings.file_associations() {
|
||||||
|
data.insert("file_associations", to_json(file_associations));
|
||||||
|
}
|
||||||
|
|
||||||
let silent_webview2_install = if let WebviewInstallMode::DownloadBootstrapper { silent }
|
let silent_webview2_install = if let WebviewInstallMode::DownloadBootstrapper { silent }
|
||||||
| WebviewInstallMode::EmbedBootstrapper { silent }
|
| WebviewInstallMode::EmbedBootstrapper { silent }
|
||||||
| WebviewInstallMode::OfflineInstaller { silent } =
|
| WebviewInstallMode::OfflineInstaller { silent } =
|
||||||
@ -388,6 +392,8 @@ fn build_nsis_app_installer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut handlebars = Handlebars::new();
|
let mut handlebars = Handlebars::new();
|
||||||
|
handlebars.register_helper("or", Box::new(handlebars_or));
|
||||||
|
handlebars.register_helper("association-description", Box::new(association_description));
|
||||||
handlebars.register_escape_fn(|s| {
|
handlebars.register_escape_fn(|s| {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
@ -414,6 +420,12 @@ fn build_nsis_app_installer(
|
|||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.expect("Failed to setup handlebar template");
|
.expect("Failed to setup handlebar template");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_ut16_le_with_bom(
|
||||||
|
&output_path.join("FileAssociation.nsh"),
|
||||||
|
include_str!("./templates/FileAssociation.nsh"),
|
||||||
|
)?;
|
||||||
|
|
||||||
let installer_nsi_path = output_path.join("installer.nsi");
|
let installer_nsi_path = output_path.join("installer.nsi");
|
||||||
write_ut16_le_with_bom(
|
write_ut16_le_with_bom(
|
||||||
&installer_nsi_path,
|
&installer_nsi_path,
|
||||||
@ -473,6 +485,42 @@ fn build_nsis_app_installer(
|
|||||||
Ok(vec![nsis_installer_path])
|
Ok(vec![nsis_installer_path])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handlebars_or(
|
||||||
|
h: &handlebars::Helper<'_, '_>,
|
||||||
|
_: &Handlebars<'_>,
|
||||||
|
_: &handlebars::Context,
|
||||||
|
_: &mut handlebars::RenderContext<'_, '_>,
|
||||||
|
out: &mut dyn handlebars::Output,
|
||||||
|
) -> handlebars::HelperResult {
|
||||||
|
let param1 = h.param(0).unwrap().render();
|
||||||
|
let param2 = h.param(1).unwrap();
|
||||||
|
|
||||||
|
out.write(&if param1.is_empty() {
|
||||||
|
param2.render()
|
||||||
|
} else {
|
||||||
|
param1
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn association_description(
|
||||||
|
h: &handlebars::Helper<'_, '_>,
|
||||||
|
_: &Handlebars<'_>,
|
||||||
|
_: &handlebars::Context,
|
||||||
|
_: &mut handlebars::RenderContext<'_, '_>,
|
||||||
|
out: &mut dyn handlebars::Output,
|
||||||
|
) -> handlebars::HelperResult {
|
||||||
|
let description = h.param(0).unwrap().render();
|
||||||
|
let ext = h.param(1).unwrap();
|
||||||
|
|
||||||
|
out.write(&if description.is_empty() {
|
||||||
|
format!("{} File", ext.render().to_uppercase())
|
||||||
|
} else {
|
||||||
|
description
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// BTreeMap<OriginalPath, (ParentOfTargetPath, TargetPath)>
|
/// BTreeMap<OriginalPath, (ParentOfTargetPath, TargetPath)>
|
||||||
type ResourcesMap = BTreeMap<PathBuf, (String, PathBuf)>;
|
type ResourcesMap = BTreeMap<PathBuf, (String, PathBuf)>;
|
||||||
fn generate_resource_data(settings: &Settings) -> crate::Result<ResourcesMap> {
|
fn generate_resource_data(settings: &Settings) -> crate::Result<ResourcesMap> {
|
||||||
|
135
tooling/bundler/src/bundle/windows/templates/FileAssociation.nsh
Normal file
135
tooling/bundler/src/bundle/windows/templates/FileAssociation.nsh
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
; from https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b
|
||||||
|
; fileassoc.nsh
|
||||||
|
; File association helper macros
|
||||||
|
; Written by Saivert
|
||||||
|
;
|
||||||
|
; Improved by Nikku<https://github.com/nikku>.
|
||||||
|
;
|
||||||
|
; Features automatic backup system and UPDATEFILEASSOC macro for
|
||||||
|
; shell change notification.
|
||||||
|
;
|
||||||
|
; |> How to use <|
|
||||||
|
; To associate a file with an application so you can double-click it in explorer, use
|
||||||
|
; the APP_ASSOCIATE macro like this:
|
||||||
|
;
|
||||||
|
; Example:
|
||||||
|
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
|
||||||
|
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
|
||||||
|
;
|
||||||
|
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
|
||||||
|
; to associate an application with a single file and using the
|
||||||
|
; the "open" verb as default. To add more verbs (actions) to a file
|
||||||
|
; use the APP_ASSOCIATE_ADDVERB macro.
|
||||||
|
;
|
||||||
|
; Example:
|
||||||
|
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
|
||||||
|
; "$INSTDIR\myapp.exe /edit $\"%1$\""
|
||||||
|
;
|
||||||
|
; To have access to more options when registering the file association use the
|
||||||
|
; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
|
||||||
|
; standard action (default verb).
|
||||||
|
;
|
||||||
|
; Note, that this script takes into account user versus global installs.
|
||||||
|
; To properly work you must initialize the SHELL_CONTEXT variable via SetShellVarContext.
|
||||||
|
;
|
||||||
|
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
|
||||||
|
; macro. Here is another example just to wrap it up:
|
||||||
|
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
|
||||||
|
;
|
||||||
|
; |> Note <|
|
||||||
|
; When defining your file class string always use the short form of your application title
|
||||||
|
; then a period (dot) and the type of file. This keeps the file class sort of unique.
|
||||||
|
; Examples:
|
||||||
|
; Winamp.Playlist
|
||||||
|
; NSIS.Script
|
||||||
|
; Photoshop.JPEGFile
|
||||||
|
;
|
||||||
|
; |> Tech info <|
|
||||||
|
; The registry key layout for a global file association is:
|
||||||
|
;
|
||||||
|
; HKEY_LOCAL_MACHINE\Software\Classes
|
||||||
|
; <".ext"> = <applicationID>
|
||||||
|
; <applicationID> = <"description">
|
||||||
|
; shell
|
||||||
|
; <verb> = <"menu-item text">
|
||||||
|
; command = <"command string">
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; The registry key layout for a per-user file association is:
|
||||||
|
;
|
||||||
|
; HKEY_CURRENT_USER\Software\Classes
|
||||||
|
; <".ext"> = <applicationID>
|
||||||
|
; <applicationID> = <"description">
|
||||||
|
; shell
|
||||||
|
; <verb> = <"menu-item text">
|
||||||
|
; command = <"command string">
|
||||||
|
;
|
||||||
|
|
||||||
|
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
|
||||||
|
; Backup the previously associated file class
|
||||||
|
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
|
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
|
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open"
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
|
||||||
|
; Backup the previously associated file class
|
||||||
|
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
|
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
|
||||||
|
StrCmp "${SHELLNEW}" "0" +2
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}\ShellNew" "NullFile" ""
|
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" `${DEFAULTVERB}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
|
||||||
|
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}\shell\${VERB}`
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
|
||||||
|
!macro APP_UNASSOCIATE EXT FILECLASS
|
||||||
|
; Backup the previously associated file class
|
||||||
|
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup`
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0"
|
||||||
|
|
||||||
|
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}`
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
|
||||||
|
ReadRegStr ${OUTPUT} SHELL_CONTEXT "Software\Classes\.${EXT}" ""
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
|
||||||
|
; !defines for use with SHChangeNotify
|
||||||
|
!ifdef SHCNE_ASSOCCHANGED
|
||||||
|
!undef SHCNE_ASSOCCHANGED
|
||||||
|
!endif
|
||||||
|
!define SHCNE_ASSOCCHANGED 0x08000000
|
||||||
|
!ifdef SHCNF_FLUSH
|
||||||
|
!undef SHCNF_FLUSH
|
||||||
|
!endif
|
||||||
|
!define SHCNF_FLUSH 0x1000
|
||||||
|
|
||||||
|
!macro UPDATEFILEASSOC
|
||||||
|
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
|
||||||
|
; can update the shell.
|
||||||
|
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
|
||||||
|
!macroend
|
@ -2,6 +2,7 @@
|
|||||||
!include FileFunc.nsh
|
!include FileFunc.nsh
|
||||||
!include x64.nsh
|
!include x64.nsh
|
||||||
!include WordFunc.nsh
|
!include WordFunc.nsh
|
||||||
|
!include "FileAssociation.nsh"
|
||||||
|
|
||||||
!define MANUFACTURER "{{manufacturer}}"
|
!define MANUFACTURER "{{manufacturer}}"
|
||||||
!define PRODUCTNAME "{{product_name}}"
|
!define PRODUCTNAME "{{product_name}}"
|
||||||
@ -527,6 +528,13 @@ Section Install
|
|||||||
IntOp $AppSize $AppSize + $0
|
IntOp $AppSize $AppSize + $0
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
; Create file associations
|
||||||
|
{{#each file_associations as |association| ~}}
|
||||||
|
{{#each association.ext as |ext| ~}}
|
||||||
|
!insertmacro APP_ASSOCIATE "{{ext}}" "{{or association.name ext}}" "{{association-description association.description ext}}" "$INSTDIR\${MAINBINARYNAME}.exe,0" "Open with ${PRODUCTNAME}" "$INSTDIR\${MAINBINARYNAME}.exe $\"%1$\""
|
||||||
|
{{/each}}
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
; Create uninstaller
|
; Create uninstaller
|
||||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
@ -623,6 +631,13 @@ Section Uninstall
|
|||||||
Delete "$INSTDIR\\{{this}}"
|
Delete "$INSTDIR\\{{this}}"
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
; Delete app associations
|
||||||
|
{{#each file_associations as |association| ~}}
|
||||||
|
{{#each association.ext as |ext| ~}}
|
||||||
|
!insertmacro APP_UNASSOCIATE "{{ext}}" "{{or association.name ext}}"
|
||||||
|
{{/each}}
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
; Delete uninstaller
|
; Delete uninstaller
|
||||||
Delete "$INSTDIR\uninstall.exe"
|
Delete "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
|
@ -114,6 +114,15 @@
|
|||||||
</Component>
|
</Component>
|
||||||
<Component Id="Path" Guid="{{path_component_guid}}" Win64="$(var.Win64)">
|
<Component Id="Path" Guid="{{path_component_guid}}" Win64="$(var.Win64)">
|
||||||
<File Id="Path" Source="{{app_exe_source}}" KeyPath="yes" Checksum="yes"/>
|
<File Id="Path" Source="{{app_exe_source}}" KeyPath="yes" Checksum="yes"/>
|
||||||
|
{{#each file_associations as |association| ~}}
|
||||||
|
{{#each association.ext as |ext| ~}}
|
||||||
|
<ProgId Id="{{../../product_name}}.{{ext}}" Advertise="yes" Description="{{association.description}}">
|
||||||
|
<Extension Id="{{ext}}" Advertise="yes">
|
||||||
|
<Verb Id="open" Command="Open with {{../../product_name}}" Argument=""%1"" />
|
||||||
|
</Extension>
|
||||||
|
</ProgId>
|
||||||
|
{{/each~}}
|
||||||
|
{{/each~}}
|
||||||
</Component>
|
</Component>
|
||||||
{{#each binaries as |bin| ~}}
|
{{#each binaries as |bin| ~}}
|
||||||
<Component Id="{{ bin.id }}" Guid="{{bin.guid}}" Win64="$(var.Win64)">
|
<Component Id="{{ bin.id }}" Guid="{{bin.guid}}" Win64="$(var.Win64)">
|
||||||
|
130
tooling/cli/Cargo.lock
generated
130
tooling/cli/Cargo.lock
generated
@ -613,6 +613,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core2"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
@ -798,6 +807,12 @@ dependencies = [
|
|||||||
"syn 2.0.17",
|
"syn 2.0.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dary_heap"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.17"
|
version = "0.99.17"
|
||||||
@ -1437,6 +1452,15 @@ version = "0.12.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -1502,7 +1526,21 @@ checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mac",
|
"mac",
|
||||||
"markup5ever",
|
"markup5ever 0.10.1",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "html5ever"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"mac",
|
||||||
|
"markup5ever 0.11.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
@ -1679,7 +1717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown 0.12.3",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2002,7 +2040,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358"
|
checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cssparser",
|
"cssparser",
|
||||||
"html5ever",
|
"html5ever 0.25.2",
|
||||||
|
"matches",
|
||||||
|
"selectors",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kuchikiki"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8"
|
||||||
|
dependencies = [
|
||||||
|
"cssparser",
|
||||||
|
"html5ever 0.26.0",
|
||||||
|
"indexmap",
|
||||||
"matches",
|
"matches",
|
||||||
"selectors",
|
"selectors",
|
||||||
]
|
]
|
||||||
@ -2040,21 +2091,25 @@ checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libflate"
|
name = "libflate"
|
||||||
version = "1.4.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18"
|
checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
|
"core2",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"dary_heap",
|
||||||
"libflate_lz77",
|
"libflate_lz77",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libflate_lz77"
|
name = "libflate_lz77"
|
||||||
version = "1.2.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf"
|
checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"core2",
|
||||||
|
"hashbrown 0.13.2",
|
||||||
"rle-decode-fast",
|
"rle-decode-fast",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2137,7 +2192,21 @@ checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"phf 0.8.0",
|
"phf 0.8.0",
|
||||||
"phf_codegen",
|
"phf_codegen 0.8.0",
|
||||||
|
"string_cache",
|
||||||
|
"string_cache_codegen",
|
||||||
|
"tendril",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markup5ever"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"phf 0.10.1",
|
||||||
|
"phf_codegen 0.10.0",
|
||||||
"string_cache",
|
"string_cache",
|
||||||
"string_cache_codegen",
|
"string_cache_codegen",
|
||||||
"tendril",
|
"tendril",
|
||||||
@ -2729,6 +2798,16 @@ dependencies = [
|
|||||||
"phf_shared 0.8.0",
|
"phf_shared 0.8.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_codegen"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator 0.10.0",
|
||||||
|
"phf_shared 0.10.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_generator"
|
name = "phf_generator"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -3335,7 +3414,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"matches",
|
"matches",
|
||||||
"phf 0.8.0",
|
"phf 0.8.0",
|
||||||
"phf_codegen",
|
"phf_codegen 0.8.0",
|
||||||
"precomputed-hash",
|
"precomputed-hash",
|
||||||
"servo_arc",
|
"servo_arc",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@ -3896,7 +3975,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"handlebars 4.3.7",
|
"handlebars 4.3.7",
|
||||||
"heck",
|
"heck",
|
||||||
"html5ever",
|
"html5ever 0.26.0",
|
||||||
"ignore",
|
"ignore",
|
||||||
"image",
|
"image",
|
||||||
"include_dir",
|
"include_dir",
|
||||||
@ -3907,7 +3986,7 @@ dependencies = [
|
|||||||
"jsonrpsee-core",
|
"jsonrpsee-core",
|
||||||
"jsonrpsee-ws-client",
|
"jsonrpsee-ws-client",
|
||||||
"jsonschema",
|
"jsonschema",
|
||||||
"kuchiki",
|
"kuchikiki",
|
||||||
"libc",
|
"libc",
|
||||||
"local-ip-address",
|
"local-ip-address",
|
||||||
"log",
|
"log",
|
||||||
@ -4012,7 +4091,7 @@ dependencies = [
|
|||||||
"ctor 0.1.26",
|
"ctor 0.1.26",
|
||||||
"getrandom 0.2.9",
|
"getrandom 0.2.9",
|
||||||
"heck",
|
"heck",
|
||||||
"html5ever",
|
"html5ever 0.25.2",
|
||||||
"infer",
|
"infer",
|
||||||
"json-patch",
|
"json-patch",
|
||||||
"json5",
|
"json5",
|
||||||
@ -4041,11 +4120,11 @@ dependencies = [
|
|||||||
"getrandom 0.2.9",
|
"getrandom 0.2.9",
|
||||||
"glob",
|
"glob",
|
||||||
"heck",
|
"heck",
|
||||||
"html5ever",
|
"html5ever 0.26.0",
|
||||||
"infer",
|
"infer",
|
||||||
"json-patch",
|
"json-patch",
|
||||||
"json5",
|
"json5",
|
||||||
"kuchiki",
|
"kuchikiki",
|
||||||
"memchr",
|
"memchr",
|
||||||
"phf 0.10.1",
|
"phf 0.10.1",
|
||||||
"schemars",
|
"schemars",
|
||||||
@ -4058,7 +4137,7 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
"url",
|
"url",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"windows 0.44.0",
|
"windows 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4773,23 +4852,14 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.39.0",
|
"windows_x86_64_msvc 0.39.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows"
|
|
||||||
version = "0.44.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
|
|
||||||
dependencies = [
|
|
||||||
"windows-implement 0.44.0",
|
|
||||||
"windows-interface",
|
|
||||||
"windows-targets 0.42.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"windows-implement 0.48.0",
|
||||||
|
"windows-interface",
|
||||||
"windows-targets 0.48.0",
|
"windows-targets 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4805,9 +4875,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-implement"
|
name = "windows-implement"
|
||||||
version = "0.44.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ce87ca8e3417b02dc2a8a22769306658670ec92d78f1bd420d6310a67c245c6"
|
checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -4816,9 +4886,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-interface"
|
name = "windows-interface"
|
||||||
version = "0.44.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "853f69a591ecd4f810d29f17e902d40e349fb05b0b11fff63b08b826bfe39c7f"
|
checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -925,6 +925,16 @@
|
|||||||
"null"
|
"null"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"fileAssociations": {
|
||||||
|
"description": "File associations to application.",
|
||||||
|
"type": [
|
||||||
|
"array",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/FileAssociation"
|
||||||
|
}
|
||||||
|
},
|
||||||
"shortDescription": {
|
"shortDescription": {
|
||||||
"description": "A short description of your application.",
|
"description": "A short description of your application.",
|
||||||
"type": [
|
"type": [
|
||||||
@ -1122,6 +1132,97 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"FileAssociation": {
|
||||||
|
"description": "File association",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ext"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"ext": {
|
||||||
|
"description": "File extensions to associate with this app. e.g. 'png'",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/AssociationExt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "The name. Maps to `CFBundleTypeName` on macOS. Default to ext[0]",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"description": "The association description. Windows-only. It is displayed on the `Type` column on Windows Explorer.",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"description": "The app’s role with respect to the type. Maps to `CFBundleTypeRole` on macOS.",
|
||||||
|
"default": "Editor",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/BundleTypeRole"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mimeType": {
|
||||||
|
"description": "The mime-type e.g. 'image/png' or 'text/plain'. Linux-only.",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"AssociationExt": {
|
||||||
|
"description": "An extension for a [`FileAssociation`].\n\nA leading `.` is automatically stripped.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"BundleTypeRole": {
|
||||||
|
"description": "macOS-only. Corresponds to CFBundleTypeRole",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Editor. Files can be read and edited.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Editor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Viewer. Files can be read.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Viewer"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.Shell",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Shell"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.QLGenerator",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"QLGenerator"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "CFBundleTypeRole.None",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"None"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"AppImageConfig": {
|
"AppImageConfig": {
|
||||||
"description": "Configuration for AppImage bundles.\n\nSee more: https://tauri.app/v1/api/config#appimageconfig",
|
"description": "Configuration for AppImage bundles.\n\nSee more: https://tauri.app/v1/api/config#appimageconfig",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -79,8 +79,6 @@ pub fn command(options: Options) -> Result<()> {
|
|||||||
let r = command_internal(options);
|
let r = command_internal(options);
|
||||||
if r.is_err() {
|
if r.is_err() {
|
||||||
kill_before_dev_process();
|
kill_before_dev_process();
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
let _ = check_for_updates();
|
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
@ -262,8 +260,6 @@ pub fn setup(options: &mut Options, mobile: bool) -> Result<AppInterface> {
|
|||||||
|
|
||||||
let _ = ctrlc::set_handler(move || {
|
let _ = ctrlc::set_handler(move || {
|
||||||
kill_before_dev_process();
|
kill_before_dev_process();
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
let _ = check_for_updates();
|
|
||||||
exit(130);
|
exit(130);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1130,6 +1130,7 @@ fn tauri_config_to_bundle_settings(
|
|||||||
})?),
|
})?),
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
|
file_associations: config.file_associations,
|
||||||
short_description: config.short_description,
|
short_description: config.short_description,
|
||||||
long_description: config.long_description,
|
long_description: config.long_description,
|
||||||
external_bin: config.external_bin,
|
external_bin: config.external_bin,
|
||||||
|
Loading…
Reference in New Issue
Block a user