Skip to content

Commit 833c5f7

Browse files
committed
fix: file open event
- Updated the @tauri-apps/api dependency in package.json and pnpm-lock.yaml to version 2.10.1 for improved functionality. - Added support for file open events in JsonEditor.svelte, allowing users to open files via macOS "Open With" and double-click actions. - Enhanced the Tauri application to handle file paths passed via command line arguments on Windows/Linux, emitting an "open-file" event for JSON files.
1 parent c975691 commit 833c5f7

4 files changed

Lines changed: 75 additions & 16 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"author": "sundegan",
2020
"dependencies": {
2121
"@monaco-editor/loader": "^1.7.0",
22-
"@tauri-apps/api": "^2",
22+
"@tauri-apps/api": "^2.10.1",
2323
"@tauri-apps/plugin-opener": "^2",
2424
"bits-ui": "^2.15.2",
2525
"clsx": "^2.1.1",

pnpm-lock.yaml

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/src/lib.rs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use commands::json::{json_format, json_minify, json_stats, json_validate, json_e
44
use commands::window::{set_window_theme, open_devtools};
55
use commands::shortcuts::{show_main_window, format_clipboard_and_show, update_shortcut};
66
use commands::file::{open_file_dialog, save_file, save_file_dialog, read_file, is_json_file, get_file_name};
7+
use tauri::Emitter;
78
use tauri_plugin_global_shortcut::GlobalShortcutExt;
89

910
#[cfg_attr(mobile, tauri::mobile_entry_point)]
1011
pub fn run() {
11-
tauri::Builder::default()
12+
let app = tauri::Builder::default()
1213
.plugin(tauri_plugin_opener::init())
1314
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
1415
.plugin(tauri_plugin_clipboard_manager::init())
@@ -34,6 +35,30 @@ pub fn run() {
3435
let _ = format_clipboard_and_show(handle).await;
3536
});
3637
}).map_err(|e| format!("Failed to register format clipboard shortcut: {}", e))?;
38+
39+
// Windows/Linux: file paths are passed via command line arguments
40+
#[cfg(not(target_os = "macos"))]
41+
{
42+
use std::path::Path;
43+
let paths: Vec<String> = std::env::args()
44+
.skip(1)
45+
.filter(|arg| !arg.starts_with('-'))
46+
.filter(|arg| {
47+
let p = Path::new(arg);
48+
p.exists() && p.extension().and_then(|e| e.to_str())
49+
.map(|e| e.eq_ignore_ascii_case("json"))
50+
.unwrap_or(false)
51+
})
52+
.collect();
53+
54+
if !paths.is_empty() {
55+
let handle = app.handle().clone();
56+
tauri::async_runtime::spawn(async move {
57+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
58+
let _ = handle.emit("open-file", paths);
59+
});
60+
}
61+
}
3762

3863
Ok(())
3964
})
@@ -56,6 +81,27 @@ pub fn run() {
5681
is_json_file,
5782
get_file_name
5883
])
59-
.run(tauri::generate_context!())
60-
.expect("error while running tauri application");
84+
.build(tauri::generate_context!())
85+
.expect("error while building tauri application");
86+
87+
app.run(|app_handle, event| {
88+
// macOS: file open events come through RunEvent::Opened
89+
#[cfg(target_os = "macos")]
90+
if let tauri::RunEvent::Opened { urls } = event {
91+
let paths: Vec<String> = urls
92+
.iter()
93+
.filter_map(|url| {
94+
if url.scheme() == "file" {
95+
url.to_file_path().ok().map(|p| p.to_string_lossy().into_owned())
96+
} else {
97+
None
98+
}
99+
})
100+
.collect();
101+
102+
if !paths.is_empty() {
103+
let _ = app_handle.emit("open-file", paths);
104+
}
105+
}
106+
});
61107
}

src/lib/components/editor/JsonEditor.svelte

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
let unlistenFormatted: (() => void) | null = null;
8585
let unlistenRaw: (() => void) | null = null;
8686
let unlistenFileDrop: (() => void) | null = null;
87+
let unlistenOpenFile: (() => void) | null = null;
8788
8889
(async () => {
8990
const { listen } = await import('@tauri-apps/api/event');
@@ -113,7 +114,6 @@
113114
});
114115
115116
// Listen for file drop events
116-
// Tauri 2.0 uses 'tauri://drag-drop' event
117117
unlistenFileDrop = await listen<{ paths: string[], position: { x: number, y: number } }>('tauri://drag-drop', async (event) => {
118118
const paths = event.payload?.paths;
119119
if (paths && paths.length > 0) {
@@ -122,19 +122,31 @@
122122
const fileContent = await readFile(filePath);
123123
const name = await getFileName(filePath);
124124
125-
const currentTab = $activeTab;
126-
127-
// Always create a new tab for dropped files
128125
tabsStore.addTab(fileContent, filePath, name);
129-
// Content and editor will be updated by $effect when tab switches
130-
131126
showToast(`Opened: ${name || 'file'}`);
132127
} catch (e) {
133128
showToast('Failed to open file');
134129
console.error('Drop file error:', e);
135130
}
136131
}
137132
});
133+
134+
// Listen for file open events (macOS "Open With" / double-click)
135+
unlistenOpenFile = await listen<string[]>('open-file', async (event) => {
136+
const paths = event.payload;
137+
if (!paths || paths.length === 0) return;
138+
for (const filePath of paths) {
139+
try {
140+
const fileContent = await readFile(filePath);
141+
const name = await getFileName(filePath);
142+
tabsStore.addTab(fileContent, filePath, name);
143+
showToast(`Opened: ${name || 'file'}`);
144+
} catch (e) {
145+
showToast('Failed to open file');
146+
console.error('Open file error:', e);
147+
}
148+
}
149+
});
138150
})();
139151
140152
// Keyboard shortcuts
@@ -231,6 +243,7 @@
231243
if (unlistenFormatted) unlistenFormatted();
232244
if (unlistenRaw) unlistenRaw();
233245
if (unlistenFileDrop) unlistenFileDrop();
246+
if (unlistenOpenFile) unlistenOpenFile();
234247
if (diffModeUnsubscribe) diffModeUnsubscribe();
235248
window.removeEventListener('keydown', handleKeydown);
236249
};

0 commit comments

Comments
 (0)