From 6eca8617ff05596163e759d5e0ace2b8f964efff Mon Sep 17 00:00:00 2001 From: Alfin Aloshi Date: Thu, 23 Apr 2026 07:35:28 +0530 Subject: [PATCH 1/2] fix(interface): prevent middle-click forward-navigation on Windows (#3008) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WebView2 enters autoscroll mode on middle-mousedown. After navigating forward then back, a second middle-click exits scroll mode via the browser forward-navigation gesture instead, causing unintended routing. Gate to Tauri+Windows only. Prevent default on button-1 mousedown with {passive: false} — disables WebView2 autoscroll mode, which is not useful in a file manager. Fixes #3008 --- packages/interface/src/ShellLayout.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/interface/src/ShellLayout.tsx b/packages/interface/src/ShellLayout.tsx index 702a47620aad..eab22f28c585 100644 --- a/packages/interface/src/ShellLayout.tsx +++ b/packages/interface/src/ShellLayout.tsx @@ -90,6 +90,17 @@ function ShellLayoutContent() { return null; }, [params.locationId, locationsQuery.data, currentPath]); + useEffect(() => { + if (platform.platform !== 'tauri' || !navigator.userAgent.includes('Windows')) return; + // Prevent WebView2 (Windows) from entering autoscroll mode on middle-click, + // which causes forward-navigation after browser history traversal (#3008). + const preventMiddleClickScroll = (e: MouseEvent) => { + if (e.button === 1) e.preventDefault(); + }; + document.addEventListener('mousedown', preventMiddleClickScroll, {passive: false}); + return () => document.removeEventListener('mousedown', preventMiddleClickScroll); + }, [platform.platform]); + useEffect(() => { // Listen for inspector window close events if (!platform.onWindowEvent) return; From 50ea0b793efb44e1d1466a4bca37dfed9ba7d42c Mon Sep 17 00:00:00 2001 From: Alfin Aloshi Date: Thu, 23 Apr 2026 07:35:41 +0530 Subject: [PATCH 2/2] chore(archive): remove unused imports and silence unused variable warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleans up 15 compiler warnings in sd-archive: Unused imports removed: - std::pin::Pin (script.rs) - RelationsDef (db.rs) - ConfigField, AdapterUpdateResult (engine.rs — used via full path) - HashMap, Error, Result, FieldType, ModelDef (migration.rs) - FtsHit (search/router.rs) - EMBEDDING_DIM (search/vector.rs) - Path (source.rs — only PathBuf used) Unused variables silenced: - _stderr in script.rs (stderr handle intentionally discarded) - _after/_before in db.rs (presence checked via is_some later) - date_field binding replaced with .is_some() check in db.rs - name: _ in source.rs AddTable match arm --- crates/archive/src/adapter/script.rs | 8 +++++++- crates/archive/src/db.rs | 16 ++++++++-------- crates/archive/src/engine.rs | 4 ++-- crates/archive/src/schema/migration.rs | 5 +---- crates/archive/src/search/router.rs | 2 +- crates/archive/src/search/vector.rs | 1 - crates/archive/src/source.rs | 4 ++-- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/crates/archive/src/adapter/script.rs b/crates/archive/src/adapter/script.rs index ee6f1c1d70d3..00acfeae88fc 100644 --- a/crates/archive/src/adapter/script.rs +++ b/crates/archive/src/adapter/script.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use std::future::Future; use std::path::{Path, PathBuf}; -use std::pin::Pin; use std::time::Instant; use serde::{Deserialize, Serialize}; @@ -481,6 +480,13 @@ impl Adapter for ScriptAdapter { .stderr .take() .ok_or_else(|| Error::AdapterSync("failed to open stderr".into()))?; + // Best-effort: drain stderr so the child can't block on a full pipe. + tokio::spawn(async move { + let mut err_reader = BufReader::new(stderr).lines(); + while let Ok(Some(line)) = err_reader.next_line().await { + tracing::warn!(line = %line, "adapter stderr"); + } + }); let config_json = serde_json::to_string(config) .map_err(|e| Error::AdapterSync(format!("failed to serialize config: {e}")))?; diff --git a/crates/archive/src/db.rs b/crates/archive/src/db.rs index e8eb8f9d6982..1f07edef6780 100644 --- a/crates/archive/src/db.rs +++ b/crates/archive/src/db.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use crate::error::{Error, Result}; -use crate::schema::{DataTypeSchema, RelationsDef}; +use crate::schema::DataTypeSchema; fn pluralize(name: &str) -> String { format!("{name}s") @@ -572,10 +572,10 @@ impl SourceDb { if let Some(ref temp) = temporal { if let Some(date_field) = &self.schema.search.date_field { - if let Some(after) = temp.date_after { + if let Some(_after) = temp.date_after { sql.push_str(&format!(" AND t.\"{}\" >= ?", date_field)); } - if let Some(before) = temp.date_before { + if let Some(_before) = temp.date_before { sql.push_str(&format!(" AND t.\"{}\" <= ?", date_field)); } } @@ -586,12 +586,12 @@ impl SourceDb { let mut q = sqlx::query_as::<_, FtsHitRow>(&sql).bind(query); if let Some(ref temp) = temporal { - if let Some(date_field) = &self.schema.search.date_field { - if temp.date_after.is_some() { - q = q.bind(temp.date_after.unwrap()); + if self.schema.search.date_field.is_some() { + if let Some(after) = temp.date_after { + q = q.bind(after); } - if temp.date_before.is_some() { - q = q.bind(temp.date_before.unwrap()); + if let Some(before) = temp.date_before { + q = q.bind(before); } } } diff --git a/crates/archive/src/engine.rs b/crates/archive/src/engine.rs index 986f68dd1a94..c4d44e3cdd1e 100644 --- a/crates/archive/src/engine.rs +++ b/crates/archive/src/engine.rs @@ -6,8 +6,8 @@ use std::path::PathBuf; use std::sync::Arc; -use crate::adapter::script::{ConfigField, ScriptAdapter}; -use crate::adapter::{Adapter, AdapterRegistry, AdapterUpdateResult, SyncReport}; +use crate::adapter::script::ScriptAdapter; +use crate::adapter::{Adapter, AdapterRegistry, SyncReport}; use crate::embed::EmbeddingModel; use crate::error::{Error, Result}; use crate::registry::{NewSource, Registry, SourceInfo}; diff --git a/crates/archive/src/schema/migration.rs b/crates/archive/src/schema/migration.rs index f534e816577d..c50d61a76a91 100644 --- a/crates/archive/src/schema/migration.rs +++ b/crates/archive/src/schema/migration.rs @@ -1,9 +1,6 @@ //! Schema migration: detect changes, apply safe migrations, refuse destructive ones. -use std::collections::HashMap; - -use crate::error::{Error, Result}; -use crate::schema::{DataTypeSchema, FieldType, ModelDef}; +use crate::schema::DataTypeSchema; /// Result of a schema migration attempt. #[derive(Debug, Clone)] diff --git a/crates/archive/src/search/router.rs b/crates/archive/src/search/router.rs index 74eef30368ef..8757cec149f1 100644 --- a/crates/archive/src/search/router.rs +++ b/crates/archive/src/search/router.rs @@ -5,7 +5,7 @@ use std::sync::Arc; -use crate::db::{FtsHit, TemporalFilter}; +use crate::db::TemporalFilter; use crate::embed::EmbeddingModel; use crate::error::Result; use crate::registry::Registry; diff --git a/crates/archive/src/search/vector.rs b/crates/archive/src/search/vector.rs index 1dac6d13a0d3..91801e22140b 100644 --- a/crates/archive/src/search/vector.rs +++ b/crates/archive/src/search/vector.rs @@ -5,7 +5,6 @@ use std::path::Path; -use crate::embed::EMBEDDING_DIM; use crate::error::Result; /// Stub vector store (does nothing). diff --git a/crates/archive/src/source.rs b/crates/archive/src/source.rs index 9ebb65364861..3a9db2f2bcc2 100644 --- a/crates/archive/src/source.rs +++ b/crates/archive/src/source.rs @@ -1,6 +1,6 @@ //! SourceManager: manages source folders and their databases. -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use crate::db::SourceDb; use crate::error::{Error, Result}; @@ -106,7 +106,7 @@ impl SourceManager { // Apply safe migrations for action in &migration_result.applied { match action { - crate::schema::migration::MigrationAction::AddTable { name } => { + crate::schema::migration::MigrationAction::AddTable { name: _ } => { // Regenerate full DDL — SQLite doesn't support CREATE TABLE IF NOT EXISTS // for adding new tables, so we run the full DDL and let it no-op for existing tables let ddl = generate_ddl(current_schema);