aboutsummaryrefslogtreecommitdiff
path: root/bundle/src-tauri/src
diff options
context:
space:
mode:
Diffstat (limited to 'bundle/src-tauri/src')
-rw-r--r--bundle/src-tauri/src/main.rs16
-rw-r--r--bundle/src-tauri/src/menu.rs55
2 files changed, 70 insertions, 1 deletions
diff --git a/bundle/src-tauri/src/main.rs b/bundle/src-tauri/src/main.rs
index 80b28c5..9f63fc5 100644
--- a/bundle/src-tauri/src/main.rs
+++ b/bundle/src-tauri/src/main.rs
@@ -1,6 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
mod compiler;
+mod menu;
mod runner;
use compiler::Compiler;
use runner::{OutputEvent, Runner};
@@ -11,7 +12,9 @@ use std::{
Mutex,
},
};
-use tauri::{ipc::Channel, AppHandle, Manager, State, WebviewWindow, WebviewWindowBuilder};
+use tauri::{
+ ipc::Channel, AppHandle, Emitter, Manager, State, WebviewWindow, WebviewWindowBuilder,
+};
// Each window runs its own program, keyed by window label.
#[derive(Default)]
@@ -87,6 +90,17 @@ fn main() {
let compiler = Compiler::load();
tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
+ .menu(menu::build)
+ // Menu items act on the focused window, like its keyboard shortcuts.
+ .on_menu_event(|app, event| {
+ let focused = app
+ .webview_windows()
+ .into_values()
+ .find(|window| window.is_focused().unwrap_or(false));
+ if let Some(window) = focused {
+ let _ = window.emit_to(window.label(), "menu", event.id().as_ref());
+ }
+ })
.manage(Runners::default())
.manage(compiler)
.invoke_handler(tauri::generate_handler![
diff --git a/bundle/src-tauri/src/menu.rs b/bundle/src-tauri/src/menu.rs
new file mode 100644
index 0000000..83ba7e3
--- /dev/null
+++ b/bundle/src-tauri/src/menu.rs
@@ -0,0 +1,55 @@
+use tauri::{
+ menu::{Menu, MenuBuilder, MenuItem, SubmenuBuilder},
+ AppHandle, Runtime,
+};
+
+// One menu for all platforms: the macOS menu bar, or the top of each window elsewhere.
+// Custom item ids name the frontend commands that the same shortcuts run.
+pub fn build<R: Runtime>(app: &AppHandle<R>) -> tauri::Result<Menu<R>> {
+ let item = |id: &str, text: &str, accelerator: &str| {
+ MenuItem::with_id(app, id, text, true, Some(accelerator))
+ };
+ let file = SubmenuBuilder::new(app, "File")
+ .item(&item("new", "New", "CmdOrCtrl+N")?)
+ .item(&item("new_window", "New Window", "CmdOrCtrl+Shift+N")?)
+ .item(&item("open", "Open…", "CmdOrCtrl+O")?)
+ .item(&item("save", "Save", "CmdOrCtrl+S")?)
+ .separator()
+ .close_window()
+ .build()?;
+ // macOS needs the predefined edit items for clipboard and undo keys in the webview.
+ let edit = SubmenuBuilder::new(app, "Edit")
+ .undo()
+ .redo()
+ .separator()
+ .cut()
+ .copy()
+ .paste()
+ .select_all()
+ .separator()
+ .item(&item("find", "Find", "CmdOrCtrl+F")?)
+ .item(&item("comment", "Toggle Line Comment", "CmdOrCtrl+/")?)
+ .build()?;
+ let window = SubmenuBuilder::new(app, "Window")
+ .minimize()
+ .maximize()
+ .build()?;
+ let menu = MenuBuilder::new(app);
+ // macOS shows the first submenu as the application menu. Quit skips unsaved-changes
+ // prompts, so other platforms close windows instead.
+ #[cfg(target_os = "macos")]
+ let menu = menu.item(
+ &SubmenuBuilder::new(app, "CPSC Bundle")
+ .about(None)
+ .separator()
+ .services()
+ .separator()
+ .hide()
+ .hide_others()
+ .show_all()
+ .separator()
+ .quit()
+ .build()?,
+ );
+ menu.items(&[&file, &edit, &window]).build()
+}