gardesk/garfield / a2a6ddf

Browse files

app: add opened files to system recents

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
a2a6ddf0087e3e4046a7e3e1a5be7cc9f2b3daf1
Parents
14dc68e
Tree
8e06699

1 changed file

StatusFile+-
M garfield/src/app.rs 84 3
garfield/src/app.rsmodified
@@ -2603,7 +2603,14 @@ impl App {
26032603
         };
26042604
 
26052605
         match std::process::Command::new(&app_cmd).arg(&path).spawn() {
2606
-            Ok(_) => self.status_bar.set_status_message(format!("Opened with {}", app_cmd)),
2606
+            Ok(_) => {
2607
+                self.status_bar.set_status_message(format!("Opened with {}", app_cmd));
2608
+                // Add to recently used files
2609
+                let mime_type = guess_mime_type(&path);
2610
+                if let Err(e) = self.recents.add_entry(&path, &mime_type) {
2611
+                    tracing::warn!("Failed to add to recents: {}", e);
2612
+                }
2613
+            }
26072614
             Err(e) => self.status_bar.set_status_message(format!("Failed to open with {}: {}", app_cmd, e)),
26082615
         }
26092616
     }
@@ -2611,7 +2618,14 @@ impl App {
26112618
     /// Open file with the system's default application (xdg-open).
26122619
     fn open_file_with_default(&mut self, path: &PathBuf) {
26132620
         match std::process::Command::new("xdg-open").arg(path).spawn() {
2614
-            Ok(_) => self.status_bar.set_status_message(format!("Opened {}", path.file_name().unwrap_or_default().to_string_lossy())),
2621
+            Ok(_) => {
2622
+                self.status_bar.set_status_message(format!("Opened {}", path.file_name().unwrap_or_default().to_string_lossy()));
2623
+                // Add to recently used files
2624
+                let mime_type = guess_mime_type(path);
2625
+                if let Err(e) = self.recents.add_entry(path, &mime_type) {
2626
+                    tracing::warn!("Failed to add to recents: {}", e);
2627
+                }
2628
+            }
26152629
             Err(e) => self.status_bar.set_status_message(format!("Failed to open: {}", e)),
26162630
         }
26172631
     }
@@ -2628,7 +2642,14 @@ impl App {
26282642
         }
26292643
 
26302644
         match std::process::Command::new(app_name).arg(&path).spawn() {
2631
-            Ok(_) => self.status_bar.set_status_message(format!("Opened with {}", app_name)),
2645
+            Ok(_) => {
2646
+                self.status_bar.set_status_message(format!("Opened with {}", app_name));
2647
+                // Add to recently used files
2648
+                let mime_type = guess_mime_type(&path);
2649
+                if let Err(e) = self.recents.add_entry(&path, &mime_type) {
2650
+                    tracing::warn!("Failed to add to recents: {}", e);
2651
+                }
2652
+            }
26322653
             Err(e) => self.status_bar.set_status_message(format!("Failed to open with {}: {}", app_name, e)),
26332654
         }
26342655
     }
@@ -3579,3 +3600,63 @@ impl Drop for App {
35793600
         let _ = self.window.connection().inner().free_gc(self.gc);
35803601
     }
35813602
 }
3603
+
3604
+/// Guess MIME type from file extension.
3605
+fn guess_mime_type(path: &std::path::Path) -> String {
3606
+    let ext = path.extension()
3607
+        .and_then(|e| e.to_str())
3608
+        .map(|e| e.to_lowercase())
3609
+        .unwrap_or_default();
3610
+
3611
+    match ext.as_str() {
3612
+        // Images
3613
+        "png" => "image/png",
3614
+        "jpg" | "jpeg" => "image/jpeg",
3615
+        "gif" => "image/gif",
3616
+        "webp" => "image/webp",
3617
+        "svg" => "image/svg+xml",
3618
+        "bmp" => "image/bmp",
3619
+        "ico" => "image/x-icon",
3620
+        // Documents
3621
+        "pdf" => "application/pdf",
3622
+        "txt" => "text/plain",
3623
+        "md" => "text/markdown",
3624
+        "html" | "htm" => "text/html",
3625
+        "css" => "text/css",
3626
+        "js" => "text/javascript",
3627
+        "json" => "application/json",
3628
+        "xml" => "application/xml",
3629
+        // Code
3630
+        "rs" => "text/x-rust",
3631
+        "py" => "text/x-python",
3632
+        "c" | "h" => "text/x-c",
3633
+        "cpp" | "hpp" | "cc" => "text/x-c++",
3634
+        "java" => "text/x-java",
3635
+        "go" => "text/x-go",
3636
+        "lua" => "text/x-lua",
3637
+        "sh" | "bash" => "application/x-shellscript",
3638
+        "toml" => "application/toml",
3639
+        "yaml" | "yml" => "application/x-yaml",
3640
+        // Archives
3641
+        "zip" => "application/zip",
3642
+        "tar" => "application/x-tar",
3643
+        "gz" | "gzip" => "application/gzip",
3644
+        "xz" => "application/x-xz",
3645
+        "7z" => "application/x-7z-compressed",
3646
+        "rar" => "application/vnd.rar",
3647
+        // Audio
3648
+        "mp3" => "audio/mpeg",
3649
+        "wav" => "audio/wav",
3650
+        "flac" => "audio/flac",
3651
+        "ogg" => "audio/ogg",
3652
+        "m4a" => "audio/mp4",
3653
+        // Video
3654
+        "mp4" => "video/mp4",
3655
+        "mkv" => "video/x-matroska",
3656
+        "avi" => "video/x-msvideo",
3657
+        "webm" => "video/webm",
3658
+        "mov" => "video/quicktime",
3659
+        // Fallback
3660
+        _ => "application/octet-stream",
3661
+    }.to_string()
3662
+}