fix(review): bugs, arch violations, design smells
P1 bugs: - unix_launcher: shell_split respects quoted args (was split_whitespace) - plugin-host: 5s timeout on external plugin search - ui: handle engine init panic, wire error state - ui-egui: read window config instead of always using defaults - plugin-url: use OpenPath action instead of SpawnProcess+xdg-open Architecture: - remove WindowConfig (mirror of WindowCfg); use WindowCfg directly - remove on_select closure from SearchResult (domain leakage) - remove LaunchAction::Custom; add Plugin::on_selected + SearchEngine::on_selected - apps: record frecency via on_selected instead of embedded closure Design smells: - frecency: extract decay_factor helper, write outside mutex - apps: remove cfg(test) cache_path hack; add new_for_test ctor - apps: stable ResultId using name+exec to prevent collision - files: stable ResultId using full path instead of index - plugin-host: remove k-launcher-os-bridge dep (WindowConfig gone)
This commit is contained in:
@@ -9,7 +9,6 @@ use iced::{
|
||||
|
||||
use k_launcher_config::AppearanceCfg;
|
||||
use k_launcher_kernel::{AppLauncher, NullSearchEngine, SearchEngine, SearchResult};
|
||||
use k_launcher_os_bridge::WindowConfig;
|
||||
|
||||
static INPUT_ID: std::sync::LazyLock<iced::widget::Id> =
|
||||
std::sync::LazyLock::new(|| iced::widget::Id::new("search"));
|
||||
@@ -63,6 +62,7 @@ pub enum Message {
|
||||
ResultsReady(u64, Arc<Vec<SearchResult>>),
|
||||
KeyPressed(KeyEvent),
|
||||
EngineReady(EngineHandle),
|
||||
EngineInitFailed(String),
|
||||
}
|
||||
|
||||
fn update(state: &mut KLauncherApp, message: Message) -> Task<Message> {
|
||||
@@ -88,6 +88,10 @@ fn update(state: &mut KLauncherApp, message: Message) -> Task<Message> {
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::EngineInitFailed(msg) => {
|
||||
state.error = Some(msg);
|
||||
Task::none()
|
||||
}
|
||||
Message::EngineReady(handle) => {
|
||||
state.engine = handle.0;
|
||||
if !state.query.is_empty() {
|
||||
@@ -121,9 +125,7 @@ fn update(state: &mut KLauncherApp, message: Message) -> Task<Message> {
|
||||
}
|
||||
Named::Enter => {
|
||||
if let Some(result) = state.results.get(state.selected) {
|
||||
if let Some(on_select) = &result.on_select {
|
||||
on_select();
|
||||
}
|
||||
state.engine.on_selected(&result.id);
|
||||
state.launcher.execute(&result.action);
|
||||
}
|
||||
std::process::exit(0);
|
||||
@@ -277,7 +279,6 @@ pub fn run(
|
||||
window_cfg: &k_launcher_config::WindowCfg,
|
||||
appearance_cfg: AppearanceCfg,
|
||||
) -> iced::Result {
|
||||
let wc = WindowConfig::from_cfg(window_cfg);
|
||||
iced::application(
|
||||
move || {
|
||||
let app = KLauncherApp::new(
|
||||
@@ -288,8 +289,15 @@ pub fn run(
|
||||
let focus = iced::widget::operation::focus(INPUT_ID.clone());
|
||||
let ef = engine_factory.clone();
|
||||
let init = Task::perform(
|
||||
async move { tokio::task::spawn_blocking(move || ef()).await.unwrap() },
|
||||
|e| Message::EngineReady(EngineHandle(e)),
|
||||
async move {
|
||||
tokio::task::spawn_blocking(move || ef())
|
||||
.await
|
||||
.map_err(|e| format!("Engine init failed: {e}"))
|
||||
},
|
||||
|result| match result {
|
||||
Ok(e) => Message::EngineReady(EngineHandle(e)),
|
||||
Err(msg) => Message::EngineInitFailed(msg),
|
||||
},
|
||||
);
|
||||
(app, Task::batch([focus, init]))
|
||||
},
|
||||
@@ -299,11 +307,11 @@ pub fn run(
|
||||
.title("K-Launcher")
|
||||
.subscription(subscription)
|
||||
.window(window::Settings {
|
||||
size: Size::new(wc.width, wc.height),
|
||||
size: Size::new(window_cfg.width, window_cfg.height),
|
||||
position: window::Position::Centered,
|
||||
decorations: wc.decorations,
|
||||
transparent: wc.transparent,
|
||||
resizable: wc.resizable,
|
||||
decorations: window_cfg.decorations,
|
||||
transparent: window_cfg.transparent,
|
||||
resizable: window_cfg.resizable,
|
||||
..Default::default()
|
||||
})
|
||||
.run()
|
||||
|
||||
Reference in New Issue
Block a user