Skip to content
170 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r91//! The app's menu: File, Edit, View, Go, Window and Help, as a desktop app
2//! has. On macOS it is the menu bar at the top of the screen, with g1t's
3//! own menu first; on Windows and Linux it sits under the window's title,
4//! and settings can hide it. The tray's menu (tray.rs) shares its ids, and
5//! every menu event, from either, comes to `handle`.
6
7use tauri::menu::{AboutMetadata, Menu, MenuItem, PredefinedMenuItem, Submenu};
8use tauri::{AppHandle, Wry};
9use tauri_plugin_opener::OpenerExt;
10
11use crate::{links, settings, tray, updates};
12
13const DOCS: &str = "https://docs.g1t.sh/guides/desktop/";
14const STATUS: &str = "https://status.g1t.sh/";
15
16pub fn build(app: &AppHandle) -> tauri::Result<Menu<Wry>> {
17 let separator = || PredefinedMenuItem::separator(app);
18 let item = |id: &str, text: &str, accelerator: Option<&str>| MenuItem::with_id(app, id, text, true, accelerator);
19
20 let settings_item = item("settings", if cfg!(target_os = "macos") { "Settings…" } else { "Settings" }, Some("CmdOrCtrl+,"))?;
21 let check = item("check", "Check for updates…", None)?;
22 let server = item("server", "Use another g1t…", None)?;
23 let quit = item("quit", "Quit g1t", Some("CmdOrCtrl+Q"))?;
24
25 let edit = Submenu::with_items(
26 app,
27 "Edit",
28 true,
29 &[
30 &PredefinedMenuItem::undo(app, None)?,
31 &PredefinedMenuItem::redo(app, None)?,
32 &separator()?,
33 &PredefinedMenuItem::cut(app, None)?,
34 &PredefinedMenuItem::copy(app, None)?,
35 &PredefinedMenuItem::paste(app, None)?,
36 &PredefinedMenuItem::select_all(app, None)?,
37 ],
38 )?;
39 let view = Submenu::with_items(
40 app,
41 "View",
42 true,
43 &[
44 &item("reload", "Reload", Some("CmdOrCtrl+R"))?,
45 &separator()?,
46 &item("zoom-reset", "Actual size", Some("CmdOrCtrl+0"))?,
47 &item("zoom-in", "Zoom in", Some("CmdOrCtrl+="))?,
48 &item("zoom-out", "Zoom out", Some("CmdOrCtrl+-"))?,
49 &separator()?,
50 &PredefinedMenuItem::fullscreen(app, None)?,
51 ],
52 )?;
53 let go = Submenu::with_items(
54 app,
55 "Go",
56 true,
57 &[
58 &item("back", "Back", Some(if cfg!(target_os = "macos") { "Cmd+[" } else { "Alt+Left" }))?,
59 &item("forward", "Forward", Some(if cfg!(target_os = "macos") { "Cmd+]" } else { "Alt+Right" }))?,
60 &separator()?,
61 &item("home", "Home", None)?,
62 &item("notifications", "Notifications", None)?,
63 ],
64 )?;
65 let window = Submenu::with_items(
66 app,
67 "Window",
68 true,
69 &[&PredefinedMenuItem::minimize(app, None)?, &PredefinedMenuItem::maximize(app, None)?],
70 )?;
71 let help = Submenu::with_items(
72 app,
73 "Help",
74 true,
75 &[&item("docs", "Desktop app guide", None)?, &item("status", "g1t.sh status", None)?, &separator()?, &check, &tray::restart_item(app)?],
76 )?;
77 // macOS keeps About in g1t's own menu; elsewhere it closes Help.
78 #[cfg(not(target_os = "macos"))]
79 {
80 help.append(&separator()?)?;
81 help.append(&PredefinedMenuItem::about(app, Some("About g1t"), Some(about()))?)?;
82 }
83
84 #[cfg(target_os = "macos")]
85 {
86 let g1t = Submenu::with_items(
87 app,
88 "g1t",
89 true,
90 &[
91 &PredefinedMenuItem::about(app, Some("About g1t"), Some(about()))?,
92 &separator()?,
93 &settings_item,
94 &server,
95 &separator()?,
96 &PredefinedMenuItem::services(app, None)?,
97 &separator()?,
98 &PredefinedMenuItem::hide(app, None)?,
99 &PredefinedMenuItem::hide_others(app, None)?,
100 &PredefinedMenuItem::show_all(app, None)?,
101 &separator()?,
102 &quit,
103 ],
104 )?;
105 let file = Submenu::with_items(app, "File", true, &[&PredefinedMenuItem::close_window(app, None)?])?;
106 Menu::with_items(app, &[&g1t, &file, &edit, &view, &go, &window, &help])
107 }
108 #[cfg(not(target_os = "macos"))]
109 {
110 let file = Submenu::with_items(
111 app,
112 "File",
113 true,
114 &[&settings_item, &server, &separator()?, &item("close", "Close window", Some("CmdOrCtrl+W"))?, &quit],
115 )?;
116 Menu::with_items(app, &[&file, &edit, &view, &go, &window, &help])
117 }
118}
119
120fn about() -> AboutMetadata<'static> {
121 AboutMetadata {
122 name: Some("g1t".into()),
123 version: Some(env!("CARGO_PKG_VERSION").into()),
124 copyright: Some("Flagon, Inc.".into()),
125 website: Some("https://g1t.sh".into()),
126 website_label: Some("g1t.sh".into()),
127 ..Default::default()
128 }
129}
130
131/// Runs the script on the main window's page.
132fn eval(app: &AppHandle, script: &str) {
133 if let Some(site) = crate::frame::site(app) {
134 let _ = site.eval(script);
135 }
136}
137
138/// A menu row was chosen, from the app's menu or the tray's.
139pub fn handle(app: &AppHandle, id: &str) {
140 match id {
141 "open" => tray::show(app),
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.142 "settings" | "runner-status" => settings::open(app),
143 "runner-toggle" => crate::runner::toggle(app),
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9144 "server" => tray::launcher(app, "change"),
145 // The settings window asks, and shows the answer where it cannot be missed.
146 "check" => settings::open_and_check(app),
147 "restart" => updates::restart(app),
148 "quit" => updates::quit(app),
149 "close" => tray::close(app),
150 "reload" => {
151 if let Some(site) = crate::frame::site(app) {
152 let _ = site.reload();
153 }
154 }
155 "zoom-in" => settings::zoom(app, 1),
156 "zoom-out" => settings::zoom(app, -1),
157 "zoom-reset" => settings::zoom(app, 0),
158 "back" => eval(app, "history.back()"),
159 "forward" => eval(app, "history.forward()"),
160 "home" => links::go(app, "/"),
161 "notifications" => links::go(app, "/notifications"),
162 "docs" => {
163 let _ = app.opener().open_url(DOCS, None::<&str>);
164 }
165 "status" => {
166 let _ = app.opener().open_url(STATUS, None::<&str>);
167 }
168 _ => {}
169 }
170}

This file's history is long; its oldest lines are credited to the oldest commit read.