Skip to content

Commit 809d0f1

Browse files
authored
macOS: handle app re-open (#905)
1 parent fc4ea04 commit 809d0f1

13 files changed

Lines changed: 281 additions & 247 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"@stablelib/base64": "^2.0.1",
4343
"@stablelib/x25519": "^2.0.1",
4444
"@tanstack/query-core": "^5.100.14",
45-
"@tanstack/react-virtual": "^3.13.25",
45+
"@tanstack/react-virtual": "^3.13.26",
4646
"@tauri-apps/api": "^2.11.0",
4747
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
4848
"@tauri-apps/plugin-deep-link": "^2.4.9",

pnpm-lock.yaml

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

src-tauri/.sqlx/query-1c996712f62a1005990733cd9eee7a94bdcf2ef01b559304aea1d642fab7ae22.json renamed to src-tauri/.sqlx/query-31e1b340bfbdf29dde642b657124a0705b638769ce6631c1b455cbf45e82bb14.json

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

src-tauri/.sqlx/query-3bedd8a0e3a8d4b76330ba0f81d82cf1590e6d15ba30360c41b0a5a3482df3df.json

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

src-tauri/.sqlx/query-f88f92313f52f0b2c584f48b40e6edb4bc14d96f3000bd58a3ca68eecb8e4a88.json renamed to src-tauri/.sqlx/query-97a52a8bbf020b77afe5dc427efb66abfdc6b571d1631a4f77fbf4fa5cfbe7e7.json

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

src-tauri/.sqlx/query-ba54bef9b71c2add858203b7be2c0e87d3a54d536ef96a923a6b949e16b9746e.json renamed to src-tauri/.sqlx/query-af70b9b18d8452a03d4d5624c2f3a11ab0d2e123989e97dfceb57e472523398c.json

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

src-tauri/.sqlx/query-49039d91cfdefbb32284d15af739a2090ba7baf9dee8cf00e8800b9a5f891fab.json renamed to src-tauri/.sqlx/query-c6a5e793cccc520039e28da8b4fb73e0c79c6a8d671c300ec2ea3eb0d58342b5.json

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

src-tauri/Cargo.lock

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

src-tauri/src/bin/defguard-client.rs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use defguard_client::{
3434
LOG_FILENAME, VERSION,
3535
};
3636
use log::{Level, LevelFilter};
37-
use tauri::{AppHandle, Builder, Manager, RunEvent, WindowEvent};
37+
use tauri::{async_runtime, AppHandle, Builder, Manager, RunEvent, WindowEvent};
3838
use tauri_plugin_deep_link::DeepLinkExt;
3939
use tauri_plugin_log::{Target, TargetKind};
4040

@@ -100,7 +100,7 @@ async fn startup(app_handle: &AppHandle) {
100100
.lock()
101101
.expect("failed to lock app state")
102102
.mtu();
103-
let handle = tauri::async_runtime::spawn(async move {
103+
let handle = async_runtime::spawn(async move {
104104
if let Err(err) = defguard_client::apple::sync_locations_and_tunnels(mtu).await {
105105
error!("Failed to sync locations and tunnels: {err}");
106106
}
@@ -122,7 +122,7 @@ async fn startup(app_handle: &AppHandle) {
122122
});
123123

124124
let handle = app_handle.clone();
125-
tauri::async_runtime::spawn(async move {
125+
async_runtime::spawn(async move {
126126
defguard_client::apple::connection_state_update_thread(&handle).await;
127127
error!("Connection state update thread has exited unexpectedly, quitting the app.");
128128
handle.exit(0);
@@ -131,7 +131,7 @@ async fn startup(app_handle: &AppHandle) {
131131

132132
// Run periodic tasks.
133133
let periodic_tasks_handle = app_handle.clone();
134-
tauri::async_runtime::spawn(async move {
134+
async_runtime::spawn(async move {
135135
run_periodic_tasks(&periodic_tasks_handle).await;
136136
// One of the tasks exited, so something went wrong, quit the app
137137
error!("One of the periodic tasks has stopped unexpectedly. Exiting the application.");
@@ -154,6 +154,17 @@ async fn startup(app_handle: &AppHandle) {
154154
debug!("Tray menu has been re-generated successfully.");
155155
}
156156

157+
/// Open the appropriate window, either the old or the new UI, depending if there are locations.
158+
#[cfg(not(target_os = "linux"))]
159+
fn open_appropriate_window(app_handle: &AppHandle) {
160+
let has_locations = async_runtime::block_on(has_non_service_locations());
161+
if has_locations {
162+
let _ = WindowManager::open_tray(app_handle);
163+
} else {
164+
let _ = WindowManager::open_full_view(app_handle);
165+
}
166+
}
167+
157168
fn main() {
158169
let app = Builder::default()
159170
.invoke_handler(tauri::generate_handler![
@@ -220,14 +231,7 @@ fn main() {
220231

221232
#[cfg(not(target_os = "linux"))]
222233
{
223-
let has_locations = tauri::async_runtime::block_on(
224-
defguard_client::window_manager::has_non_service_locations(),
225-
);
226-
if has_locations {
227-
let _ = WindowManager::open_tray(app);
228-
} else {
229-
let _ = WindowManager::open_full_view(app);
230-
}
234+
open_appropriate_window(app);
231235
}
232236
}
233237
}))
@@ -370,12 +374,12 @@ fn main() {
370374
)?;
371375

372376
// run DB migrations
373-
tauri::async_runtime::block_on(handle_db_migrations());
377+
async_runtime::block_on(handle_db_migrations());
374378

375379
// Check if client needs to be initialized
376380
// and try to load provisioning config if necessary
377381
let provisioning_config =
378-
tauri::async_runtime::block_on(handle_client_initialization(app_handle));
382+
async_runtime::block_on(handle_client_initialization(app_handle));
379383

380384
let state = AppState::new(config, provisioning_config);
381385
app.manage(state);
@@ -395,7 +399,8 @@ fn main() {
395399
}
396400
#[cfg(not(target_os = "linux"))]
397401
{
398-
// If the app was cold-launched by a deep link the full view must open, not the tray.
402+
// If the app was cold-launched by a deep-link, the full view must open, not the
403+
// tray.
399404
let launched_by_deep_link = app_handle
400405
.deep_link()
401406
.get_current()
@@ -406,15 +411,7 @@ fn main() {
406411
info!("App launched via deep link, opening full view directly.");
407412
let _ = WindowManager::open_full_view(app_handle);
408413
} else {
409-
let has_locations = tauri::async_runtime::block_on(
410-
defguard_client::window_manager::has_non_service_locations()
411-
);
412-
if has_locations {
413-
WindowManager::open_tray(app_handle)?;
414-
} else {
415-
info!("No locations found, showing full view on startup.");
416-
let _ = WindowManager::open_full_view(app_handle);
417-
}
414+
open_appropriate_window(app_handle);
418415
}
419416
}
420417

@@ -455,7 +452,7 @@ fn main() {
455452
log_dir.display(),
456453
service::config::DEFAULT_LOG_DIR
457454
);
458-
tauri::async_runtime::block_on(startup(app_handle));
455+
async_runtime::block_on(startup(app_handle));
459456

460457
// Handle a deep link that launched the app (startup case).
461458
if let Ok(Some(urls)) = app_handle.deep_link().get_current() {
@@ -465,7 +462,7 @@ fn main() {
465462
// Handle Ctrl-C.
466463
debug!("Setting up Ctrl-C handler.");
467464
let app_handle_clone = app_handle.clone();
468-
tauri::async_runtime::spawn(async move {
465+
async_runtime::spawn(async move {
469466
tokio::signal::ctrl_c()
470467
.await
471468
.expect("Signal handler failure");
@@ -490,7 +487,7 @@ fn main() {
490487
let semaphore = Arc::new(AtomicBool::new(false));
491488
let semaphore_clone = Arc::clone(&semaphore);
492489

493-
let handle = tauri::async_runtime::spawn(async move {
490+
let handle = async_runtime::spawn(async move {
494491
let _ = close_all_connections().await;
495492
// This will clean the database file, pruning write-ahead log.
496493
DB_POOL.close().await;
@@ -499,19 +496,28 @@ fn main() {
499496
// Obj-C API needs a runtime, but at this point Tauri has closed its runtime, so
500497
// create a temporary one.
501498
defguard_client::apple::spawn_runloop_and_wait_for(&semaphore);
502-
tauri::async_runtime::block_on(async move {
499+
async_runtime::block_on(async move {
503500
let _ = handle.await;
504501
});
505502
}
506503
#[cfg(not(target_os = "macos"))]
507504
{
508-
tauri::async_runtime::block_on(async move {
505+
async_runtime::block_on(async move {
509506
let _ = close_all_connections().await;
510507
// This will clean the database file, pruning write-ahead log.
511508
DB_POOL.close().await;
512509
});
513510
}
514511
}
512+
#[cfg(target_os = "macos")]
513+
RunEvent::Reopen {
514+
has_visible_windows,
515+
..
516+
} => {
517+
if !has_visible_windows {
518+
open_appropriate_window(app_handle);
519+
}
520+
}
515521
_ => {
516522
trace!("Received event: {event:?}");
517523
}

0 commit comments

Comments
 (0)