Fix race condition in tauri and window not navigating in release mode

This commit is contained in:
Patrick Pacher 2024-03-27 12:52:52 +01:00
parent 3c0a362bff
commit 347e2d1982
5 changed files with 50 additions and 18 deletions
desktop/tauri/src-tauri

View file

@ -38,7 +38,13 @@ struct WsHandler {
}
impl portmaster::Handler for WsHandler {
fn name(&self) -> String {
"main-handler".to_string()
}
fn on_connect(&mut self, cli: portapi::client::PortAPI) -> () {
info!("connection established, creating main window");
// we successfully connected to Portmaster. Set is_first_connect to false
// so we don't show the splash-screen when we loose connection.
self.is_first_connect = false;
@ -52,6 +58,8 @@ impl portmaster::Handler for WsHandler {
// bootstrapping.
if let Err(err) = create_main_window(&self.handle) {
error!("failed to create main window: {}", err.to_string());
} else {
debug!("created main window")
}
let handle = self.handle.clone();

View file

@ -31,7 +31,7 @@ use std::{
sync::atomic::{AtomicBool, Ordering},
};
use log::debug;
use log::{debug, error};
use serde;
use std::sync::Mutex;
use tauri::{
@ -42,6 +42,7 @@ use tauri::{
pub trait Handler {
fn on_connect(&mut self, cli: PortAPI) -> ();
fn on_disconnect(&mut self);
fn name(&self) -> String;
}
pub struct PortmasterPlugin<R: Runtime> {
@ -107,18 +108,24 @@ impl<R: Runtime> PortmasterPlugin<R> {
/// Registers a new connection handler that is called on connect
/// and disconnect of the Portmaster websocket API.
pub fn register_handler(&self, mut handler: impl Handler + Send + 'static) {
// register_handler can only be invoked after the plugin setup
// completed. in this case, the websocket thread is already spawned and
// we might already be connected or know that the connection failed.
// Call the respective handler method immediately now.
if let Some(api) = self.get_api() {
handler.on_connect(api);
} else {
handler.on_disconnect();
}
if let Ok(mut handlers) = self.handlers.lock() {
// register_handler can only be invoked after the plugin setup
// completed. in this case, the websocket thread is already spawned and
// we might already be connected or know that the connection failed.
// Call the respective handler method immediately now.
if let Some(api) = self.get_api() {
debug!("already connected to Portmaster API, calling on_connect()");
handler.on_connect(api);
} else {
debug!("not yet connected to Portmaster API, calling on_disconnect()");
handler.on_disconnect();
}
handlers.push(Box::new(handler));
debug!("number of registered handlers: {}", handlers.len());
}
}
@ -211,6 +218,8 @@ impl<R: Runtime> PortmasterPlugin<R> {
/// Internal method to call all on_connect handlers
fn on_connect(&self, api: PortAPI) {
debug!("connection to portmaster established, calling handlers");
self.is_reachable.store(true, Ordering::Relaxed);
// store the new api client.
@ -224,9 +233,14 @@ impl<R: Runtime> PortmasterPlugin<R> {
}
if let Ok(mut handlers) = self.handlers.lock() {
debug!("executing handler.on_connect()");
for handler in handlers.iter_mut() {
debug!("calling registered handler: {}", handler.name());
handler.on_connect(api.clone());
}
} else {
error!("failed to lock handlers")
}
}

View file

@ -129,7 +129,7 @@ pub fn may_navigate_to_ui(win: &mut Window, force: bool) {
return;
}
if force || cfg!(debug_assertions) || win.url().host_str() != Some("localhost") {
if force || cfg!(debug_assertions) || win.url().as_str() == "tauri://localhost" {
#[cfg(debug_assertions)]
if let Ok(target_url) = std::env::var("TAURI_PM_URL") {
debug!("[tauri] navigating to {}", target_url);
@ -147,5 +147,7 @@ pub fn may_navigate_to_ui(win: &mut Window, force: bool) {
#[cfg(not(debug_assertions))]
win.navigate("http://localhost:817".parse().unwrap());
} else {
error!("not navigating to user interface: current url: {}", win.url().as_str());
}
}

View file

@ -7,7 +7,7 @@ use gtk_sys::{
};
use log::{debug, error};
use std::collections::HashMap;
use std::ffi::c_int;
use std::ffi::{c_char, c_int};
use std::ffi::{CStr, CString};
use std::io;
use std::path::{Path, PathBuf};
@ -404,7 +404,7 @@ fn get_icon_as_png_dataurl(name: &str, size: i8) -> Result<(String, String)> {
let icon_info = gtk_icon_theme_lookup_icon(
GTK_DEFAULT_THEME.unwrap(),
c_str.as_ptr() as *const u8,
c_str.as_ptr() as *const c_char,
size as c_int,
0,
);

View file

@ -42,13 +42,21 @@
"bundle": {
"active": true,
"category": "Utility",
"copyright": "",
"copyright": "Safing Limited Inc",
"deb": {
"depends": []
"depends": [
"libayatana-appindicator3"
],
"desktopTemplate": "../../../packaging/linux/portmaster.desktop",
"files": {
"/usr/lib/systemd/system/portmaster.service": "../../../packaging/linux/portmaster.service",
"/etc/xdg/autostart/portmaster.service": "../../../packaging/linux/portmaster-autostart.desktop",
"/var/": "../../../packaging/linux/var"
}
},
"externalBin": [
"../binaries/portmaster-start",
"../binaries/portmaster-core"
"binaries/portmaster-start",
"binaries/portmaster-core"
],
"icon": [
"../assets/icons/pm_dark_512.png",