@@ -8,7 +8,6 @@ pub use mime_guess::Mime;
88use rustc_hash:: FxHashMap ;
99use std:: {
1010 cmp:: Ordering ,
11- env,
1211 ffi:: OsStr ,
1312 fs, io,
1413 path:: { Path , PathBuf } ,
@@ -280,107 +279,62 @@ impl MimeAppCache {
280279 }
281280 }
282281
283- let desktops: Vec < String > = env:: var ( "XDG_CURRENT_DESKTOP" )
284- . unwrap_or_default ( )
285- . split ( ':' )
286- . map ( str:: to_ascii_lowercase)
287- . collect ( ) ;
288-
289- // Load mimeapps.list files
290- // https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html
291- //TODO: ensure correct lookup order
292- let mut mimeapps_paths = Vec :: new ( ) ;
293- let xdg_dirs = xdg:: BaseDirectories :: new ( ) ;
294-
295- mimeapps_paths. extend ( xdg_dirs. find_data_files ( "applications/mimeapps.list" ) ) ;
296-
297- for desktop in desktops. iter ( ) . rev ( ) {
298- mimeapps_paths
299- . extend ( xdg_dirs. find_data_files ( format ! ( "applications/{desktop}-mimeapps.list" ) ) ) ;
300- }
301-
302- mimeapps_paths. extend ( xdg_dirs. find_config_files ( "mimeapps.list" ) ) ;
303-
304- for desktop in desktops. iter ( ) . rev ( ) {
305- mimeapps_paths. extend ( xdg_dirs. find_config_files ( format ! ( "{desktop}-mimeapps.list" ) ) ) ;
306- }
282+ let mut list = cosmic_mime_apps:: List :: default ( ) ;
307283
308- //TODO: handle directory specific behavior
309- for path in mimeapps_paths {
310- let entry = match freedesktop_entry_parser:: parse_entry ( & path) {
311- Ok ( ok) => ok,
312- Err ( err) => {
313- log:: warn!( "failed to parse {}: {}" , path. display( ) , err) ;
314- continue ;
315- }
316- } ;
284+ let paths = cosmic_mime_apps:: list_paths ( ) ;
285+ list. load_from_paths ( & paths) ;
317286
318- for attr in entry
319- . section ( "Added Associations" )
320- . attrs ( )
321- . chain ( entry. section ( "Default Applications" ) . attrs ( ) )
322- {
323- if let Ok ( mime) = attr. name . parse :: < Mime > ( ) {
324- if let Some ( filenames) = attr. value {
325- for filename in filenames. split_terminator ( ';' ) {
326- log:: trace!( "add {mime}={filename}" ) ;
327- let apps = self
328- . cache
329- . entry ( mime. clone ( ) )
330- . or_insert_with ( || Vec :: with_capacity ( 1 ) ) ;
331- if !apps. iter ( ) . any ( |x| filename_eq ( & x. path , filename) ) {
332- if let Some ( app) =
333- all_apps. iter ( ) . find ( |& x| filename_eq ( & x. path , filename) )
334- {
335- apps. push ( MimeApp :: from ( app) ) ;
336- } else {
337- log:: info!(
338- "failed to add association for {mime:?}: application {filename:?} not found"
339- ) ;
340- }
341- }
342- }
287+ for ( mime, filenames) in list
288+ . added_associations
289+ . iter ( )
290+ . chain ( list. default_apps . iter ( ) )
291+ {
292+ for filename in filenames {
293+ log:: trace!( "add {mime}={filename}" ) ;
294+ let apps = self
295+ . cache
296+ . entry ( mime. clone ( ) )
297+ . or_insert_with ( || Vec :: with_capacity ( 1 ) ) ;
298+ if !apps. iter ( ) . any ( |x| filename_eq ( & x. path , filename) ) {
299+ if let Some ( app) = all_apps. iter ( ) . find ( |& x| filename_eq ( & x. path , filename) ) {
300+ apps. push ( MimeApp :: from ( app) ) ;
301+ } else {
302+ log:: info!(
303+ "failed to add association for {mime:?}: application {filename:?} not found"
304+ ) ;
343305 }
344306 }
345307 }
308+ }
346309
347- for attr in entry. section ( "Removed Associations" ) . attrs ( ) {
348- if let Ok ( mime) = attr. name . parse :: < Mime > ( ) {
349- if let Some ( filenames) = attr. value {
350- for filename in filenames. split_terminator ( ';' ) {
351- log:: trace!( "remove {mime}={filename}" ) ;
352- if let Some ( apps) = self . cache . get_mut ( & mime) {
353- apps. retain ( |x| !filename_eq ( & x. path , filename) ) ;
354- }
355- }
356- }
310+ for ( mime, filenames) in list. removed_associations . iter ( ) {
311+ for filename in filenames {
312+ log:: trace!( "remove {mime}={filename}" ) ;
313+ if let Some ( apps) = self . cache . get_mut ( & mime) {
314+ apps. retain ( |x| !filename_eq ( & x. path , filename) ) ;
357315 }
358316 }
317+ }
359318
360- for attr in entry. section ( "Default Applications" ) . attrs ( ) {
361- if let Ok ( mime) = attr. name . parse :: < Mime > ( ) {
362- if let Some ( filenames) = attr. value {
363- for filename in filenames. split_terminator ( ';' ) {
364- log:: trace!( "default {mime}={filename}" ) ;
365- if let Some ( apps) = self . cache . get_mut ( & mime) {
366- let mut found = false ;
367- for app in apps. iter_mut ( ) {
368- if filename_eq ( & app. path , filename) {
369- app. is_default = true ;
370- found = true ;
371- } else {
372- app. is_default = false ;
373- }
374- }
375- if found {
376- break ;
377- }
378- log:: debug!(
379- "failed to set default for {mime:?}: application {filename:?} not found"
380- ) ;
381- }
319+ for ( mime, filenames) in list. default_apps . iter ( ) {
320+ for filename in filenames {
321+ log:: trace!( "default {mime}={filename}" ) ;
322+ if let Some ( apps) = self . cache . get_mut ( & mime) {
323+ let mut found = false ;
324+ for app in apps. iter_mut ( ) {
325+ if filename_eq ( & app. path , filename) {
326+ app. is_default = true ;
327+ found = true ;
328+ } else {
329+ app. is_default = false ;
382330 }
383331 }
332+ if found {
333+ break ;
334+ }
335+ log:: debug!(
336+ "failed to set default for {mime:?}: application {filename:?} not found"
337+ ) ;
384338 }
385339 }
386340 }
0 commit comments