11use std:: {
2- cell:: RefCell ,
32 collections:: HashMap ,
43 env,
54 fmt:: Debug ,
65 fs:: { self , DirEntry } ,
76 io:: BufRead ,
87 path:: PathBuf ,
98 process:: Command ,
10- sync:: Arc ,
9+ sync:: { Arc , RwLock } ,
1110} ;
1211
1312use config:: { Config , get_config} ;
@@ -153,7 +152,7 @@ fn read_single_entry(
153152 if first_line != "[Desktop Entry]" && !first_line. starts_with ( "#" ) {
154153 return ;
155154 }
156- for line in iter. flatten ( ) {
155+ for line in iter. map_while ( Result :: ok ) {
157156 if line. starts_with ( "[Desktop Action" ) {
158157 break ;
159158 }
@@ -352,7 +351,11 @@ pub async fn to_oxiany_async(msg: Message) -> Arc<dyn OxiAny> {
352351}
353352
354353pub fn run_command ( command : & str ) {
355- let res = Command :: new ( "sh" ) . arg ( "-c" ) . arg ( command) . spawn ( ) ;
354+ let res = Command :: new ( "sh" )
355+ . arg ( "-c" )
356+ . arg ( format ! ( "nohup {command} >/dev/null 2>&1 &" ) )
357+ . spawn ( ) ;
358+
356359 if let Err ( error) = res {
357360 panic ! ( "Failed to spawn command: {error}" ) ;
358361 }
@@ -363,7 +366,7 @@ pub fn run_command(command: &str) {
363366pub extern "C" fn model (
364367 global_config : Table ,
365368) -> (
366- Arc < RefCell < & ' static mut dyn OxiAny > > ,
369+ Arc < RwLock < & ' static mut dyn OxiAny > > ,
367370 Option < Task < Arc < dyn OxiAny > > > ,
368371) {
369372 let model = Box :: leak ( Box :: new ( Model :: new ( global_config) ) ) ;
@@ -377,7 +380,7 @@ pub extern "C" fn model(
377380
378381 // TODO get config from main app perhaps? if so how? this should only take subkeys
379382 (
380- Arc :: new ( RefCell :: new ( model as & ' static mut dyn OxiAny ) ) ,
383+ Arc :: new ( RwLock :: new ( model as & ' static mut dyn OxiAny ) ) ,
381384 Some ( Task :: future ( to_oxiany_async ( entries) ) ) ,
382385 )
383386}
@@ -386,10 +389,10 @@ pub extern "C" fn model(
386389#[ allow( improper_ctypes_definitions) ]
387390pub extern "C" fn update (
388391 filter_text : String ,
389- model : Arc < RefCell < & ' static mut dyn OxiAny > > ,
392+ model : Arc < RwLock < & ' static mut dyn OxiAny > > ,
390393 msg : Arc < & ' static mut dyn OxiAny > ,
391394) -> Option < Task < Arc < dyn OxiAny > > > {
392- let mut model_borrow = model. borrow_mut ( ) ;
395+ let mut model_borrow = model. try_write ( ) . ok ( ) ? ;
393396 let model = model_borrow. downcast_mut :: < Model > ( ) ?;
394397 let msg_opt = msg. downcast_ref :: < Message > ( ) ;
395398 if msg_opt. is_none ( ) {
@@ -420,9 +423,9 @@ pub extern "C" fn update(
420423#[ allow( improper_ctypes_definitions) ]
421424pub extern "C" fn sort (
422425 filter_text : String ,
423- model : Arc < RefCell < & ' static mut dyn OxiAny > > ,
426+ model : Arc < RwLock < & ' static mut dyn OxiAny > > ,
424427) -> Option < Task < Arc < dyn OxiAny > > > {
425- let mut model_borrow = model. borrow_mut ( ) ;
428+ let mut model_borrow = model. try_write ( ) . ok ( ) ? ;
426429 let model = model_borrow. downcast_mut :: < Model > ( ) ?;
427430 let applications = model. applications . clone ( ) ;
428431 Some ( Task :: future ( to_oxiany_async ( sort_appliations (
@@ -436,46 +439,57 @@ pub extern "C" fn sort(
436439#[ allow( improper_ctypes_definitions) ]
437440pub extern "C" fn launch (
438441 focused_index : usize ,
439- model : Arc < RefCell < & ' static mut dyn OxiAny > > ,
442+ model : Arc < RwLock < & ' static mut dyn OxiAny > > ,
440443) -> Option < Task < & ' static dyn OxiAny > > {
441- let mut model_borrow = model. borrow_mut ( ) ;
442- let model = model_borrow. downcast_mut :: < Model > ( ) ?;
443- let exec_opt = & model. sorted_applications . get ( focused_index) ;
444- if exec_opt. is_none ( ) {
445- model. errors . push ( "Could not get entry for index" . into ( ) ) ;
446- return None ;
444+ let lock = model. try_write ( ) ;
445+ if let Ok ( mut model_borrow) = lock {
446+ let model_opt = model_borrow. downcast_mut :: < Model > ( ) ;
447+ if let Some ( model) = model_opt {
448+ let exec_opt = & model. sorted_applications . get ( focused_index) ;
449+ if exec_opt. is_none ( ) {
450+ model. errors . push ( "Could not get entry for index" . into ( ) ) ;
451+ return None ;
452+ }
453+ let exec = & exec_opt. unwrap ( ) . entry . exec ;
454+ run_command ( exec) ;
455+ }
447456 }
448- let exec = & exec_opt. unwrap ( ) . entry . exec ;
449- run_command ( exec) ;
450457 None
451458}
452459
453460#[ unsafe( no_mangle) ]
454461#[ allow( improper_ctypes_definitions) ]
455462pub extern "C" fn view (
456- model : Arc < RefCell < & ' static mut dyn OxiAny > > ,
463+ model : Arc < RwLock < & ' static mut dyn OxiAny > > ,
457464) -> Result < Vec < ( i64 , Element < ' static , Arc < dyn OxiAny > > ) > , std:: io:: Error > {
458- let model_borrow = model. borrow ( ) ;
459- let model = model_borrow
460- . downcast_ref :: < Model > ( )
461- . ok_or ( std:: io:: Error :: new (
465+ let lock = model. try_read ( ) ;
466+ if let Ok ( model_borrow) = lock {
467+ let model = model_borrow
468+ . downcast_ref :: < Model > ( )
469+ . ok_or ( std:: io:: Error :: new (
470+ std:: io:: ErrorKind :: InvalidInput ,
471+ "Could not get model in view" ,
472+ ) ) ?;
473+ let entries: Vec < ( i64 , Element < Arc < dyn OxiAny > > ) > = model
474+ . sorted_applications
475+ . clone ( )
476+ . into_iter ( )
477+ . take ( model. config . max_entries )
478+ . map ( |scored_entry| {
479+ (
480+ scored_entry. score ,
481+ Into :: < Element < Message > > :: into ( create_entry_card ( scored_entry. entry ) )
482+ . map ( to_oxiany_rc) ,
483+ )
484+ } )
485+ . collect :: < Vec < _ > > ( ) ;
486+ Ok ( entries)
487+ } else {
488+ Err ( std:: io:: Error :: new (
462489 std:: io:: ErrorKind :: InvalidInput ,
463490 "Could not get model in view" ,
464- ) ) ?;
465- let entries: Vec < ( i64 , Element < Arc < dyn OxiAny > > ) > = model
466- . sorted_applications
467- . clone ( )
468- . into_iter ( )
469- . take ( model. config . max_entries )
470- . map ( |scored_entry| {
471- (
472- scored_entry. score ,
473- Into :: < Element < Message > > :: into ( create_entry_card ( scored_entry. entry ) )
474- . map ( to_oxiany_rc) ,
475- )
476- } )
477- . collect :: < Vec < _ > > ( ) ;
478- Ok ( entries)
491+ ) )
492+ }
479493}
480494
481495#[ unsafe( no_mangle) ]
@@ -486,23 +500,31 @@ pub extern "C" fn name() -> &'static str {
486500
487501#[ unsafe( no_mangle) ]
488502#[ allow( improper_ctypes_definitions) ]
489- pub extern "C" fn errors ( model : Arc < RefCell < & ' static mut dyn OxiAny > > ) -> Vec < String > {
490- let model_borrow = model. borrow ( ) ;
491- let model_opt = model_borrow. downcast_ref :: < Model > ( ) ;
492- if let Some ( model) = model_opt {
493- model. errors . clone ( )
503+ pub extern "C" fn errors ( model : Arc < RwLock < & ' static mut dyn OxiAny > > ) -> Vec < String > {
504+ let lock = model. try_read ( ) ;
505+ if let Ok ( model_borrow) = lock {
506+ let model_opt = model_borrow. downcast_ref :: < Model > ( ) ;
507+ if let Some ( model) = model_opt {
508+ model. errors . clone ( )
509+ } else {
510+ vec ! [ String :: from( "Could not get model while fetching errors" ) ]
511+ }
494512 } else {
495513 vec ! [ String :: from( "Could not get model while fetching errors" ) ]
496514 }
497515}
498516
499517#[ unsafe( no_mangle) ]
500518#[ allow( improper_ctypes_definitions) ]
501- pub extern "C" fn count ( model : Arc < RefCell < & ' static mut dyn OxiAny > > ) -> usize {
502- let model_borrow = model. borrow ( ) ;
503- let model_opt = model_borrow. downcast_ref :: < Model > ( ) ;
504- if let Some ( model) = model_opt {
505- usize:: min ( model. sorted_applications . len ( ) , model. config . max_entries )
519+ pub extern "C" fn count ( model : Arc < RwLock < & ' static mut dyn OxiAny > > ) -> usize {
520+ let lock = model. try_read ( ) ;
521+ if let Ok ( model_borrow) = lock {
522+ let model_opt = model_borrow. downcast_ref :: < Model > ( ) ;
523+ if let Some ( model) = model_opt {
524+ usize:: min ( model. sorted_applications . len ( ) , model. config . max_entries )
525+ } else {
526+ 0
527+ }
506528 } else {
507529 0
508530 }
0 commit comments