
Application Menu(앱의 이름), File, Edit, View, Window는 macOS가 자동으로 추가하는 메뉴이다. macOS는 자체적으로 애플리케이션에 몇 가지 기본 메뉴 항목을 제공한다. 이는 macOS에서의 일관된 사용자 경험을 제공하기 위한 운영체제 수준의 기능이다.
기본적으로 추가되는 macOS 메뉴 항목들:
Application Menu: 애플리케이션 자체를 위한 메뉴
File: 일반적으로 파일 관련 작업 (새 파일 열기, 저장 등)을 위한 메뉴
Edit: 복사, 붙여넣기, 잘라내기 등과 같은 편집 작업
View: 창 레이아웃 변경이나 창 확대/축소 기능 등
Window: 열린 창들을 관리하는 옵션
이 메뉴들은 Tauri 애플리케이션의 메뉴 설정과 관계없이 기본적으로 macOS에서 제공하며, 운영체제 차원에서 자동으로 추가된다. 이러한 항목을 제거하거나 수정하려면 Tauri에서 메뉴 설정을 통해 명시적으로 메뉴를 구성해야 한다.
Tauri 빌드 시 별도로 메뉴에 대한 설정을 하지 않으면 macOS가 추가하는 메뉴들이 설정된다.
만약 커스텀하게 메뉴를 관리한다면, macOS에서 제공되는 기능들은 모두 제거되기 때문에 필요한 기능을 직접 구현해야한다.

윈도우 메뉴의 기본 구조는 다음과 같다.
Menu 하위에 SubMenu가 존재하고, SubMenu 하위에 MenuItem/CustomMenuItem이 존재한다. 이때 OS가 추가하는 메뉴는 MenuItem, 사용자가 직접 추가하는 메뉴는 CustomMenuItem이다.
use tauri::{CustomMenuItem, Menu, MenuItem, Submenu};
tauri에서는 각각의 요소를 생성할 수 있는 생성자를 제공한다.
첨부된 이미지들은 Window Menu 영역을 캡쳐한 것들이다.
tauri::Builder::default()
.run(tauri::generate_context!())
.expect("error while running tauri application");
다음의 코드를 통해 tauri 앱을 빌드한다. 별도로 메뉴 설정을 하지 않았기 때문에 macOS에서 제공하는 메뉴들이 추가되는 상태이다.

let menu = Menu::new();
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
menu 하위에 SubMenu/MenuItem을 추가하지 않았기 때문에 아무런 메뉴도 노출되지 않는다.
새로운 메뉴를 만들어서 추가했기 때문에 기존 macOS에서 제공하는 메뉴들도 적용되지 않는다.

let first = Submenu::new("First", Menu::new());
let menu = Menu::new().add_submenu(first);
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
이번엔 menu에 First라는 이름의 SubMenu를 추가했다. 하지만 First 대신 cert-jira라는 이름의 SubMenu가 추가된 것을 확인할 수 있다.
이는 macOS에서 기본적으로 첫번째 SubMenu의 이름을 앱의 이름으로 강제하기 때문이다.

let first = Submenu::new("First", Menu::new());
let second = Submenu::new("Second", Menu::new());
let menu = Menu::new().add_submenu(first).add_submenu(second);
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
두번째 SubMenu부터는 설정한 이름이 정상적으로 노출되는 것을 확인할 수 있다.

let initialize = CustomMenuItem::new("initialize".to_string(), "초기화");
let quit = CustomMenuItem::new("quit".to_string(), "종료");
let first = Submenu::new("First", Menu::new().add_item(initialize).add_item(quit));
let menu = Menu::new().add_submenu(first);
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
menu에 First라는 이름의 SubMenu를 추가한다.
=> cert-jira 탭이 생성된다. (앱의 이름이 cert-jira이기 때문)
First 하위에는 Initialize, Quit 두 종류의 CustomMenuItem을 추가한다.
=> cert-jira 탭 하위에 "초기화", "종료" 두 종류의 버튼이 추가된다.

let initialize = CustomMenuItem::new("initialize".to_string(), "초기화");
let quit = CustomMenuItem::new("quit".to_string(), "종료");
let first = Submenu::new(
"First",
Menu::new()
.add_item(initialize)
.add_item(quit))
.add_native_item(MenuItem::Undo),
);
let menu = Menu::new().add_submenu(first);
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
add_native_item이라는 메서드를 활용하여 OS에서 제공하는 기본적인 기능을 추가할 수 있다.
추가할 수 있는 native item 목록은 이곳에서 확인이 가능하다.

let initialize = CustomMenuItem::new("initialize".to_string(), "초기화").accelerator("cmd + a");
let quit = CustomMenuItem::new("quit".to_string(), "종료").accelerator("cmd + b");
let first = Submenu::new(
"First",
Menu::new()
.add_item(initialize)
.add_item(quit))
.add_native_item(MenuItem::Undo),
);
let menu = Menu::new().add_submenu(first);
tauri::Builder::default()
.menu(menu)
.run(tauri::generate_context!())
.expect("error while running tauri application");
MenuItem에는 기본적으로 단축키가 적용된 것을 볼 수 있다. CustomMenuItem 또한 accelerator 메서드를 통해 단축키 지정이 가능하다.
let initialize = CustomMenuItem::new("initialize".to_string(), "초기화").accelerator("cmd + a");
let quit = CustomMenuItem::new("quit".to_string(), "종료").accelerator("cmd + b");
let first = Submenu::new(
"First",
Menu::new()
.add_item(initialize)
.add_item(quit))
.add_native_item(MenuItem::Undo),
);
let menu = Menu::new().add_submenu(first);
tauri::Builder::default()
.menu(menu)
.on_menu_event(|event| match event.menu_item_id() {
"initialize" => {
event.window().emit("INITIALIZE", "").unwrap();
}
"quit" => {
std::process::exit(0);
}
_ => {}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
MenuItem은 그 자체로 기능을 가지지만, CustomMenuItem은 기능을 지정해주어야 한다. 이를 위한 메서드가 on_menu_event이다. CustomMenuItem의 이름을 키로 하는 객체를 작성하여 실행될 함수를 지정할 수 있다.
동균님 집 윈도우