Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "whatrust"
version = "0.3.2"
version = "0.3.3"
edition = "2021"
rust-version = "1.82"

Expand Down
16 changes: 12 additions & 4 deletions src-tauri/src/aumid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,22 @@ mod win {
pub fn register(aumid: &str, display_name: &str) {
// Step 1 — the registry entry is what makes the Action Center render
// the toast for an unpackaged desktop app.
if let Err(e) = write_registry(aumid, display_name) {
eprintln!("[whatrust] AUMID registry registration failed: {e:?}");
match write_registry(aumid, display_name) {
Ok(()) => crate::dlog::log(&format!(
"aumid: HKCU\\Software\\Classes\\AppUserModelId\\{aumid} registered"
)),
Err(e) => crate::dlog::log(&format!("aumid: registry registration FAILED: {e:?}")),
}
// Step 2 — pin this process to the AUMID (taskbar grouping + toast
// attribution). Harmless if it fails; we just log.
let id = wide(aumid);
if let Err(e) = unsafe { SetCurrentProcessExplicitAppUserModelID(PCWSTR(id.as_ptr())) } {
eprintln!("[whatrust] SetCurrentProcessExplicitAppUserModelID failed: {e:?}");
match unsafe { SetCurrentProcessExplicitAppUserModelID(PCWSTR(id.as_ptr())) } {
Ok(()) => crate::dlog::log(&format!(
"aumid: SetCurrentProcessExplicitAppUserModelID({aumid}) ok"
)),
Err(e) => crate::dlog::log(&format!(
"aumid: SetCurrentProcessExplicitAppUserModelID FAILED: {e:?}"
)),
}
}

Expand Down
8 changes: 8 additions & 0 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@ fn is_remote_label(label: &str) -> bool {

#[tauri::command]
pub fn notify(window: tauri::Window, app: tauri::AppHandle, title: String, body: String) {
// issue #3 diagnostics: confirm the command is actually reached from the
// injected bridge. If this line never appears in the log when a message
// arrives, the page never called our Notification shim (e.g. it used the
// service-worker showNotification path), not the OS toast layer. No message
// content is logged (PII) — only that an event occurred.
crate::dlog::log("commands::notify invoked");
// While locked, suppress notifications entirely so message previews don't leak
// to the OS notification center / lock screen. The tray unread badge still updates
// via set_unread (a count only, no content).
if !crate::lock::is_unlocked(&app) {
crate::dlog::log("commands::notify suppressed: app is locked");
return;
}
if !crate::settings::load(&app).notifications {
crate::dlog::log("commands::notify suppressed: notifications disabled in settings");
return;
}
// Prefix the account name when more than one account exists, so notifications
Expand Down
54 changes: 54 additions & 0 deletions src-tauri/src/dlog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Minimal diagnostic log to a file under the app-data dir, so failures are
//! visible even on a Windows GUI-subsystem build (which has no attached
//! console — `eprintln!` goes nowhere there). Added for issue #3 (Windows
//! toast notifications not appearing).
//!
//! - Windows: `%LOCALAPPDATA%\whatRust\logs\whatrust.log`
//! - Linux: `$XDG_DATA_HOME/whatRust/logs/whatrust.log` (or `~/.local/share/...`)
//!
//! Truncated once per launch via [`init`], appended thereafter, so it stays
//! bounded to a single session. Best-effort: never panics. It records control
//! flow and error codes only — never message titles or bodies (no PII).

use std::io::Write;
use std::path::PathBuf;
use std::sync::Mutex;

/// Serializes writes across the per-account notification threads.
static LOCK: Mutex<()> = Mutex::new(());

fn log_path() -> Option<PathBuf> {
#[cfg(windows)]
let base: Option<PathBuf> = std::env::var_os("LOCALAPPDATA").map(PathBuf::from);
#[cfg(not(windows))]
let base: Option<PathBuf> = std::env::var_os("XDG_DATA_HOME")
.map(PathBuf::from)
.or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".local/share")));

let dir = base?.join("whatRust").join("logs");
std::fs::create_dir_all(&dir).ok()?;
Some(dir.join("whatrust.log"))
}

/// Start a fresh log for this launch (truncate). Best-effort.
pub fn init() {
if let Some(p) = log_path() {
let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
let _ = std::fs::File::create(&p);
}
log("=== session start ===");
}

/// Append one line. Best-effort: silently does nothing if the path or write
/// fails, and never panics (mutex poison is recovered).
pub fn log(msg: &str) {
let Some(p) = log_path() else { return };
let ts = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open(&p) {
let _ = writeln!(f, "[{ts}] {msg}");
}
}
6 changes: 6 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod tray;
mod commands;
mod notify;
mod aumid;
mod dlog;

use tauri::Manager;

Expand Down Expand Up @@ -94,6 +95,11 @@ pub fn run() {
.setup(|app| {
let handle = app.handle();

// Start a fresh diagnostic log for this launch (issue #3): the only
// way to see notification failures on a Windows GUI build with no
// console. See dlog.rs.
dlog::init();

// Windows: register our AppUserModelID so WinRT toast notifications
// actually render for the installed app (no-op elsewhere). Must run
// before any account window can fire a notification. See aumid.rs.
Expand Down
15 changes: 9 additions & 6 deletions src-tauri/src/notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use tauri::AppHandle;
use tauri_plugin_notification::NotificationExt;

pub fn show(app: &AppHandle, title: &str, body: &str) {
// Don't silently swallow failures: on Windows a toast can fail (e.g. an
// unregistered AppUserModelID — see aumid.rs) and the only signal is this
// Result. Logging it makes such failures diagnosable from the console.
if let Err(e) = app.notification().builder().title(title).body(body).show() {
eprintln!("[whatrust] failed to show notification: {e:?}");
}
// NOTE: tauri-plugin-notification's `show()` dispatches the real toast on a
// detached async task and discards its result, so the value returned here is
// effectively always Ok — it does NOT reflect whether the OS actually
// rendered the toast. We still log that this point was reached (issue #3
// diagnostics): if "notify::show dispatched" appears in the log but no toast
// shows, the failure is downstream in the Windows toast layer, not in our
// command/IPC path. No message content is logged (PII).
let r = app.notification().builder().title(title).body(body).show();
crate::dlog::log(&format!("notify::show dispatched (plugin returned {r:?})"));
}
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "whatRust",
"version": "0.3.2",
"version": "0.3.3",
"identifier": "com.karem.whatrust",
"build": {
"frontendDist": "../settings-ui"
Expand Down
Loading