mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
[desktop] Add support for system theme detection
This commit is contained in:
parent
5b03076fac
commit
a6e1a37239
6 changed files with 159 additions and 20 deletions
92
desktop/tauri/src-tauri/Cargo.lock
generated
92
desktop/tauri/src-tauri/Cargo.lock
generated
|
@ -210,6 +210,7 @@ dependencies = [
|
|||
"assert_matches",
|
||||
"cached",
|
||||
"ctor",
|
||||
"dark-light",
|
||||
"dataurl",
|
||||
"dirs 1.0.5",
|
||||
"futures-util",
|
||||
|
@ -227,7 +228,7 @@ dependencies = [
|
|||
"open",
|
||||
"reqwest 0.12.5",
|
||||
"rfd",
|
||||
"rust-ini",
|
||||
"rust-ini 0.20.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha",
|
||||
|
@ -1634,6 +1635,22 @@ dependencies = [
|
|||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dark-light"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c"
|
||||
dependencies = [
|
||||
"dconf_rs",
|
||||
"detect-desktop-environment",
|
||||
"dirs 4.0.0",
|
||||
"objc",
|
||||
"rust-ini 0.18.0",
|
||||
"web-sys",
|
||||
"winreg 0.10.1",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
|
@ -1744,6 +1761,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dconf_rs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.9"
|
||||
|
@ -1818,6 +1841,12 @@ dependencies = [
|
|||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "detect-desktop-environment"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810"
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "1.6.0"
|
||||
|
@ -1869,13 +1898,22 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
"dirs-sys 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1888,6 +1926,17 @@ dependencies = [
|
|||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users 0.4.5",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
|
@ -1940,6 +1989,12 @@ dependencies = [
|
|||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlv-list"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
|
||||
|
||||
[[package]]
|
||||
name = "dlv-list"
|
||||
version = "0.5.2"
|
||||
|
@ -4821,13 +4876,23 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
|
||||
dependencies = [
|
||||
"dlv-list 0.3.0",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
|
||||
dependencies = [
|
||||
"dlv-list",
|
||||
"dlv-list 0.5.2",
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
|
@ -6124,6 +6189,16 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"ordered-multimap 0.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.20.0"
|
||||
|
@ -6131,7 +6206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"ordered-multimap",
|
||||
"ordered-multimap 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -9416,6 +9491,15 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
|
|
|
@ -53,6 +53,8 @@ reqwest = { version = "0.12" }
|
|||
rfd = { version = "*", default-features = false, features = [ "tokio", "gtk3", "common-controls-v6" ] }
|
||||
open = "5.1.3"
|
||||
|
||||
dark-light = "1.1.1"
|
||||
|
||||
# Linux only
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
glib = "0.18.4"
|
||||
|
|
|
@ -20,7 +20,6 @@ mod window;
|
|||
|
||||
use log::{debug, error, info};
|
||||
use portmaster::PortmasterExt;
|
||||
use tauri_plugin_window_state::{AppHandleExt, StateFlags, WindowExt};
|
||||
use traymenu::setup_tray_menu;
|
||||
use window::{close_splash_window, create_main_window};
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ pub trait ServiceManager {
|
|||
fn start(&self) -> Result<StatusResult>;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct EmptyServiceManager();
|
||||
|
||||
impl ServiceManager for EmptyServiceManager {
|
||||
|
|
|
@ -41,12 +41,56 @@ lazy_static! {
|
|||
const PM_TRAY_ICON_ID: &'static str = "pm_icon";
|
||||
|
||||
// Icons
|
||||
const BLUE_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_blue.ico");
|
||||
const RED_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_red.ico");
|
||||
const YELLOW_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_yellow.ico");
|
||||
const GREEN_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_green.ico");
|
||||
|
||||
fn get_green_icon() -> &'static [u8] {
|
||||
const LIGHT_GREEN_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_green.ico");
|
||||
const DARK_GREEN_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_dark_green.ico");
|
||||
|
||||
let mode = dark_light::detect();
|
||||
match mode {
|
||||
dark_light::Mode::Light => DARK_GREEN_ICON,
|
||||
_ => LIGHT_GREEN_ICON,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_blue_icon() -> &'static [u8] {
|
||||
const LIGHT_BLUE_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_blue.ico");
|
||||
const DARK_BLUE_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_dark_blue.ico");
|
||||
let mode = dark_light::detect();
|
||||
match mode {
|
||||
dark_light::Mode::Light => DARK_BLUE_ICON,
|
||||
_ => LIGHT_BLUE_ICON,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_red_icon() -> &'static [u8] {
|
||||
const LIGHT_RED_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_red.ico");
|
||||
const DARK_RED_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_dark_red.ico");
|
||||
let mode = dark_light::detect();
|
||||
match mode {
|
||||
dark_light::Mode::Light => DARK_RED_ICON,
|
||||
_ => LIGHT_RED_ICON,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_yellow_icon() -> &'static [u8] {
|
||||
const LIGHT_YELLOW_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_yellow.ico");
|
||||
|
||||
const DARK_YELLOW_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_dark_yellow.ico");
|
||||
let mode = dark_light::detect();
|
||||
match mode {
|
||||
dark_light::Mode::Light => DARK_YELLOW_ICON,
|
||||
_ => LIGHT_YELLOW_ICON,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_tray_menu(
|
||||
app: &mut tauri::App,
|
||||
|
@ -105,7 +149,7 @@ pub fn setup_tray_menu(
|
|||
.build()?;
|
||||
|
||||
let icon = TrayIconBuilder::with_id(PM_TRAY_ICON_ID)
|
||||
.icon(Image::from_bytes(RED_ICON).unwrap())
|
||||
.icon(Image::from_bytes(get_red_icon()).unwrap())
|
||||
.menu(&menu)
|
||||
.on_menu_event(move |app, event| match event.id().as_ref() {
|
||||
"exit_ui" => {
|
||||
|
@ -205,11 +249,11 @@ pub fn update_icon(icon: AppIcon, subsystems: HashMap<String, Subsystem>, spn_st
|
|||
}
|
||||
|
||||
let next_icon = match failure.0 {
|
||||
subsystem::FAILURE_WARNING => YELLOW_ICON,
|
||||
subsystem::FAILURE_ERROR => RED_ICON,
|
||||
subsystem::FAILURE_WARNING => get_yellow_icon(),
|
||||
subsystem::FAILURE_ERROR => get_red_icon(),
|
||||
_ => match spn_status.as_str() {
|
||||
"connected" | "connecting" => BLUE_ICON,
|
||||
_ => GREEN_ICON,
|
||||
"connected" | "connecting" => get_blue_icon(),
|
||||
_ => get_green_icon(),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -289,7 +333,7 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) {
|
|||
}
|
||||
};
|
||||
|
||||
_ = icon.set_icon(Some(Image::from_bytes(BLUE_ICON).unwrap()));
|
||||
_ = icon.set_icon(Some(Image::from_bytes(get_blue_icon()).unwrap()));
|
||||
|
||||
let mut subsystems: HashMap<String, Subsystem> = HashMap::new();
|
||||
let mut spn_status: String = "".to_string();
|
||||
|
@ -407,7 +451,7 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) {
|
|||
}
|
||||
|
||||
update_spn_ui_state(false);
|
||||
_ = icon.set_icon(Some(Image::from_bytes(RED_ICON).unwrap()));
|
||||
_ = icon.set_icon(Some(Image::from_bytes(get_red_icon()).unwrap()));
|
||||
}
|
||||
|
||||
fn update_spn_ui_state(enabled: bool) {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
use log::{debug, error};
|
||||
use tauri::{
|
||||
AppHandle, Listener, Manager, Result, Theme, UserAttentionType, WebviewUrl, WebviewWindow,
|
||||
WebviewWindowBuilder,
|
||||
image::Image, AppHandle, Listener, Manager, Result, Theme, UserAttentionType, WebviewUrl,
|
||||
WebviewWindow, WebviewWindowBuilder,
|
||||
};
|
||||
|
||||
use crate::portmaster::PortmasterExt;
|
||||
|
||||
const LIGHT_PM_ICON: &'static [u8] =
|
||||
include_bytes!("../../../../assets/data/icons/pm_light_512.png");
|
||||
const DARK_PM_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_512.png");
|
||||
|
||||
/// Either returns the existing "main" window or creates a new one.
|
||||
///
|
||||
/// The window is not automatically shown (i.e it starts hidden).
|
||||
|
@ -47,6 +51,11 @@ pub fn create_main_window(app: &AppHandle) -> Result<WebviewWindow> {
|
|||
// If the window is not yet navigated to the Portmaster UI, do it now.
|
||||
may_navigate_to_ui(&mut window, false);
|
||||
|
||||
let _ = match dark_light::detect() {
|
||||
dark_light::Mode::Light => window.set_icon(Image::from_bytes(DARK_PM_ICON).unwrap()),
|
||||
_ => window.set_icon(Image::from_bytes(LIGHT_PM_ICON).unwrap()),
|
||||
};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if let Ok(_) = std::env::var("TAURI_SHOW_IMMEDIATELY") {
|
||||
debug!("[tauri] TAURI_SHOW_IMMEDIATELY is set, opening window");
|
||||
|
|
Loading…
Add table
Reference in a new issue