feat(snippets): Use rdev by default, fallback to evdev on Wayland

This commit updates the snippet expansion feature to dynamically select an input manager based on the user's display server. It now checks for the `WAYLAND_DISPLAY` environment variable at startup to determine whether to use the `evdev` (for Wayland) or `rdev` (for X11) backend. This change significantly improves compatibility, allowing snippet expansion to function correctly on both major Linux display servers, whereas previously it was limited.
This commit is contained in:
ByteAtATime 2025-07-12 21:28:16 -07:00
parent 2c1542e2a4
commit 327584f905
No known key found for this signature in database
2 changed files with 34 additions and 13 deletions

View file

@ -17,7 +17,7 @@ mod soulver;
mod store;
mod system;
use crate::snippets::input_manager::{EvdevInputManager, InputManager};
use crate::snippets::input_manager::{EvdevInputManager, InputManager, RdevInputManager};
use crate::{app::App, cache::AppCache};
use ai::AiUsageManager;
use browser_extension::WsState;
@ -192,16 +192,34 @@ fn setup_input_listener(app: &tauri::AppHandle) {
let snippet_manager = app.state::<SnippetManager>().inner().clone();
let snippet_manager_arc = Arc::new(snippet_manager);
let input_manager = EvdevInputManager::new().unwrap();
let input_manager_arc: Arc<dyn InputManager> = Arc::new(input_manager);
app.manage(input_manager_arc.clone());
let is_wayland = std::env::var("WAYLAND_DISPLAY").is_ok();
let engine = ExpansionEngine::new(snippet_manager_arc, input_manager_arc);
thread::spawn(move || {
if let Err(e) = engine.start_listening() {
eprintln!("[ExpansionEngine] Failed to start: {}", e);
let input_manager_result: Result<Arc<dyn InputManager>, anyhow::Error> = if is_wayland {
println!("[Snippets] Wayland detected, using evdev for snippet expansion.");
EvdevInputManager::new().map(|m| Arc::new(m) as Arc<dyn InputManager>)
} else {
println!("[Snippets] X11 or unknown session, using rdev for snippet expansion.");
RdevInputManager::new().map(|m| Arc::new(m) as Arc<dyn InputManager>)
};
match input_manager_result {
Ok(input_manager) => {
app.manage(input_manager.clone());
let engine = ExpansionEngine::new(snippet_manager_arc, input_manager);
thread::spawn(move || {
if let Err(e) = engine.start_listening() {
eprintln!("[ExpansionEngine] Failed to start: {}", e);
}
});
}
});
Err(e) => {
eprintln!(
"[Snippets] Failed to initialize input manager: {}. Snippet expansion will be disabled.",
e
);
}
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]

View file

@ -75,10 +75,13 @@ pub struct RdevInputManager {
}
impl RdevInputManager {
pub fn new() -> Self {
Self {
enigo: Mutex::new(Enigo::new(&enigo::Settings::default()).unwrap()),
}
pub fn new() -> Result<Self> {
Ok(Self {
enigo: Mutex::new(
Enigo::new(&enigo::Settings::default())
.context("Failed to initialize enigo for rdev manager")?,
),
})
}
}