Skip to content

Commit

Permalink
feat: add OpenFile event for macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
meowtec committed Jun 12, 2022
1 parent e4937d0 commit 291d764
Show file tree
Hide file tree
Showing 17 changed files with 3,532 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ exclude = [
"examples/api/src-tauri",
"examples/updater/src-tauri",
"examples/resources/src-tauri",
"examples/sidecar/src-tauri"
"examples/sidecar/src-tauri",
"examples/file-associations/src-tauri"
]

# default to small, optimized workspace release binaries
Expand Down
3 changes: 3 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,9 @@ fn handle_event_loop<T: UserEvent>(
);
}
},
Event::OpenFile(file_path) => {
callback(RunEvent::OpenFile(file_path));
},
_ => (),
}

Expand Down
2 changes: 2 additions & 0 deletions core/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub trait UserEvent: Debug + Clone + Send + 'static {}
impl<T: Debug + Clone + Send + 'static> UserEvent for T {}

/// Event triggered on the event loop run.
#[derive(Debug)]
#[non_exhaustive]
pub enum RunEvent<T: UserEvent> {
/// Event loop is exiting.
Expand All @@ -225,6 +226,7 @@ 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.
MainEventsCleared,
OpenFile(PathBuf),
/// A custom event defined by the user.
UserEvent(T),
}
Expand Down
45 changes: 45 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,46 @@ impl BundleTarget {
}
}

/// macOS-only. Corresponds to CFBundleTypeRole
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
pub enum FileAssociationRole {
/// CFBundleTypeRole.Editor. Files can be read and edited.
Editor,
/// CFBundleTypeRole.Viewer. Files can be read.
Viewer,
/// CFBundleTypeRole.Shell
Shell,
/// CFBundleTypeRole.QLGenerator
QLGenerator,
/// CFBundleTypeRole.None
None,
}

impl Display for FileAssociationRole {
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"),
}
}
}

/// File association
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
pub struct FileAssociation {
/// File extensions to associate with this app.
pub ext: Vec<String>,
/// The name. Default to ext[0]
pub name: Option<String>,
/// macOS-only The app’s role with respect to the type.
pub role: Option<FileAssociationRole>,
}

/// Configuration for Debian (.deb) bundles.
#[skip_serializing_none]
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
Expand Down Expand Up @@ -318,6 +358,8 @@ pub struct BundleConfig {
/// 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.
pub category: Option<String>,
/// File associations to application.
pub file_associations: Option<Vec<FileAssociation>>,
/// A short description of your application.
pub short_description: Option<String>,
/// A longer, multi-line description of the application.
Expand Down Expand Up @@ -2726,6 +2768,7 @@ mod build {
let resources = quote!(None);
let copyright = quote!(None);
let category = quote!(None);
let file_associations = quote!(None);
let short_description = quote!(None);
let long_description = quote!(None);
let deb = quote!(Default::default());
Expand All @@ -2743,6 +2786,7 @@ mod build {
resources,
copyright,
category,
file_associations,
short_description,
long_description,
deb,
Expand Down Expand Up @@ -3145,6 +3189,7 @@ mod test {
resources: None,
copyright: None,
category: None,
file_associations: None,
short_description: None,
long_description: None,
deb: Default::default(),
Expand Down
7 changes: 7 additions & 0 deletions core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ 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.
MainEventsCleared,
/// Emitted when a file is opened by application.
OpenFile(PathBuf),
/// Updater event.
#[cfg(updater)]
#[cfg_attr(doc_cfg, doc(cfg(feature = "updater")))]
Expand Down Expand Up @@ -1502,6 +1504,10 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
manager.on_window_close(label);
}

if let RuntimeRunEvent::OpenFile(file_path) = &event {
app_handle.trigger_global("open-file", Some(file_path.to_string_lossy().to_string()));
}

let event = match event {
RuntimeRunEvent::Exit => RunEvent::Exit,
RuntimeRunEvent::ExitRequested { tx } => RunEvent::ExitRequested {
Expand All @@ -1515,6 +1521,7 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
RuntimeRunEvent::Resumed => RunEvent::Resumed,
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
RuntimeRunEvent::UserEvent(t) => t.into(),
RuntimeRunEvent::OpenFile(file_path) => RunEvent::OpenFile(file_path),
_ => unimplemented!(),
};

Expand Down
11 changes: 11 additions & 0 deletions examples/file-associations/README.md
Original file line number Diff line number Diff line change
@@ -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
```
12 changes: 12 additions & 0 deletions examples/file-associations/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!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>
</body>
</html>
15 changes: 15 additions & 0 deletions examples/file-associations/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "file-associations",
"version": "1.0.0",
"pkg": {
"assets": [
"src/**/*"
]
},
"scripts": {
"tauri": "node ../../tooling/cli/node/tauri.js"
},
"devDependencies": {

}
}
28 changes: 28 additions & 0 deletions examples/file-associations/scripts/move-binary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* This script is used to rename the binary with the platform specific postfix.
* When `tauri build` is ran, it looks for the binary name appended with the platform specific postfix.
*/

const execa = require('execa')
const fs = require('fs')

let extension = ''
if (process.platform === 'win32') {
extension = '.exe'
}

async function main() {
const rustInfo = (await execa('rustc', ['-vV'])).stdout
const targetTriple = /host: (\S+)/g.exec(rustInfo)[1]
if (!targetTriple) {
console.error('Failed to determine platform target triple')
}
fs.renameSync(
`src-tauri/binaries/app${extension}`,
`src-tauri/binaries/app-${targetTriple}${extension}`
)
}

main().catch((e) => {
throw e
})
4 changes: 4 additions & 0 deletions examples/file-associations/src-tauri/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
WixTools
3 changes: 3 additions & 0 deletions examples/file-associations/src-tauri/.license_template
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 291d764

Please sign in to comment.