Skip to content

Commit 4ea89f6

Browse files
committed
feat: minimize to tray on window close and support silent autostart
1 parent 641f0be commit 4ea89f6

6 files changed

Lines changed: 96 additions & 27 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ src-tauri/target/
3131
zapret-discord-youtube-main/
3232
zapret2 releases/
3333
zapret2-master/
34+
Zapret-GUI-main/
3435

3536
# User Local Configuration & State
3637
configs/custom_profiles.json

‎src-tauri/Cargo.lock‎

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

‎src-tauri/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ tauri-build = { version = "2.0", features = [] }
1010
embed-resource = "2.5"
1111

1212
[dependencies]
13-
tauri = { version = "2.0", features = ["tray-icon"] }
13+
tauri = { version = "2.0", features = ["tray-icon", "image-png"] }
1414
tauri-plugin-shell = "2.0"
1515
serde = { version = "1.0", features = ["derive"] }
1616
serde_json = "1.0"

‎src-tauri/src/commands.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,11 @@ pub async fn parse_args_string(raw: String) -> Result<Vec<String>, String> {
192192
let lists_dir = resolved.lists_dir.unwrap_or_else(|| resolved.bin_dir.join("../lists"));
193193
Ok(crate::win32::custom_profiles::parse_command_line_args(&raw, &resolved.bin_dir, &lists_dir))
194194
}
195+
196+
/// Exits the application cleanly, stopping the background supervisor and WinDivert first.
197+
#[tauri::command]
198+
pub async fn exit_app(state: State<'_, AppState>, app: tauri::AppHandle) -> Result<(), String> {
199+
let _ = state.supervisor.stop().await;
200+
app.exit(0);
201+
Ok(())
202+
}

‎src-tauri/src/main.rs‎

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ async fn main() {
3737
// 3. Build Tauri v2 application
3838
tauri::Builder::default()
3939
.plugin(tauri_plugin_shell::init())
40+
.on_window_event(|window, event| {
41+
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
42+
// Intercept close button and hide to system tray instead of terminating
43+
api.prevent_close();
44+
let _ = window.hide();
45+
}
46+
})
4047
.manage(AppState {
4148
supervisor: supervisor_clone,
4249
diagnostics: diagnostics_clone,
@@ -46,11 +53,18 @@ async fn main() {
4653
let handle = app.handle().clone();
4754
supervisor.set_app_handle(handle.clone());
4855

56+
// If started via Windows autostart with --minimized, hide main window
57+
if std::env::args().any(|a| a == "--minimized" || a == "--autostart") {
58+
if let Some(window) = app.get_webview_window("main") {
59+
let _ = window.hide();
60+
}
61+
}
62+
4963
// Build System Tray Menu
50-
let toggle_item = MenuItem::with_id(app, "toggle", "Показать / Скрыть (Show/Hide)", true, None::<&str>)?;
51-
let start_item = MenuItem::with_id(app, "start", "Включить обход (Start Bypass)", true, None::<&str>)?;
52-
let stop_item = MenuItem::with_id(app, "stop", "Выключить обход (Stop Bypass)", true, None::<&str>)?;
53-
let quit_item = MenuItem::with_id(app, "quit", "Выход (Exit)", true, None::<&str>)?;
64+
let toggle_item = MenuItem::with_id(app, "toggle", "Открыть окно zapret2", true, None::<&str>)?;
65+
let start_item = MenuItem::with_id(app, "start", "Включить обход", true, None::<&str>)?;
66+
let stop_item = MenuItem::with_id(app, "stop", "Выключить обход", true, None::<&str>)?;
67+
let quit_item = MenuItem::with_id(app, "quit", "Выход из программы", true, None::<&str>)?;
5468

5569
let tray_menu = Menu::with_items(
5670
app,
@@ -64,15 +78,16 @@ async fn main() {
6478

6579
let supervisor_tray = supervisor.clone();
6680

67-
let mut tray_builder = TrayIconBuilder::new()
68-
.menu(&tray_menu)
69-
.show_menu_on_left_click(false);
70-
71-
if let Some(icon) = app.default_window_icon().cloned() {
72-
tray_builder = tray_builder.icon(icon);
73-
}
81+
let icon = match app.default_window_icon().cloned() {
82+
Some(i) => i,
83+
None => tauri::image::Image::from_bytes(include_bytes!("../icons/32x32.png")).expect("Failed to load embedded tray icon"),
84+
};
7485

75-
let _tray = tray_builder
86+
let _tray = TrayIconBuilder::new()
87+
.menu(&tray_menu)
88+
.icon(icon)
89+
.tooltip("zapret2 — Обход блокировок активен")
90+
.show_menu_on_left_click(false)
7691
.on_menu_event(move |app_h, event| {
7792
match event.id.as_ref() {
7893
"toggle" => {
@@ -81,6 +96,7 @@ async fn main() {
8196
let _ = window.hide();
8297
} else {
8398
let _ = window.show();
99+
let _ = window.unminimize();
84100
let _ = window.set_focus();
85101
}
86102
}
@@ -109,21 +125,28 @@ async fn main() {
109125
}
110126
})
111127
.on_tray_icon_event(|tray, event| {
112-
if let TrayIconEvent::Click {
113-
button: MouseButton::Left,
114-
button_state: MouseButtonState::Up,
115-
..
116-
} = event
117-
{
118-
let app = tray.app_handle();
119-
if let Some(window) = app.get_webview_window("main") {
120-
if window.is_visible().unwrap_or(false) {
121-
let _ = window.hide();
122-
} else {
123-
let _ = window.show();
124-
let _ = window.set_focus();
128+
match event {
129+
TrayIconEvent::Click {
130+
button: MouseButton::Left,
131+
button_state: MouseButtonState::Up,
132+
..
133+
}
134+
| TrayIconEvent::DoubleClick {
135+
button: MouseButton::Left,
136+
..
137+
} => {
138+
let app = tray.app_handle();
139+
if let Some(window) = app.get_webview_window("main") {
140+
if window.is_visible().unwrap_or(false) {
141+
let _ = window.hide();
142+
} else {
143+
let _ = window.show();
144+
let _ = window.unminimize();
145+
let _ = window.set_focus();
146+
}
125147
}
126148
}
149+
_ => {}
127150
}
128151
})
129152
.build(app)?;
@@ -148,6 +171,7 @@ async fn main() {
148171
commands::parse_args_string,
149172
commands::get_autostart_status,
150173
commands::set_autostart_status,
174+
commands::exit_app,
151175
])
152176
.run(tauri::generate_context!())
153177
.expect("Error while running zapret2 Tauri supervisor application");

‎src-tauri/src/win32/autostart.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn set_autostart(enable: bool) -> Result<bool, String> {
5757
if enable {
5858
let exe_path = resolve_autostart_exe_path()?;
5959
let exe_str = exe_path.to_string_lossy().to_string();
60-
let task_run_arg = format!("\"{}\"", exe_str);
60+
let task_run_arg = format!("\"{}\" --minimized", exe_str);
6161

6262
let output = Command::new("schtasks.exe")
6363
.args([

0 commit comments

Comments
 (0)