diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 6c0dae1..fff8a4d 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -48,7 +48,7 @@ jobs: with: key: ${{ matrix.os }}-${{ matrix.rust-target }} - if: ${{ matrix.os == 'ubuntu-20.04' }} - run: sudo apt-get update && sudo apt-get install -y gcc libxcb-composite0-dev + run: sudo apt-get update && sudo apt-get install -y gcc libxcb-composite0-dev libgtk-3-dev - run: cargo build --release - if: ${{ matrix.tar }} run: | @@ -80,7 +80,7 @@ jobs: with: key: ${{ matrix.os }} - if: ${{ matrix.os == 'ubuntu-latest' }} - run: sudo apt-get update && sudo apt-get install -y gcc libxcb-composite0-dev + run: sudo apt-get update && sudo apt-get install -y gcc libxcb-composite0-dev libgtk-3-dev - if: ${{ matrix.os == 'windows-latest' }} run: reg import tests/ludusavi.reg - if: ${{ matrix.os == 'windows-latest' }} @@ -106,5 +106,7 @@ jobs: - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.os }} + - if: ${{ matrix.os == 'ubuntu-latest' }} + run: sudo apt-get update && sudo apt-get install -y gcc libxcb-composite0-dev libgtk-3-dev - run: cargo fmt --all -- --check - run: cargo clippy --workspace -- --deny warnings diff --git a/CHANGELOG.md b/CHANGELOG.md index 786e659..7b8c6ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ * Changed: * Windows registry backups are now saved as `*.reg` files instead of `*.yaml`. Existing backups will not be affected. + * Dialogs (folder picker and `wrap --gui` prompts) now use GTK on Linux. + The previous system relied on Zenity/KDialog, + which could behave poorly depending on the version or in a Flatpak context. * Fixed: * The registry format change also resolved an issue where very large (> 100 MB) `registry.yaml` files could be slow to read and consume a lot of extra memory, diff --git a/Cargo.lock b/Cargo.lock index 7286c3a..29ba6ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,6 +223,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "atk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -464,6 +476,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "calloop" version = "0.13.0" @@ -507,6 +529,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -639,36 +671,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "cocoa" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation 0.9.4", - "core-graphics 0.22.3", - "foreign-types 0.3.2", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "libc", - "objc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -780,19 +782,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "core-graphics" version = "0.23.2" @@ -802,7 +791,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -815,7 +804,7 @@ dependencies = [ "bitflags 2.6.0", "core-foundation 0.10.0", "core-graphics-types 0.2.0", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -962,12 +951,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f791803201ab277ace03903de1594460708d2d54df6053f2d9e82f592b19e3b" -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "cursor-icon" version = "1.1.0" @@ -1044,16 +1027,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.4.1" @@ -1066,17 +1039,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -1365,15 +1327,6 @@ dependencies = [ "ttf-parser 0.20.0", ] -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -1381,7 +1334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1395,12 +1348,6 @@ dependencies = [ "syn 2.0.79", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1521,6 +1468,36 @@ dependencies = [ "thread_local", ] +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1558,6 +1535,19 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -1575,6 +1565,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "globetter" version = "0.2.0" @@ -1615,6 +1615,17 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "gpu-alloc" version = "0.6.0" @@ -1667,6 +1678,24 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "guillotiere" version = "0.6.2" @@ -1972,7 +2001,7 @@ dependencies = [ "iced_futures", "log", "once_cell", - "raw-window-handle 0.6.2", + "raw-window-handle", "rustc-hash 2.0.0", "thiserror", "unicode-segmentation", @@ -2000,7 +2029,7 @@ dependencies = [ "bytes", "iced_core", "iced_futures", - "raw-window-handle 0.6.2", + "raw-window-handle", "thiserror", ] @@ -2438,7 +2467,6 @@ dependencies = [ "itertools", "known-folders", "log", - "native-dialog", "once_cell", "opener", "pretty_assertions", @@ -2446,6 +2474,7 @@ dependencies = [ "regashii", "regex", "reqwest", + "rfd", "rusqlite", "schemars", "semver", @@ -2461,7 +2490,7 @@ dependencies = [ "unic-langid", "velcro", "walkdir", - "which 6.0.3", + "which", "whoami", "windows 0.58.0", "winreg 0.52.0", @@ -2502,7 +2531,7 @@ dependencies = [ "bitflags 2.6.0", "block", "core-graphics-types 0.1.3", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", @@ -2562,26 +2591,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "native-dialog" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab637f328b31bd0855c43bd38a4a4455e74324d9e74e0aac6a803422f43abc6" -dependencies = [ - "block", - "cocoa", - "dirs-next", - "objc", - "objc-foundation", - "objc_id", - "once_cell", - "raw-window-handle 0.4.3", - "thiserror", - "wfd", - "which 4.4.2", - "winapi", -] - [[package]] name = "ndk" version = "0.9.0" @@ -2593,7 +2602,7 @@ dependencies = [ "log", "ndk-sys 0.6.0+11769913", "num_enum", - "raw-window-handle 0.6.2", + "raw-window-handle", "thiserror", ] @@ -2711,17 +2720,6 @@ dependencies = [ "objc_exception", ] -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -2934,15 +2932,6 @@ dependencies = [ "cc", ] -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - [[package]] name = "object" version = "0.36.5" @@ -3018,6 +3007,18 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -3472,15 +3473,6 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" version = "0.6.2" @@ -3656,6 +3648,28 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "rfd" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af382a047821a08aa6bfc09ab0d80ff48d45d8726f7cd8e44891f7cb4a4278e" +dependencies = [ + "block2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.48.0", +] + [[package]] name = "ring" version = "0.17.8" @@ -3962,6 +3976,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4158,14 +4181,14 @@ dependencies = [ "core-graphics 0.24.0", "drm", "fastrand", - "foreign-types 0.5.0", + "foreign-types", "js-sys", "log", "memmap2", "objc2", "objc2-foundation", "objc2-quartz-core", - "raw-window-handle 0.6.2", + "raw-window-handle", "redox_syscall 0.5.7", "rustix", "tiny-xlib", @@ -4300,12 +4323,31 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml 0.8.19", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.13.0" @@ -4510,11 +4552,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -4523,6 +4580,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.6.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -4782,6 +4841,12 @@ dependencies = [ "velcro_core", ] +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -5039,16 +5104,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "wfd" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e713040b67aae5bf1a0ae3e1ebba8cc29ab2b90da9aa1bff6e09031a8a41d7a8" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "wgpu" version = "0.19.4" @@ -5063,7 +5118,7 @@ dependencies = [ "naga", "parking_lot 0.12.3", "profiling", - "raw-window-handle 0.6.2", + "raw-window-handle", "smallvec", "static_assertions", "wasm-bindgen", @@ -5091,7 +5146,7 @@ dependencies = [ "once_cell", "parking_lot 0.12.3", "profiling", - "raw-window-handle 0.6.2", + "raw-window-handle", "rustc-hash 1.1.0", "smallvec", "thiserror", @@ -5134,7 +5189,7 @@ dependencies = [ "parking_lot 0.12.3", "profiling", "range-alloc", - "raw-window-handle 0.6.2", + "raw-window-handle", "renderdoc-sys", "rustc-hash 1.1.0", "smallvec", @@ -5156,18 +5211,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "which" version = "6.0.3" @@ -5238,7 +5281,7 @@ dependencies = [ "clipboard_macos", "clipboard_wayland", "clipboard_x11", - "raw-window-handle 0.6.2", + "raw-window-handle", "thiserror", ] @@ -5580,7 +5623,7 @@ dependencies = [ "orbclient", "percent-encoding", "pin-project", - "raw-window-handle 0.6.2", + "raw-window-handle", "redox_syscall 0.4.1", "rustix", "sctk-adwaita", @@ -5637,7 +5680,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 62e26db..8107cc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,13 +28,13 @@ indicatif = { version = "0.17.8", features = ["rayon"] } intl-memoizer = "0.5.2" itertools = "0.13.0" log = "0.4.22" -native-dialog = "=0.6.3" # https://github.com/native-dialog-rs/native-dialog-rs/issues/41#issuecomment-2048336796 once_cell = "1.19.0" opener = "0.7.2" rayon = "1.10.0" regashii = "0.2.0" regex = "1.10.6" reqwest = { version = "0.12.7", features = ["blocking", "gzip", "rustls-tls"], default-features = false } +rfd = { version = "0.15.0", features = ["gtk3"], default-features = false } rusqlite = { version = "0.32.1", features = ["bundled"] } schemars = { version = "0.8.21", features = ["chrono"] } semver = { version = "1.0.23", features = ["serde"] } diff --git a/assets/windows-manifest.xml b/assets/windows-manifest.xml new file mode 100644 index 0000000..7bf6881 --- /dev/null +++ b/assets/windows-manifest.xml @@ -0,0 +1,9 @@ + + + + true/pm + permonitorv2 + true + + + diff --git a/build.rs b/build.rs index d732d89..b7e3411 100644 --- a/build.rs +++ b/build.rs @@ -1,11 +1,13 @@ fn main() { println!("cargo:rerun-if-env-changed=LUDUSAVI_VERSION"); println!("cargo:rerun-if-env-changed=LUDUSAVI_VARIANT"); + println!("cargo:rerun-if-changed=assets/windows-manifest.xml"); #[cfg(windows)] { let mut res = winres::WindowsResource::new(); res.set_icon("assets/icon.ico"); + res.set_manifest_file("assets/windows-manifest.xml"); res.compile().unwrap(); } } diff --git a/src/cli/ui.rs b/src/cli/ui.rs index 5a092d4..bdbf58e 100644 --- a/src/cli/ui.rs +++ b/src/cli/ui.rs @@ -45,18 +45,13 @@ pub fn alert_with_error(gui: bool, force: bool, msg: &str, error: &Error) -> Res pub fn alert(gui: bool, force: bool, msg: &str) -> Result<(), Error> { log::debug!("Showing alert to user (GUI={}, force={}): {}", gui, force, msg); if gui { - match native_dialog::MessageDialog::new() - .set_title(&TRANSLATOR.app_name()) - .set_text(msg) - .set_type(native_dialog::MessageType::Error) - .show_alert() - { - Ok(_) => Ok(()), - Err(err) => { - log::error!("Unable to show alert: {:?}", err); - Err(Error::CliUnableToRequestConfirmation) - } - } + rfd::MessageDialog::new() + .set_title(TRANSLATOR.app_name()) + .set_description(msg) + .set_level(rfd::MessageLevel::Error) + .set_buttons(rfd::MessageButtons::Ok) + .show(); + Ok(()) } else if !force { // TODO: Dialoguer doesn't have an alert type. // https://github.com/console-rs/dialoguer/issues/287 @@ -84,21 +79,21 @@ pub fn confirm(gui: bool, force: Option, msg: &str) -> Result } if gui { - match native_dialog::MessageDialog::new() - .set_title(&TRANSLATOR.app_name()) - .set_text(msg) - .set_type(native_dialog::MessageType::Info) - .show_confirm() + let choice = match rfd::MessageDialog::new() + .set_title(TRANSLATOR.app_name()) + .set_description(msg) + .set_level(rfd::MessageLevel::Info) + .set_buttons(rfd::MessageButtons::YesNo) + .show() { - Ok(value) => { - log::debug!("User responded: {}", value); - Ok(value) - } - Err(err) => { - log::error!("Unable to request confirmation: {:?}", err); - Err(Error::CliUnableToRequestConfirmation) - } - } + rfd::MessageDialogResult::Yes => true, + rfd::MessageDialogResult::No => false, + rfd::MessageDialogResult::Ok => true, + rfd::MessageDialogResult::Cancel => false, + rfd::MessageDialogResult::Custom(_) => false, + }; + log::debug!("User responded: {}", choice); + Ok(choice) } else { match dialoguer::Confirm::new().with_prompt(msg).interact() { Ok(value) => { diff --git a/src/gui.rs b/src/gui.rs index 77e774d..cdcc6b3 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -59,12 +59,10 @@ pub fn run(flags: Flags) { log::error!("Failed to initialize GUI: {e:?}"); eprintln!("Failed to initialize GUI: {e:?}"); - if let Err(e) = native_dialog::MessageDialog::new() - .set_type(native_dialog::MessageType::Error) - .set_text(e.to_string().as_str()) - .show_alert() - { - log::error!("Failed to display error dialog: {e:?}"); - } + rfd::MessageDialog::new() + .set_level(rfd::MessageLevel::Error) + .set_description(e.to_string()) + .set_buttons(rfd::MessageButtons::Ok) + .show(); } } diff --git a/src/gui/app.rs b/src/gui/app.rs index 6f6da74..30499ab 100644 --- a/src/gui/app.rs +++ b/src/gui/app.rs @@ -2126,34 +2126,15 @@ impl App { self.save_config(); Task::none() } - Message::BrowseDir(subject) => { - if cfg!(target_os = "macos") { - // On Mac, this must be on the main thread, or it will panic. - let choice = native_dialog::FileDialog::new().show_open_single_dir(); - Task::done(Message::browsed_dir(subject, choice)) - } else { - Task::future(async move { - let choice = async move { native_dialog::FileDialog::new().show_open_single_dir() }.await; + Message::BrowseDir(subject) => Task::future(async move { + let choice = async move { rfd::AsyncFileDialog::new().pick_folder().await }.await; - Message::browsed_dir(subject, choice) - }) - } - } - Message::BrowseFile(subject) => { - if cfg!(target_os = "macos") { - // On Mac, this must be on the main thread, or it will panic. - let choice = native_dialog::FileDialog::new().show_open_single_file(); - Task::done(Message::browsed_file(subject, choice)) - } else { - Task::future(async move { - let choice = async move { native_dialog::FileDialog::new().show_open_single_file() }.await; + Message::browsed_dir(subject, choice.map(|x| x.path().to_path_buf())) + }), + Message::BrowseFile(subject) => Task::future(async move { + let choice = async move { rfd::AsyncFileDialog::new().pick_file().await }.await; - Message::browsed_file(subject, choice) - }) - } - } - Message::BrowseDirFailure => self.show_modal(Modal::Error { - variant: Error::UnableToBrowseFileSystem, + Message::browsed_file(subject, choice.map(|x| x.path().to_path_buf())) }), Message::SelectedFile(subject, path) => { match subject { diff --git a/src/gui/common.rs b/src/gui/common.rs index b1e1a58..65b9684 100644 --- a/src/gui/common.rs +++ b/src/gui/common.rs @@ -208,7 +208,6 @@ pub enum Message { }, BrowseDir(BrowseSubject), BrowseFile(BrowseFileSubject), - BrowseDirFailure, SelectedFile(BrowseFileSubject, StrictPath), SelectAllGames, DeselectAllGames, @@ -293,12 +292,9 @@ pub enum Message { } impl Message { - pub fn browsed_dir( - subject: BrowseSubject, - choice: Result, native_dialog::Error>, - ) -> Self { + pub fn browsed_dir(subject: BrowseSubject, choice: Option) -> Self { match choice { - Ok(Some(path)) => match subject { + Some(path) => match subject { BrowseSubject::BackupTarget => Message::EditedBackupTarget(crate::path::render_pathbuf(&path)), BrowseSubject::RestoreSource => Message::EditedRestoreSource(crate::path::render_pathbuf(&path)), BrowseSubject::Root(i) => Message::EditedRoot(EditAction::Change( @@ -321,19 +317,14 @@ impl Message { Message::EditedBackupFilterIgnoredPath(EditAction::Change(i, crate::path::render_pathbuf(&path))) } }, - Ok(None) => Message::Ignore, - Err(_) => Message::BrowseDirFailure, + None => Message::Ignore, } } - pub fn browsed_file( - subject: BrowseFileSubject, - choice: Result, native_dialog::Error>, - ) -> Self { + pub fn browsed_file(subject: BrowseFileSubject, choice: Option) -> Self { match choice { - Ok(Some(path)) => Message::SelectedFile(subject, StrictPath::from(path)), - Ok(None) => Message::Ignore, - Err(_) => Message::BrowseDirFailure, + Some(path) => Message::SelectedFile(subject, StrictPath::from(path)), + None => Message::Ignore, } } }