From 0eb6e7632bd4e698251efd3e5ae78a86527abae9 Mon Sep 17 00:00:00 2001 From: termux-pacman-bot Date: Tue, 27 Jan 2026 06:47:21 +0000 Subject: [PATCH] fix(main/yazi): force-enable `trash-rs` support on Android - Force-enable `trash-rs` and force the 'd' key to work to move files to `/data/data/com.termux/files/home/.local/share/Trash/files`, i.e. `$HOME/.local/share/Trash/files` - Since for some reason `libc::getmntent()` does not exist in Rust for Android, it is necessary to make a dirty implementation of a function within `trash-rs` that is otherwise unimplemented for Android by avoiding the use of `getmntent()`. This implementation is not a fully proper way to detect mount points on Android, but it is sufficient to allow sending files to Trash to work without failure. It assumes that `/data` is mounted (since without `/data`, Termux cannot be running anyway), which allows the Termux home folder Trash to work (`/data/data/com.termux/files/home/.local/share/Trash/files`), and also pretends that `/storage/emulated/0` is a mounted filesystem so that Trashing files from `/sdcard` or `/storage/emulated/0` sends them to the Android system Home folder Trash (since, unlike the case of the Termux home folder, `/storage/emulated` is the actual mountpoint, but that folder does not grant permission for users to write to even if the user has used `termux-setup-storage`, only `/storage/emulated/0` does) - Has has been tested and confirmed to work good enough to suceessfully move files to trash in `yazi` on Samsung Galaxy A70 SM-A705FN with LineageOS 20 Android 13 SELinux Enabled --- packages/yazi/build.sh | 31 ++++++++++++- packages/yazi/force-enable-trash.patch | 29 ++++++++++++ ...rs-implement-get_mount_points-android.diff | 45 +++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 packages/yazi/force-enable-trash.patch create mode 100644 packages/yazi/trash-rs-implement-get_mount_points-android.diff diff --git a/packages/yazi/build.sh b/packages/yazi/build.sh index e7d0330b69..7289a4eeb1 100644 --- a/packages/yazi/build.sh +++ b/packages/yazi/build.sh @@ -3,6 +3,7 @@ TERMUX_PKG_DESCRIPTION="Blazing fast terminal file manager written in Rust, base TERMUX_PKG_LICENSE="MIT" TERMUX_PKG_MAINTAINER="@termux" TERMUX_PKG_VERSION="26.1.22" +TERMUX_PKG_REVISION=1 TERMUX_PKG_SRCURL=https://github.com/sxyazi/yazi/archive/refs/tags/v${TERMUX_PKG_VERSION}.tar.gz TERMUX_PKG_SHA256=83b8a1bf166bfcb54b44b966fa3f34afa7c55584bf81d29275a1cdd99d1c9c4c TERMUX_PKG_BUILD_DEPENDS='aosp-libs, imagemagick' @@ -12,7 +13,29 @@ TERMUX_PKG_BUILD_IN_SRC=true termux_step_pre_configure() { termux_setup_rust - [[ "$TERMUX_ON_DEVICE_BUILD" == "false" ]] && termux_setup_proot + if [[ "$TERMUX_ON_DEVICE_BUILD" == "false" ]]; then + termux_setup_proot + fi + + cargo vendor + find ./vendor \ + -mindepth 1 -maxdepth 1 -type d \ + ! -wholename ./vendor/trash \ + -exec rm -rf '{}' \; + + find vendor/trash -type f -print0 | \ + xargs -0 sed -i \ + -e 's|"android"|"disabling_this_because_it_is_for_building_an_apk"|g' \ + -e "s|/tmp|$TERMUX_PREFIX/tmp|g" + + local patch="$TERMUX_PKG_BUILDER_DIR/trash-rs-implement-get_mount_points-android.diff" + local dir="vendor/trash" + echo "Applying patch: $patch" + patch -p1 -d "$dir" < "$patch" + + echo "" >> Cargo.toml + echo '[patch.crates-io]' >> Cargo.toml + echo 'trash = { path = "./vendor/trash" }' >> Cargo.toml } termux_step_make() { @@ -37,10 +60,14 @@ termux_step_make_install() { # application icons local res + local termux_proot_run='' + if [[ "$TERMUX_ON_DEVICE_BUILD" == "false" ]]; then + termux_proot_run=termux-proot-run + fi echo -n "Generating icons:" for res in 16 24 32 48 64 128 256; do mkdir -p "${TERMUX_PREFIX}/share/icons/hicolor/${res}x${res}/apps" - termux-proot-run magick assets/logo.png \ + $termux_proot_run magick assets/logo.png \ -resize "${res}x${res}" \ "${TERMUX_PREFIX}/share/icons/hicolor/${res}x${res}/apps/yazi.png" [[ -e "${TERMUX_PREFIX}/share/icons/hicolor/${res}x${res}/apps/yazi.png" ]] && { diff --git a/packages/yazi/force-enable-trash.patch b/packages/yazi/force-enable-trash.patch new file mode 100644 index 0000000000..9389c0a7bd --- /dev/null +++ b/packages/yazi/force-enable-trash.patch @@ -0,0 +1,29 @@ +--- a/yazi-fs/Cargo.toml ++++ b/yazi-fs/Cargo.toml +@@ -45,5 +45,5 @@ windows-sys = { version = "0.61.2", features = [ "Win32_Storage_FileSystem" ] } + core-foundation-sys = { workspace = true } + objc2 = { workspace = true } + +-[target.'cfg(not(target_os = "android"))'.dependencies] ++[target.'cfg(not(target_os = "disabling_this_because_it_is_for_building_an_apk"))'.dependencies] + trash = "5.2.5" +--- a/yazi-fs/src/provider/local/local.rs ++++ b/yazi-fs/src/provider/local/local.rs +@@ -189,7 +189,7 @@ impl<'a> Provider for Local<'a> { + async fn trash(&self) -> io::Result<()> { + let path = self.path.to_owned(); + tokio::task::spawn_blocking(move || { +- #[cfg(target_os = "android")] ++ #[cfg(target_os = "disabling_this_because_it_is_for_building_an_apk")] + { + Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported OS for trash operation")) + } +@@ -200,7 +200,7 @@ impl<'a> Provider for Local<'a> { + ctx.set_delete_method(DeleteMethod::NsFileManager); + ctx.delete(path).map_err(io::Error::other) + } +- #[cfg(all(not(target_os = "macos"), not(target_os = "android")))] ++ #[cfg(all(not(target_os = "macos"), not(target_os = "disabling_this_because_it_is_for_building_an_apk")))] + { + trash::delete(path).map_err(io::Error::other) + } diff --git a/packages/yazi/trash-rs-implement-get_mount_points-android.diff b/packages/yazi/trash-rs-implement-get_mount_points-android.diff new file mode 100644 index 0000000000..7f18c272b1 --- /dev/null +++ b/packages/yazi/trash-rs-implement-get_mount_points-android.diff @@ -0,0 +1,45 @@ +This dirty implementation of get_mount_points() for trash-rs for Android +has been tested and confirmed to work good enough to suceessfully move files to trash +in reverse dependency Yazi on Samsung Galaxy A70 SM-A705FN with LineageOS 20 Android 13 SELinux Enabled + +--- a/src/freedesktop.rs ++++ b/src/freedesktop.rs +@@ -784,6 +784,28 @@ fn get_mount_points() -> Result, Error> { + Ok(result) + } + ++#[cfg(target_os = "android")] ++fn get_mount_points() -> Result, Error> { ++ // assume '/data' and '/strorage/emulated/0' are mounted ++ // for some reason, 'getmntent()' is not available in Rust on Android, ++ // despite being available in C on Android. ++ // https://github.com/rust-lang/libc/blob/0403150379d66216e90a0f8a804ae1ca33691067/src/unix/linux_like/android/mod.rs ++ let mut result = Vec::new(); ++ let mount_point = MountPoint { ++ mnt_dir: "/data".into(), ++ _mnt_fsname: "/this/should/not/matter".to_string(), ++ _mnt_type: "ext4".to_string() ++ }; ++ result.push(mount_point); ++ let mount_point = MountPoint { ++ mnt_dir: "/storage/emulated/0".into(), ++ _mnt_fsname: "/this/should/not/matter".to_string(), ++ _mnt_type: "fuse".to_string() ++ }; ++ result.push(mount_point); ++ Ok(result) ++} ++ + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))] + fn get_mount_points() -> Result, Error> { + use once_cell::sync::Lazy; +@@ -898,7 +914,8 @@ fn get_mount_points() -> Result, Error> { + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", +- target_os = "netbsd" ++ target_os = "netbsd", ++ target_os = "android" + )))] + fn get_mount_points() -> Result, Error> { + // On platforms that don't have support yet, return an error