Merge pull request #1468 from safing/fix/tauri-race-condition

Fix race condition in tauri and window not navigating in release mode
This commit is contained in:
Patrick Pacher 2024-03-27 13:58:47 +01:00 committed by GitHub
commit 43bcd79299
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 50 additions and 18 deletions

View file

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

View file

@ -31,7 +31,7 @@ use std::{
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
use log::debug; use log::{debug, error};
use serde; use serde;
use std::sync::Mutex; use std::sync::Mutex;
use tauri::{ use tauri::{
@ -42,6 +42,7 @@ use tauri::{
pub trait Handler { pub trait Handler {
fn on_connect(&mut self, cli: PortAPI) -> (); fn on_connect(&mut self, cli: PortAPI) -> ();
fn on_disconnect(&mut self); fn on_disconnect(&mut self);
fn name(&self) -> String;
} }
pub struct PortmasterPlugin<R: Runtime> { pub struct PortmasterPlugin<R: Runtime> {
@ -107,18 +108,24 @@ impl<R: Runtime> PortmasterPlugin<R> {
/// Registers a new connection handler that is called on connect /// Registers a new connection handler that is called on connect
/// and disconnect of the Portmaster websocket API. /// and disconnect of the Portmaster websocket API.
pub fn register_handler(&self, mut handler: impl Handler + Send + 'static) { 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() { 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)); 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 /// Internal method to call all on_connect handlers
fn on_connect(&self, api: PortAPI) { fn on_connect(&self, api: PortAPI) {
debug!("connection to portmaster established, calling handlers");
self.is_reachable.store(true, Ordering::Relaxed); self.is_reachable.store(true, Ordering::Relaxed);
// store the new api client. // store the new api client.
@ -224,9 +233,14 @@ impl<R: Runtime> PortmasterPlugin<R> {
} }
if let Ok(mut handlers) = self.handlers.lock() { if let Ok(mut handlers) = self.handlers.lock() {
debug!("executing handler.on_connect()");
for handler in handlers.iter_mut() { for handler in handlers.iter_mut() {
debug!("calling registered handler: {}", handler.name());
handler.on_connect(api.clone()); 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; 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)] #[cfg(debug_assertions)]
if let Ok(target_url) = std::env::var("TAURI_PM_URL") { if let Ok(target_url) = std::env::var("TAURI_PM_URL") {
debug!("[tauri] navigating to {}", target_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))] #[cfg(not(debug_assertions))]
win.navigate("http://localhost:817".parse().unwrap()); 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 log::{debug, error};
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::c_int; use std::ffi::{c_char, c_int};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::io; use std::io;
use std::path::{Path, PathBuf}; 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( let icon_info = gtk_icon_theme_lookup_icon(
GTK_DEFAULT_THEME.unwrap(), GTK_DEFAULT_THEME.unwrap(),
c_str.as_ptr() as *const u8, c_str.as_ptr() as *const c_char,
size as c_int, size as c_int,
0, 0,
); );

View file

@ -42,13 +42,21 @@
"bundle": { "bundle": {
"active": true, "active": true,
"category": "Utility", "category": "Utility",
"copyright": "", "copyright": "Safing Limited Inc",
"deb": { "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.desktop": "../../../packaging/linux/portmaster-autostart.desktop",
"/var/": "../../../packaging/linux/var"
}
}, },
"externalBin": [ "externalBin": [
"../binaries/portmaster-start", "binaries/portmaster-start",
"../binaries/portmaster-core" "binaries/portmaster-core"
], ],
"icon": [ "icon": [
"../assets/icons/pm_dark_512.png", "../assets/icons/pm_dark_512.png",