Skip to content

Commit 8e0aa65

Browse files
committed
feat(desktop): improve Flatpak download handling by opening file manager
- Implement `openInFileManager` to highlight downloaded files using D-Bus `org.freedesktop.FileManager1.ShowItems`, with a fallback to `xdg-open` on the parent directory. - Update Flatpak notification messages to be more concise, removing absolute file paths in favor of automatically opening the file manager. - Refactor package installation and AppImage handling to trigger the file manager focus after download. - Simplify the fallback case for unknown file types to notify the user and open the download location.
1 parent 43da234 commit 8e0aa65

1 file changed

Lines changed: 52 additions & 15 deletions

File tree

core/data/src/jvmMain/kotlin/zed/rainxch/core/data/services/DesktopInstaller.kt

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -499,24 +499,24 @@ class DesktopInstaller(
499499
Logger.w { "xdg-open exited with code $exitCode" }
500500
showFlatpakNotification(
501501
title = "Installation",
502-
message = "Downloaded to: ${file.absolutePath}\n" +
503-
"Please open this file with your software center to install.",
502+
message = "Please open this file with your software center to install.",
504503
)
504+
openInFileManager(file)
505505
}
506506
} catch (e: Exception) {
507507
Logger.w { "Failed to open file via xdg-open: ${e.message}" }
508508
showFlatpakNotification(
509509
title = "Download Complete",
510-
message = "Downloaded to: ${file.absolutePath}\n" +
511-
"Please install manually from your file manager.",
510+
message = "Please install manually from your file manager.",
512511
)
512+
openInFileManager(file)
513513
}
514514
}
515515

516516
"appimage" -> {
517517
// AppImages can't run inside Flatpak (no FUSE), and there's no point
518518
// moving them to ~/Applications from within the sandbox.
519-
// Instead, set executable and tell the user where to find it.
519+
// Instead, set executable and open the file manager so the user can find it.
520520
Logger.d { "AppImage downloaded in Flatpak — preparing for host launch" }
521521

522522
// Try to make it executable (may work if it's on a filesystem we can chmod)
@@ -529,23 +529,19 @@ class DesktopInstaller(
529529

530530
showFlatpakNotification(
531531
title = "AppImage Downloaded",
532-
message = "Downloaded to: ${file.absolutePath}\n" +
533-
"Right-click → Properties → mark as executable, then double-click to run.\n" +
534-
"Or run from terminal: chmod +x '${file.name}' && ./'${file.name}'",
532+
message = "Right-click → Properties → mark as executable, then double-click to run.",
535533
)
534+
535+
// Open the file manager highlighting the downloaded file
536+
openInFileManager(file)
536537
}
537538

538539
else -> {
539-
// Fallback: try xdg-open for any other type
540-
try {
541-
ProcessBuilder("xdg-open", file.absolutePath).start()
542-
} catch (e: Exception) {
543-
Logger.w { "Could not open file: ${e.message}" }
544-
}
545540
showFlatpakNotification(
546541
title = "Download Complete",
547-
message = "Downloaded to: ${file.absolutePath}",
542+
message = "File saved to your Downloads folder.",
548543
)
544+
openInFileManager(file)
549545
}
550546
}
551547
}
@@ -576,6 +572,47 @@ class DesktopInstaller(
576572
}
577573
}
578574

575+
/**
576+
* Opens the system file manager with the given file highlighted/selected.
577+
*
578+
* Tries D-Bus FileManager1.ShowItems first (works on GNOME, KDE, etc. and
579+
* goes through the Flatpak portal), then falls back to xdg-open on the
580+
* parent directory.
581+
*/
582+
private fun openInFileManager(file: File) {
583+
try {
584+
// D-Bus call to org.freedesktop.FileManager1.ShowItems — this highlights
585+
// the specific file in the file manager. Works via Flatpak portal.
586+
val fileUri = "file://${file.absolutePath}"
587+
val process = ProcessBuilder(
588+
"gdbus", "call",
589+
"--session",
590+
"--dest", "org.freedesktop.FileManager1",
591+
"--object-path", "/org/freedesktop/FileManager1",
592+
"--method", "org.freedesktop.FileManager1.ShowItems",
593+
"['$fileUri']", "",
594+
).start()
595+
val exitCode = process.waitFor()
596+
597+
if (exitCode == 0) {
598+
Logger.d { "Opened file manager via D-Bus ShowItems: ${file.absolutePath}" }
599+
return
600+
}
601+
Logger.w { "D-Bus ShowItems failed with exit code $exitCode" }
602+
} catch (e: Exception) {
603+
Logger.w { "D-Bus ShowItems not available: ${e.message}" }
604+
}
605+
606+
// Fallback: open the parent directory
607+
try {
608+
val parentDir = file.parentFile ?: return
609+
ProcessBuilder("xdg-open", parentDir.absolutePath).start()
610+
Logger.d { "Opened parent directory: ${parentDir.absolutePath}" }
611+
} catch (e: Exception) {
612+
Logger.w { "Could not open file manager: ${e.message}" }
613+
}
614+
}
615+
579616
private fun installWindows(
580617
file: File,
581618
ext: String,

0 commit comments

Comments
 (0)