From 3826726b843f62e76287f64267da06327bc9bb6e Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Mon, 26 Feb 2024 19:48:54 +0100 Subject: [PATCH 01/36] remove all code and start with relm4 0.6 --- .gitignore | 23 +- Cargo.lock | 868 +++++++++++------- Cargo.toml | 22 +- build-aux/dist-vendor.sh | 0 .../org.kuchelmeister.ToolboxTuner.Devel.json | 54 ++ .../org.kuchelmeister.ToolbxTuner.Devel.json | 46 - containers/Containerfile | 17 - containers/docker-compose.test.yml | 10 - containers/docker-compose.yml | 8 - ...g.kuchelmeister.ToolboxTuner-symbolic.svg} | 0 ... org.kuchelmeister.ToolboxTuner.Devel.svg} | 0 ...org.kuchelmeister.ToolboxTuner.Source.svg} | 0 ...svg => org.kuchelmeister.ToolboxTuner.svg} | 0 data/meson.build | 2 +- ....kuchelmeister.ToolboxTuner.desktop.in.in} | 10 +- ....kuchelmeister.ToolboxTuner.gschema.xml.in | 17 + ...elmeister.ToolboxTuner.metainfo.xml.in.in} | 15 +- ...g.kuchelmeister.ToolbxTuner.gschema.xml.in | 6 - data/resources/resources.gresource.xml | 4 +- data/resources/style.css | 4 + data/resources/ui/shortcuts.ui | 29 + hooks/pre-commit.hook | 12 +- meson.build | 10 +- meson_options.txt | 3 +- po/POTFILES.in | 8 +- src/app.rs | 166 ++++ src/config.rs.in | 1 + src/main.rs | 52 +- src/meson.build | 13 +- src/modals/about.rs | 50 + src/modals/mod.rs | 1 + src/setup.rs | 39 + src/ui.rs | 3 - src/ui/app.rs | 6 - src/ui/app/messages.rs | 12 - src/ui/app/model.rs | 65 -- src/ui/app/toolbox_list.rs | 165 ---- src/ui/app/update.rs | 72 -- src/ui/app/widgets.rs | 42 - src/ui/app/workers.rs | 83 -- src/ui/components.rs | 11 - src/ui/ui_strings.rs | 20 - src/util.rs | 1 - src/util/toolbx.rs | 427 --------- 44 files changed, 1016 insertions(+), 1381 deletions(-) mode change 100755 => 100644 build-aux/dist-vendor.sh create mode 100644 build-aux/org.kuchelmeister.ToolboxTuner.Devel.json delete mode 100644 build-aux/org.kuchelmeister.ToolbxTuner.Devel.json delete mode 100644 containers/Containerfile delete mode 100644 containers/docker-compose.test.yml delete mode 100644 containers/docker-compose.yml rename data/icons/{org.kuchelmeister.ToolbxTuner-symbolic.svg => org.kuchelmeister.ToolboxTuner-symbolic.svg} (100%) rename data/icons/{org.kuchelmeister.ToolbxTuner.Devel.svg => org.kuchelmeister.ToolboxTuner.Devel.svg} (100%) rename data/icons/{org.kuchelmeister.ToolbxTuner.Source.svg => org.kuchelmeister.ToolboxTuner.Source.svg} (100%) rename data/icons/{org.kuchelmeister.ToolbxTuner.svg => org.kuchelmeister.ToolboxTuner.svg} (100%) rename data/{org.kuchelmeister.ToolbxTuner.desktop.in.in => org.kuchelmeister.ToolboxTuner.desktop.in.in} (66%) create mode 100644 data/org.kuchelmeister.ToolboxTuner.gschema.xml.in rename data/{org.kuchelmeister.ToolbxTuner.metainfo.xml.in.in => org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in} (82%) delete mode 100644 data/org.kuchelmeister.ToolbxTuner.gschema.xml.in create mode 100644 data/resources/ui/shortcuts.ui mode change 100755 => 100644 hooks/pre-commit.hook create mode 100644 src/app.rs create mode 100644 src/modals/about.rs create mode 100644 src/modals/mod.rs create mode 100644 src/setup.rs delete mode 100644 src/ui.rs delete mode 100644 src/ui/app.rs delete mode 100644 src/ui/app/messages.rs delete mode 100644 src/ui/app/model.rs delete mode 100644 src/ui/app/toolbox_list.rs delete mode 100644 src/ui/app/update.rs delete mode 100644 src/ui/app/widgets.rs delete mode 100644 src/ui/app/workers.rs delete mode 100644 src/ui/components.rs delete mode 100644 src/ui/ui_strings.rs delete mode 100644 src/util.rs delete mode 100644 src/util/toolbx.rs diff --git a/.gitignore b/.gitignore index 26b6664..142a702 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,15 @@ -target/ -build/ -_build/ -builddir/ -build-aux/app -.flatpak-builder -src/config.rs +/target/ +/build/ +/_build/ +/builddir/ +/build-aux/app +/build-aux/.flatpak-builder/ +/src/config.rs *.ui.in~ *.ui~ -.json~ -.flatpak/ -vendor -flatpak_app -libs +/.flatpak/ +/vendor +/.vscode +.flatpak-builder/ *.AppImage diff --git a/Cargo.lock b/Cargo.lock index fc30a09..4101e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -18,10 +18,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "anyhow" -version = "1.0.71" +name = "aho-corasick" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] [[package]] name = "autocfg" @@ -31,9 +51,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -51,29 +71,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bytes" -version = "1.4.0" +name = "block" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bumpalo" +version = "3.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" [[package]] name = "cairo-rs" -version = "0.15.12" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" +checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" dependencies = [ "bitflags", "cairo-sys-rs", "glib", "libc", + "once_cell", "thiserror", ] [[package]] name = "cairo-sys-rs" -version = "0.15.1" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" dependencies = [ "glib-sys", "libc", @@ -82,15 +109,15 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" [[package]] name = "cfg-expr" -version = "0.15.3" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "215c0072ecc28f92eeb0eea38ba63ddfcb65c2828c46311d646f1a3ff5f9841c" +checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" dependencies = [ "smallvec", "target-lexicon", @@ -119,12 +146,16 @@ dependencies = [ ] [[package]] -name = "fragile" -version = "1.2.2" +name = "flume" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7464c5c4a3f014d9b2ec4073650e5c06596f385060af740fc45ad5a19f959e8" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" dependencies = [ - "fragile 2.0.0", + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", ] [[package]] @@ -134,25 +165,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] -name = "futures-channel" -version = "0.3.28" +name = "futures" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -161,24 +208,46 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -186,22 +255,23 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.15.11" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" +checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" dependencies = [ "bitflags", "gdk-pixbuf-sys", "gio", "glib", "libc", + "once_cell", ] [[package]] name = "gdk-pixbuf-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" +checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" dependencies = [ "gio-sys", "glib-sys", @@ -212,9 +282,9 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabb7cf843c26b085a5d68abb95d0c0bf27a9ae2eeff9c4adb503a1eb580876" +checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" dependencies = [ "bitflags", "cairo-rs", @@ -228,9 +298,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efe7dcb44f5c00aeabff3f69abfc5673de46559070f89bd3fbb7b66485d9cef2" +checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -244,33 +314,69 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.27.3" +name = "getrandom" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gettext-rs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364" +dependencies = [ + "gettext-sys", + "locale_config", +] + +[[package]] +name = "gettext-sys" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d" +dependencies = [ + "cc", + "temp-dir", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "gio" -version = "0.15.12" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-io", + "futures-util", "gio-sys", "glib", "libc", "once_cell", + "pin-project-lite", + "smallvec", "thiserror", ] [[package]] name = "gio-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" dependencies = [ "glib-sys", "gobject-sys", @@ -281,19 +387,22 @@ dependencies = [ [[package]] name = "glib" -version = "0.15.12" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", + "futures-util", + "gio-sys", "glib-macros", "glib-sys", "gobject-sys", "libc", + "memchr", "once_cell", "smallvec", "thiserror", @@ -301,9 +410,9 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.15.13" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" +checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" dependencies = [ "anyhow", "heck", @@ -316,9 +425,9 @@ dependencies = [ [[package]] name = "glib-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0" dependencies = [ "libc", "system-deps", @@ -326,9 +435,9 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" dependencies = [ "glib-sys", "libc", @@ -337,9 +446,9 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.15.1" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570" +checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" dependencies = [ "glib", "graphene-sys", @@ -348,9 +457,9 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa691fc7337ba1df599afb55c3bcb85c04f1b3f17362570e9bb0ff0d1bc3028a" +checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" dependencies = [ "glib-sys", "libc", @@ -360,9 +469,9 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e9020d333280b3aa38d496495bfa9b50712eebf1ad63f0ec5bcddb5eb61be4" +checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" dependencies = [ "bitflags", "cairo-rs", @@ -376,9 +485,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add39ccf60078508c838643a2dcc91f045c46ed63b5ea6ab701b2e25bda3fea" +checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -392,9 +501,9 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.4.9" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8ae5aef2793bc3551b5e5e3fa062a5de54bb1eccf10dfa4effe9e4384fbbbc" +checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" dependencies = [ "bitflags", "cairo-rs", @@ -415,24 +524,23 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.4.10" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aba0b544e91a753068e279e99d34e9624b8cfd26282167024c8a5773b8a826c" +checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" dependencies = [ "anyhow", "proc-macro-crate", "proc-macro-error", "proc-macro2", - "quick-xml", "quote", "syn 1.0.109", ] [[package]] name = "gtk4-sys" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc8006eea634b7c72da3ff79e24606e45f21b3b832a3c5a1f543f5f97eb0f63" +checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -449,9 +557,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -461,32 +569,42 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown", ] [[package]] -name = "itoa" -version = "1.0.8" +name = "js-sys" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libadwaita" -version = "0.1.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ae453d28e3b91f03749f02b1531e8cfe315a1d0762b77a61797d2ab80bb87d" +checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" dependencies = [ + "bitflags", "gdk-pixbuf", "gdk4", "gio", @@ -494,15 +612,14 @@ dependencies = [ "gtk4", "libadwaita-sys", "libc", - "once_cell", "pango", ] [[package]] name = "libadwaita-sys" -version = "0.1.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8" +checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" dependencies = [ "gdk4-sys", "gio-sys", @@ -510,20 +627,34 @@ dependencies = [ "gobject-sys", "gtk4-sys", "libc", + "pango-sys", "system-deps", ] [[package]] name = "libc" -version = "0.2.147" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "locale_config" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" +dependencies = [ + "lazy_static", + "objc", + "objc-foundation", + "regex", + "winapi", +] [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -531,15 +662,24 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memoffset" @@ -552,22 +692,30 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] -name = "mio" -version = "0.8.8" +name = "nanorand" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "libc", - "wasi", - "windows-sys", + "getrandom", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", ] [[package]] @@ -581,27 +729,63 @@ dependencies = [ ] [[package]] -name = "object" -version = "0.31.1" +name = "objc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[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_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pango" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" dependencies = [ "bitflags", + "gio", "glib", "libc", "once_cell", @@ -610,9 +794,9 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.15.10" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" dependencies = [ "glib-sys", "gobject-sys", @@ -621,33 +805,30 @@ dependencies = [ ] [[package]] -name = "parking_lot" -version = "0.12.1" +name = "pin-project" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ - "lock_api", - "parking_lot_core", + "pin-project-internal", ] [[package]] -name = "parking_lot_core" -version = "0.9.8" +name = "pin-project-internal" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", + "proc-macro2", + "quote", + "syn 2.0.51", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -657,9 +838,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "proc-macro-crate" @@ -668,7 +849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -697,64 +878,78 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-xml" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" -dependencies = [ - "memchr", -] - [[package]] name = "quote" -version = "1.0.29" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] -name = "redox_syscall" -version = "0.3.5" +name = "regex" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ - "bitflags", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "relm4" -version = "0.4.4" +name = "regex-automata" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e737555426b35a18e9f6fa8d291ce858d358504d441d1e0a7b06ce6c905cc63" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ - "fragile 1.2.2", - "futures-core", + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relm4" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81" +dependencies = [ + "async-trait", + "flume", + "fragile", + "futures", "gtk4", "libadwaita", - "log", "once_cell", "relm4-macros", + "tokio", + "tracing", ] [[package]] name = "relm4-macros" -version = "0.4.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7136d9b9b97dc87198c619587de7bd61aca5ec4bec58a7167404c1edf750a490" +checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.51", ] [[package]] @@ -772,96 +967,78 @@ dependencies = [ "semver", ] -[[package]] -name = "ryu" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" - [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", -] - -[[package]] -name = "serde_json" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" -dependencies = [ - "itoa", - "ryu", - "serde", + "syn 2.0.51", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] [[package]] -name = "signal-hook-registry" -version = "1.4.1" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "libc", + "lazy_static", ] [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] -name = "socket2" -version = "0.4.9" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "libc", - "winapi", + "lock_api", ] [[package]] @@ -877,9 +1054,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" dependencies = [ "proc-macro2", "quote", @@ -888,9 +1065,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.1.1" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331" dependencies = [ "cfg-expr", "heck", @@ -901,110 +1078,180 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.9" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8e77cb757a61f51b947ec4a7e3646efd825b73561db1c232a8ccb639e611a0" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "temp-dir" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.51", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", ] [[package]] name = "tokio" -version = "1.29.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ - "autocfg", "backtrace", - "bytes", - "libc", - "mio", "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.26", ] [[package]] name = "toml" -version = "0.7.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.6", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.2", ] [[package]] -name = "toolbxtuner" +name = "toolbox-tuner" version = "0.0.1" dependencies = [ + "gettext-rs", "relm4", - "serde", - "serde_json", - "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version-compare" @@ -1024,6 +1271,60 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.51", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + [[package]] name = "winapi" version = "0.3.9" @@ -1046,77 +1347,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - [[package]] name = "winnow" -version = "0.5.0" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 07bb28a..325cf6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,15 @@ [package] -name = "toolbxtuner" +name = "toolbox-tuner" version = "0.0.1" authors = ["Hannes Kuchelmeister "] edition = "2021" +publish = false -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +lto = true [dependencies] -relm4 = {version="0.4", features = ["libadwaita", "macros"]} -tokio = { version = "1", features = ["full"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" - -[package.metadata.appimage] -auto_link = true -auto_link_exclude_list = [ - "libc.so*", - "libdl.so*", - "libpthread.so*", -] +gettext-rs = { version = "0.7", features = ["gettext-system"] } +tracing = "0.1" +tracing-subscriber = "0.3" +relm4 = { version = "0.6.0", features = ["libadwaita", "gnome_44"] } diff --git a/build-aux/dist-vendor.sh b/build-aux/dist-vendor.sh old mode 100755 new mode 100644 diff --git a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json new file mode 100644 index 0000000..9ce4cd4 --- /dev/null +++ b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json @@ -0,0 +1,54 @@ +{ + "id": "org.kuchelmeister.ToolboxTuner.Devel", + "runtime": "org.gnome.Platform", + "runtime-version": "44", + "sdk": "org.gnome.Sdk", + "sdk-extensions": [ + "org.freedesktop.Sdk.Extension.rust-stable", + "org.freedesktop.Sdk.Extension.llvm15" + ], + "command": "toolbox-tuner", + "finish-args": [ + "--share=ipc", + "--socket=fallback-x11", + "--socket=wayland", + "--device=dri", + "--env=RUST_LOG=toolbox_tuner=debug", + "--env=G_MESSAGES_DEBUG=none", + "--env=RUST_BACKTRACE=1" + ], + "build-options": { + "append-path": "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm15/bin", + "prepend-ld-library-path": "/usr/lib/sdk/llvm15/lib", + "build-args": [ + "--share=network" + ], + "env": { + "CARGO_REGISTRIES_CRATES_IO_PROTOCOL": "sparse", + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER": "clang", + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER": "clang", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold" + }, + "test-args": [ + "--socket=x11", + "--share=network" + ] + }, + "modules": [ + { + "name": "toolbox-tuner", + "buildsystem": "meson", + "run-tests": true, + "config-opts": [ + "-Dprofile=development" + ], + "sources": [ + { + "type": "dir", + "path": "../" + } + ] + } + ] +} diff --git a/build-aux/org.kuchelmeister.ToolbxTuner.Devel.json b/build-aux/org.kuchelmeister.ToolbxTuner.Devel.json deleted file mode 100644 index eb9b43c..0000000 --- a/build-aux/org.kuchelmeister.ToolbxTuner.Devel.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "id": "org.kuchelmeister.ToolbxTuner.Devel", - "runtime": "org.gnome.Platform", - "runtime-version": "42", - "sdk": "org.gnome.Sdk", - "sdk-extensions": [ - "org.freedesktop.Sdk.Extension.rust-stable" - ], - "command": "toolbxtuner", - "finish-args": [ - "--talk-name=org.freedesktop.Flatpak", - "--socket=fallback-x11", - "--socket=wayland", - "--device=dri", - "--env=RUST_LOG=toolbxtuner=debug", - "--env=G_MESSAGES_DEBUG=none", - "--env=RUST_BACKTRACE=1", - "--share=ipc" - ], - "build-options": { - "append-path": "/usr/lib/sdk/rust-stable/bin", - "build-args": [ - "--share=network" - ], - "test-args": [ - "--socket=x11", - "--share=network" - ] - }, - "modules": [ - { - "name": "toolbxtuner", - "buildsystem": "meson", - "run-tests": true, - "config-opts": [ - "-Dprofile=development" - ], - "sources": [ - { - "type": "dir", - "path": "../" - } - ] - } - ] -} diff --git a/containers/Containerfile b/containers/Containerfile deleted file mode 100644 index af6867f..0000000 --- a/containers/Containerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM quay.io/podman/stable - -ENV RUST_VERSION=1.61.0 -ENV HOME=/home/root - -RUN dnf install gtk4-devel gcc libadwaita-devel -y -RUN dnf install toolbox -y - -RUN curl https://sh.rustup.rs -sSf | sh -s -- -y -RUN . $HOME/.cargo/env -ENV PATH=/home/root/.cargo/bin:$PATH -RUN rustup install ${RUST_VERSION} - -WORKDIR /mnt - -CMD cargo test - diff --git a/containers/docker-compose.test.yml b/containers/docker-compose.test.yml deleted file mode 100644 index fabdb76..0000000 --- a/containers/docker-compose.test.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3" -services: - toolbx-tuner-tests: - build: . - privileged: true - volumes: - - ..:/mnt:z - security_opt: - - label=disable - diff --git a/containers/docker-compose.yml b/containers/docker-compose.yml deleted file mode 100644 index 82694e5..0000000 --- a/containers/docker-compose.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: "3" -services: - gtk4-rs: - image: ghcr.io/13hannes11/gtk4-rs-docker:latest-appimage - volumes: - - ..:/mnt:z - command: sh -c "cargo appimage" - diff --git a/data/icons/org.kuchelmeister.ToolbxTuner-symbolic.svg b/data/icons/org.kuchelmeister.ToolboxTuner-symbolic.svg similarity index 100% rename from data/icons/org.kuchelmeister.ToolbxTuner-symbolic.svg rename to data/icons/org.kuchelmeister.ToolboxTuner-symbolic.svg diff --git a/data/icons/org.kuchelmeister.ToolbxTuner.Devel.svg b/data/icons/org.kuchelmeister.ToolboxTuner.Devel.svg similarity index 100% rename from data/icons/org.kuchelmeister.ToolbxTuner.Devel.svg rename to data/icons/org.kuchelmeister.ToolboxTuner.Devel.svg diff --git a/data/icons/org.kuchelmeister.ToolbxTuner.Source.svg b/data/icons/org.kuchelmeister.ToolboxTuner.Source.svg similarity index 100% rename from data/icons/org.kuchelmeister.ToolbxTuner.Source.svg rename to data/icons/org.kuchelmeister.ToolboxTuner.Source.svg diff --git a/data/icons/org.kuchelmeister.ToolbxTuner.svg b/data/icons/org.kuchelmeister.ToolboxTuner.svg similarity index 100% rename from data/icons/org.kuchelmeister.ToolbxTuner.svg rename to data/icons/org.kuchelmeister.ToolboxTuner.svg diff --git a/data/meson.build b/data/meson.build index 05dec0c..5643b60 100644 --- a/data/meson.build +++ b/data/meson.build @@ -65,7 +65,7 @@ configure_file( install_dir: datadir / 'glib-2.0' / 'schemas' ) -# Validate GSchema +# Validata GSchema if glib_compile_schemas.found() test( 'validate-gschema', glib_compile_schemas, diff --git a/data/org.kuchelmeister.ToolbxTuner.desktop.in.in b/data/org.kuchelmeister.ToolboxTuner.desktop.in.in similarity index 66% rename from data/org.kuchelmeister.ToolbxTuner.desktop.in.in rename to data/org.kuchelmeister.ToolboxTuner.desktop.in.in index f0de095..e02d0a8 100644 --- a/data/org.kuchelmeister.ToolbxTuner.desktop.in.in +++ b/data/org.kuchelmeister.ToolboxTuner.desktop.in.in @@ -1,12 +1,12 @@ [Desktop Entry] -Name=Toolbx Tuner -Comment=Manage and enhance your toolbxes (containertoolboxes) -Exec=toolbxtuner -Terminal=false +Name=Toolbox Tuner +Comment=Manage and enhance your toolboxes (containertoolboxes) Type=Application +Exec=toolbox-tuner +Terminal=false Categories=Utility; # Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! -Keywords=Gnome;GTK;Container;Toolbx;Podman;Toolbox;Fedora;Silvervblue; +Keywords=Gnome;GTK;Container;Podman;Toolbox;Fedora;Silvervblue; # Translators: Do NOT translate or transliterate this text (this is an icon file name)! Icon=@icon@ StartupNotify=true diff --git a/data/org.kuchelmeister.ToolboxTuner.gschema.xml.in b/data/org.kuchelmeister.ToolboxTuner.gschema.xml.in new file mode 100644 index 0000000..4fd4593 --- /dev/null +++ b/data/org.kuchelmeister.ToolboxTuner.gschema.xml.in @@ -0,0 +1,17 @@ + + + + + 600 + Window width + + + 400 + Window height + + + false + Window maximized state + + + diff --git a/data/org.kuchelmeister.ToolbxTuner.metainfo.xml.in.in b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in similarity index 82% rename from data/org.kuchelmeister.ToolbxTuner.metainfo.xml.in.in rename to data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in index 726ff30..ae187f0 100644 --- a/data/org.kuchelmeister.ToolbxTuner.metainfo.xml.in.in +++ b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in @@ -1,5 +1,5 @@ - + @app-id@ CC0 @@ -9,19 +9,23 @@

An application to manage and enhance your containertoolboxes.

- + Main application window showing multiple toolboxes https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_light.png - + Main application window in dark mode https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_dark.png - + + #a3f6f1 + #60ada6 + + - + https://github.com/13hannes11/toolbx-tuner https://github.com/13hannes11/toolbx-tuner/issues/ @@ -30,3 +34,4 @@ @gettext-package@ @app-id@.desktop
+ diff --git a/data/org.kuchelmeister.ToolbxTuner.gschema.xml.in b/data/org.kuchelmeister.ToolbxTuner.gschema.xml.in deleted file mode 100644 index e6418dc..0000000 --- a/data/org.kuchelmeister.ToolbxTuner.gschema.xml.in +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml index 7bc4c8a..a28ee95 100644 --- a/data/resources/resources.gresource.xml +++ b/data/resources/resources.gresource.xml @@ -1,6 +1,8 @@ - + + ui/shortcuts.ui + style.css diff --git a/data/resources/style.css b/data/resources/style.css index e69de29..35ffd40 100644 --- a/data/resources/style.css +++ b/data/resources/style.css @@ -0,0 +1,4 @@ +.title-header{ + font-size: 36px; + font-weight: bold; +} \ No newline at end of file diff --git a/data/resources/ui/shortcuts.ui b/data/resources/ui/shortcuts.ui new file mode 100644 index 0000000..ef12f02 --- /dev/null +++ b/data/resources/ui/shortcuts.ui @@ -0,0 +1,29 @@ + + + + True + + + shortcuts + 10 + + + General + + + Show Shortcuts + win.show-help-overlay + + + + + Quit + app.quit + + + + + + + + diff --git a/hooks/pre-commit.hook b/hooks/pre-commit.hook old mode 100755 new mode 100644 index cc44705..464590e --- a/hooks/pre-commit.hook +++ b/hooks/pre-commit.hook @@ -2,16 +2,16 @@ # Source: https://gitlab.gnome.org/GNOME/fractal/blob/master/hooks/pre-commit.hook install_rustfmt() { - if ! which rustup &> /dev/null; then + if ! which rustup >/dev/null 2>&1; then curl https://sh.rustup.rs -sSf | sh -s -- -y export PATH=$PATH:$HOME/.cargo/bin - if ! which rustup &> /dev/null; then + if ! which rustup >/dev/null 2>&1; then echo "Failed to install rustup. Performing the commit without style checking." exit 0 fi fi - if ! rustup component list|grep rustfmt &> /dev/null; then + if ! rustup component list|grep rustfmt >/dev/null 2>&1; then echo "Installing rustfmt…" rustup component add rustfmt fi @@ -34,11 +34,11 @@ if ! which cargo >/dev/null 2>&1 || ! cargo fmt --help >/dev/null 2>&1; then echo "" while true do - echo -n "Install rustfmt via rustup? [y/n/Q]: "; read yn < /dev/tty + printf "%s" "Install rustfmt via rustup? [y/n/Q]: "; read yn < /dev/tty case $yn in [Yy]* ) install_rustfmt; break;; [Nn]* ) echo "Performing commit."; exit 0;; - [Qq]* | "" ) echo "Aborting commit."; exit -1 >/dev/null 2>&1;; + [Qq]* | "" ) echo "Aborting commit."; exit 1 >/dev/null 2>&1;; * ) echo "Invalid input";; esac done @@ -51,7 +51,7 @@ if test $? != 0; then echo "--Checking style fail--" echo "Please fix the above issues, either manually or by running: cargo fmt --all" - exit -1 + exit 1 else echo "--Checking style pass--" fi diff --git a/meson.build b/meson.build index 4e0aa99..f0086df 100644 --- a/meson.build +++ b/meson.build @@ -1,15 +1,15 @@ project( - 'toolbxtuner', + 'toolbox-tuner', 'rust', version: '0.0.1', meson_version: '>= 0.59', - license: 'GPL-3', + # license: 'MIT', ) i18n = import('i18n') gnome = import('gnome') -base_id = 'org.kuchelmeister.ToolbxTuner' +base_id = 'org.kuchelmeister.ToolboxTuner' dependency('glib-2.0', version: '>= 2.66') dependency('gio-2.0', version: '>= 2.66') @@ -35,7 +35,7 @@ gettext_package = meson.project_name() if get_option('profile') == 'development' profile = 'Devel' - vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip() + vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD', check: false).stdout().strip() if vcs_tag == '' version_suffix = '-devel' else @@ -57,7 +57,7 @@ meson.add_dist_script( if get_option('profile') == 'development' # Setup pre-commit hook for ensuring coding style is always consistent message('Setting up git pre-commit hook..') - run_command('cp', '-f', 'hooks/pre-commit.hook', '.git/hooks/pre-commit') + run_command('cp', '-f', 'hooks/pre-commit.hook', '.git/hooks/pre-commit', check: false) endif subdir('data') diff --git a/meson_options.txt b/meson_options.txt index 568f4ac..f882783 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,9 +3,8 @@ option( type: 'combo', choices: [ 'default', - 'flathub', 'development' ], value: 'default', - description: 'The build profile for Toolbx Tuner. One of "default" or "development".' + description: 'The build profile for Toolbox Tuner. One of "default" or "development".' ) diff --git a/po/POTFILES.in b/po/POTFILES.in index 83bf505..00c689c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,6 @@ -data/org.kuchelmeister.ToolbxTuner.desktop.in.in -data/org.kuchelmeister.ToolbxTuner.gschema.xml.in -data/org.kuchelmeister.ToolbxTuner.metainfo.xml.in.in +data/org.kuchelmeister.ToolboxTuner.desktop.in.in +data/org.kuchelmeister.ToolboxTuner.gschema.xml.in +data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in +data/resources/ui/shortcuts.ui +data/resources/ui/window.ui src/application.rs diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..043ac57 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,166 @@ +use relm4::{ + actions::{RelmAction, RelmActionGroup}, + adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender, + Controller, SimpleComponent, +}; + +use gtk::prelude::{ + ApplicationExt, ApplicationWindowExt, GtkWindowExt, OrientableExt, SettingsExt, WidgetExt, +}; +use gtk::{gio, glib}; + +use crate::config::{APP_ID, PROFILE}; +use crate::modals::about::AboutDialog; + +pub(super) struct App { + about_dialog: Controller, +} + +#[derive(Debug)] +pub(super) enum AppMsg { + Quit, +} + +relm4::new_action_group!(pub(super) WindowActionGroup, "win"); +//relm4::new_stateless_action!(PreferencesAction, WindowActionGroup, "preferences"); +relm4::new_stateless_action!(pub(super) ShortcutsAction, WindowActionGroup, "show-help-overlay"); +relm4::new_stateless_action!(AboutAction, WindowActionGroup, "about"); + +#[relm4::component(pub)] +impl SimpleComponent for App { + type Init = (); + type Input = AppMsg; + type Output = (); + type Widgets = AppWidgets; + + menu! { + primary_menu: { + section! { + //"_Preferences" => PreferencesAction, + "_Keyboard" => ShortcutsAction, + "_About Toolbox Tuner" => AboutAction, + } + } + } + + view! { + main_window = adw::ApplicationWindow::new(&main_application()) { + connect_close_request[sender] => move |_| { + sender.input(AppMsg::Quit); + gtk::Inhibit(true) + }, + + #[wrap(Some)] + set_help_overlay: shortcuts = >k::Builder::from_resource( + "/org/kuchelmeister/ToolboxTuner/gtk/help-overlay.ui" + ) + .object::("help_overlay") + .unwrap() -> gtk::ShortcutsWindow { + set_transient_for: Some(&main_window), + set_application: Some(&main_application()), + }, + + add_css_class?: if PROFILE == "Devel" { + Some("devel") + } else { + None + }, + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + + adw::HeaderBar { + pack_end = >k::MenuButton { + set_icon_name: "open-menu-symbolic", + set_menu_model: Some(&primary_menu), + } + }, + + gtk::Label { + set_label: "Hello world!", + add_css_class: "title-header", + set_vexpand: true, + } + } + + } + } + + fn init( + _init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let about_dialog = AboutDialog::builder() + .transient_for(root) + .launch(()) + .detach(); + + let model = Self { about_dialog }; + + let widgets = view_output!(); + + let mut actions = RelmActionGroup::::new(); + + let shortcuts_action = { + let shortcuts = widgets.shortcuts.clone(); + RelmAction::::new_stateless(move |_| { + shortcuts.present(); + }) + }; + + let about_action = { + let sender = model.about_dialog.sender().clone(); + RelmAction::::new_stateless(move |_| { + sender.send(()).unwrap(); + }) + }; + + actions.add_action(shortcuts_action); + actions.add_action(about_action); + actions.register_for_widget(&widgets.main_window); + + widgets.load_window_size(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, _sender: ComponentSender) { + match message { + AppMsg::Quit => main_application().quit(), + } + } + + fn shutdown(&mut self, widgets: &mut Self::Widgets, _output: relm4::Sender) { + widgets.save_window_size().unwrap(); + } +} + +impl AppWidgets { + fn save_window_size(&self) -> Result<(), glib::BoolError> { + let settings = gio::Settings::new(APP_ID); + let (width, height) = self.main_window.default_size(); + + settings.set_int("window-width", width)?; + settings.set_int("window-height", height)?; + + settings.set_boolean("is-maximized", self.main_window.is_maximized())?; + + Ok(()) + } + + fn load_window_size(&self) { + let settings = gio::Settings::new(APP_ID); + + let width = settings.int("window-width"); + let height = settings.int("window-height"); + let is_maximized = settings.boolean("is-maximized"); + + self.main_window.set_default_size(width, height); + + if is_maximized { + self.main_window.maximize(); + } + } +} + diff --git a/src/config.rs.in b/src/config.rs.in index 699897f..0c1c0f6 100644 --- a/src/config.rs.in +++ b/src/config.rs.in @@ -1,6 +1,7 @@ pub const APP_ID: &str = @APP_ID@; pub const GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; pub const LOCALEDIR: &str = @LOCALEDIR@; +#[allow(unused)] pub const PKGDATADIR: &str = @PKGDATADIR@; pub const PROFILE: &str = @PROFILE@; pub const RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/resources.gresource"); diff --git a/src/main.rs b/src/main.rs index f73f759..f2739fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,47 @@ -use std::collections::VecDeque; +#[rustfmt::skip] +mod config; +mod app; +mod modals; +mod setup; -use relm4::gtk::{Application, ApplicationWindow}; -use relm4::{factory::FactoryVecDeque, RelmApp}; -use ui::app::model::AppModel; -use util::toolbx::ToolbxContainer; +use gtk::prelude::ApplicationExt; +use relm4::{ + actions::{AccelsPlus, RelmAction, RelmActionGroup}, + gtk, main_application, RelmApp, +}; -mod ui; -mod util; +use app::App; +use setup::setup; + +relm4::new_action_group!(AppActionGroup, "app"); +relm4::new_stateless_action!(QuitAction, AppActionGroup, "quit"); fn main() { - let mut model = AppModel { - toolboxes: FactoryVecDeque::new(), + // Enable logging + tracing_subscriber::fmt() + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL) + .with_max_level(tracing::Level::INFO) + .init(); + + setup(); + + let app = main_application(); + app.set_resource_base_path(Some("/org/kuchelmeister/ToolboxTuner/")); + + let mut actions = RelmActionGroup::::new(); + + let quit_action = { + let app = app.clone(); + RelmAction::::new_stateless(move |_| { + app.quit(); + }) }; - let app = RelmApp::new(model); - app.run(); + actions.add_action(quit_action); + actions.register_for_main_application(); + + app.set_accelerators_for_action::(&["q"]); + + let app = RelmApp::from_app(app); + + app.run::(()); } diff --git a/src/meson.build b/src/meson.build index 4f94a86..d99036d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -25,20 +25,13 @@ if get_option('profile') == 'default' cargo_options += [ '--release' ] rust_target = 'release' message('Building in release mode') - cargo_env = [ 'CARGO_HOME=' + meson.project_build_root() / 'cargo-home' ] -endif -if get_option('profile') == 'flathub' - cargo_options += [ '--release', '--offline' ] - rust_target = 'release' - message('Building in flathub release mode') - cargo_env = [ 'CARGO_HOME=/run/build/toolbx-tuner/cargo' ] -endif -if get_option('profile') == 'development' +else rust_target = 'debug' message('Building in debug mode') - cargo_env = [ 'CARGO_HOME=' + meson.project_build_root() / 'cargo-home' ] endif +cargo_env = [ 'CARGO_HOME=' + meson.project_build_root() / 'cargo-home' ] + cargo_build = custom_target( 'cargo-build', build_by_default: true, diff --git a/src/modals/about.rs b/src/modals/about.rs new file mode 100644 index 0000000..d3f070e --- /dev/null +++ b/src/modals/about.rs @@ -0,0 +1,50 @@ +use gtk::prelude::GtkWindowExt; +use relm4::{adw, gtk, ComponentParts, ComponentSender, SimpleComponent}; + +use crate::config::{APP_ID, VERSION}; + +pub struct AboutDialog {} + +impl SimpleComponent for AboutDialog { + type Init = (); + type Widgets = adw::AboutWindow; + type Input = (); + type Output = (); + type Root = adw::AboutWindow; + + fn init_root() -> Self::Root { + adw::AboutWindow::builder() + .application_icon(APP_ID) + // Insert your license of choice here + .license_type(gtk::License::Lgpl30) + // Insert your website here + .website("https://github.com/13hannes11/toolbox-tuner") + // Insert your Issues page + .issue_url("https://github.com/13hannes11/toolbox-tuner/issues") + // Insert your application name here + .application_name("Toolbox Tuner") + .version(VERSION) + .translator_credits("translator-credits") + .copyright("© 2022-2024 Hannes Kuchelmeister") + .developers(vec!["Hannes Kuchelmeister"]) + .designers(vec!["Hannes Kuchelmeister"]) + .build() + } + + fn init( + _: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self {}; + + let widgets = root.clone(); + widgets.set_hide_on_close(true); + ComponentParts { model, widgets } + } + + fn update_view(&self, dialog: &mut Self::Widgets, _sender: ComponentSender) { + dialog.present(); + } +} + diff --git a/src/modals/mod.rs b/src/modals/mod.rs new file mode 100644 index 0000000..ced7521 --- /dev/null +++ b/src/modals/mod.rs @@ -0,0 +1 @@ +pub mod about; diff --git a/src/setup.rs b/src/setup.rs new file mode 100644 index 0000000..2bff9a2 --- /dev/null +++ b/src/setup.rs @@ -0,0 +1,39 @@ +use relm4::gtk; + +use gettextrs::{gettext, LocaleCategory}; +use gtk::{gio, glib}; + +use crate::config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; + +pub fn setup() { + // Initialize GTK + gtk::init().unwrap(); + + setup_gettext(); + + glib::set_application_name(&gettext("Toolbox Tuner")); + + let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file"); + gio::resources_register(&res); + + setup_css(&res); + + gtk::Window::set_default_icon_name(APP_ID); +} + +fn setup_gettext() { + // Prepare i18n + gettextrs::setlocale(LocaleCategory::LcAll, ""); + gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); + gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); +} + +fn setup_css(res: &gio::Resource) { + let data = res + .lookup_data( + "/org/kuchelmeister/ToolboxTuner/style.css", + gio::ResourceLookupFlags::NONE, + ) + .unwrap(); + relm4::set_global_css(&glib::GString::from_utf8_checked(data.to_vec()).unwrap()); +} diff --git a/src/ui.rs b/src/ui.rs deleted file mode 100644 index d47ef01..0000000 --- a/src/ui.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod app; -pub mod components; -pub mod ui_strings; diff --git a/src/ui/app.rs b/src/ui/app.rs deleted file mode 100644 index caa508a..0000000 --- a/src/ui/app.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod messages; -pub mod model; -pub mod toolbox_list; -pub mod update; -pub mod widgets; -pub mod workers; diff --git a/src/ui/app/messages.rs b/src/ui/app/messages.rs deleted file mode 100644 index cc23db8..0000000 --- a/src/ui/app/messages.rs +++ /dev/null @@ -1,12 +0,0 @@ -use relm4::factory::DynamicIndex; - -use crate::util::toolbx::ToolbxContainer; - -use super::model::ToolbxEntry; - -pub enum AppMsg { - ToolbxListUpdate(Vec), - ToolbxContainerToggleStartStop(DynamicIndex), - OpenToolbxTerminal(DynamicIndex), - ToolbxContainerChanged(DynamicIndex, ToolbxEntry), -} diff --git a/src/ui/app/model.rs b/src/ui/app/model.rs deleted file mode 100644 index 9468c33..0000000 --- a/src/ui/app/model.rs +++ /dev/null @@ -1,65 +0,0 @@ -use relm4::{factory::FactoryVecDeque, Model}; - -use crate::{ui::components::AppComponents, util::toolbx::ToolbxContainer}; - -use super::{messages::AppMsg, widgets::AppWidgets}; - -#[derive(Debug, Clone)] -pub struct ToolbxEntry { - pub toolbx_container: ToolbxContainer, - pub changing_status: bool, - // TODO: settings -} - -impl ToolbxEntry { - pub fn update_container(&mut self, container: ToolbxContainer) { - std::mem::replace::(&mut self.toolbx_container, container); - } - pub fn update_entry(&mut self, container: ToolbxEntry) { - std::mem::replace::( - &mut self.toolbx_container, - container.toolbx_container, - ); - self.changing_status = container.changing_status; - } -} - -pub struct AppModel { - pub toolboxes: FactoryVecDeque, -} - -impl Model for AppModel { - type Msg = AppMsg; - type Widgets = AppWidgets; - type Components = AppComponents; -} - -impl AppModel { - pub fn update_toolbxes(&mut self, toolbox_iter: I) - where - I: Iterator, - { - // Update each toolbx entry if there were changes to it - // TODO: deal with the removal of toolboxes - for tbx_update in toolbox_iter { - println!("name: {}", tbx_update.name); - let mut exists = false; - for (index, tbx_entry) in self.toolboxes.iter().enumerate() { - if tbx_update.name == tbx_entry.toolbx_container.name { - self.toolboxes - .get_mut(index) - .map(|x| x.update_container(tbx_update.clone())); - exists = true; - break; - } - } - if !exists { - println!("{}", tbx_update.name); - self.toolboxes.push_back(ToolbxEntry { - toolbx_container: tbx_update, - changing_status: false, - }) - } - } - } -} diff --git a/src/ui/app/toolbox_list.rs b/src/ui/app/toolbox_list.rs deleted file mode 100644 index 63f8b03..0000000 --- a/src/ui/app/toolbox_list.rs +++ /dev/null @@ -1,165 +0,0 @@ -use relm4::{ - adw::{ - self, - prelude::{BoxExt, ButtonExt, WidgetExt}, - traits::{ActionRowExt, PreferencesRowExt}, - }, - factory::{DynamicIndex, FactoryPrototype, FactoryVecDeque}, - gtk, send, view, Sender, -}; - -use crate::{ - ui::ui_strings::{ - APP_ICON, APP_TOOLTIP, SETTINGS_ICON, SETTINGS_TOOLTIP, SHUTDOWN_ICON, SHUTDOWN_TOOLTIP, - START_ICON, START_TOOLTIP, TERMINAL_ICON, TERMINAL_TOOLTIP, UPDATE_ICON, UPDATE_TOOLTIP, - }, - util::toolbx::ToolbxStatus, -}; - -use super::{messages::AppMsg, model::ToolbxEntry}; - -#[derive(Debug)] -pub struct FactoryWidgets { - pub action_row: adw::ActionRow, - status_button: gtk::Button, - status_spinner: gtk::Spinner, -} - -impl FactoryPrototype for ToolbxEntry { - type Factory = FactoryVecDeque; - type Widgets = FactoryWidgets; - type Root = adw::ActionRow; - type View = gtk::ListBox; - type Msg = AppMsg; - - fn init_view(&self, key: &DynamicIndex, sender: Sender) -> Self::Widgets { - let index_terminal = key.clone(); - let index_settings = key.clone(); - - view! { - suffix_box = >k::Box{ - append = >k::AspectFrame{ - set_ratio: 1.0, - set_child = Some(>k::Button::from_icon_name(TERMINAL_ICON)) { - set_margin_start: 10, - set_margin_top: 10, - set_margin_bottom: 10, - set_tooltip_text: Some(TERMINAL_TOOLTIP), - set_css_classes: &["flat"], - connect_clicked(sender) => move |btn| { - send!(sender, AppMsg::OpenToolbxTerminal(index_terminal.clone())); - }, - } - }, - } - }; - let mut status_button_tooltip = START_TOOLTIP; - let mut status_button_icon = START_ICON; - - match self.toolbx_container.status { - ToolbxStatus::Running => { - status_button_tooltip = SHUTDOWN_TOOLTIP; - status_button_icon = SHUTDOWN_ICON; - } - _ => { - status_button_tooltip = START_TOOLTIP; - status_button_icon = START_ICON; - } - } - - let subtitle = format!( - "created {}\n{}", - self.toolbx_container.created, self.toolbx_container.image - ); - - let index = key.clone(); - - view! { - status_spinner = >k::Spinner { - set_margin_top: 10, - set_margin_bottom: 10, - set_tooltip_text: Some(status_button_tooltip), - set_css_classes: &["circular"], - - } - }; - //status_spinner.start(); - - view! { - status_button = >k::Button::from_icon_name(status_button_icon) { - set_margin_top: 10, - set_margin_bottom: 10, - set_tooltip_text: Some(status_button_tooltip), - set_css_classes: &["circular"], - connect_clicked(sender) => move |btn| { - // Disable button - btn.set_sensitive(false); - send!(sender, AppMsg::ToolbxContainerToggleStartStop(index.clone())); - }, - } - }; - - view! { - action_row = &adw::ActionRow { - set_title: &self.toolbx_container.name, - set_subtitle: subtitle.as_str(), - add_prefix = >k::Box { - append = >k::AspectFrame{ - set_ratio: 1.0, - set_child: Some(&status_button), - } - }, - add_suffix: &suffix_box, - } - - }; - FactoryWidgets { - action_row, - status_button, - status_spinner, - } - } - - fn view( - &self, - key: &>::Key, - widgets: &Self::Widgets, - ) { - println!("updated {}", key.current_index()); - - // fixme: IDEALY this is would be done with message handling and only if the request actually is done - - if self.changing_status { - widgets.status_button.set_sensitive(false); - widgets - .status_button - .set_child(Some(&widgets.status_spinner)); - widgets.status_spinner.start(); - } else { - match self.toolbx_container.status { - ToolbxStatus::Running => { - widgets.status_button.set_icon_name(SHUTDOWN_ICON); - widgets - .status_button - .set_tooltip_text(Some(SHUTDOWN_TOOLTIP)); - } - _ => { - widgets.status_button.set_icon_name(START_ICON); - widgets.status_button.set_tooltip_text(Some(START_TOOLTIP)); - } - } - widgets.status_button.set_sensitive(true); - widgets.status_spinner.stop(); - } - } - - fn root_widget(widgets: &Self::Widgets) -> &Self::Root { - &widgets.action_row - } - - fn position( - &self, - key: &>::Key, - ) -> >::Position { - } -} diff --git a/src/ui/app/update.rs b/src/ui/app/update.rs deleted file mode 100644 index 6e12c80..0000000 --- a/src/ui/app/update.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::process::Command; - -use relm4::{AppUpdate, Sender}; - -use crate::{ui::components::AppComponents, util::toolbx::ToolbxStatus}; - -use super::{messages::AppMsg, model::AppModel, workers::AsyncHandlerMsg}; - -impl AppUpdate for AppModel { - fn update(&mut self, msg: AppMsg, components: &AppComponents, _sender: Sender) -> bool { - match msg { - AppMsg::ToolbxContainerToggleStartStop(index) => { - if let Some(toolbx_container) = self.toolboxes.get_mut(index.current_index()) { - match toolbx_container.toolbx_container.status { - ToolbxStatus::Exited | ToolbxStatus::Configured | ToolbxStatus::Created => { - toolbx_container.changing_status = true; - components - .async_handler - .sender() - .blocking_send(AsyncHandlerMsg::StartToolbx( - index, - toolbx_container.clone(), - )) - .expect("Receiver dropped"); - } - ToolbxStatus::Running => { - toolbx_container.changing_status = true; - components - .async_handler - .sender() - .blocking_send(AsyncHandlerMsg::StopToolbx( - index, - toolbx_container.clone(), - )) - .expect("Receiver dropped"); - } - } - // TODO: tell button to reactivate somehow - } - } - AppMsg::ToolbxContainerChanged(index, container) => { - if let Some(toolbx_container) = self.toolboxes.get_mut(index.current_index()) { - toolbx_container.update_entry(container); - } - } - AppMsg::ToolbxListUpdate(tbx_vec) => { - println!("Updating Toolbox List"); - self.update_toolbxes(tbx_vec.into_iter()); - } - - AppMsg::OpenToolbxTerminal(index) => { - if let Some(toolbx_container) = self.toolboxes.get_mut(index.current_index()) { - // TODO: support many terminals and check which are installed - let output = Command::new("flatpak-spawn") - .arg("--host") - .arg("gnome-terminal") //Command::new("gnome-terminal") - .arg("--") - .arg("toolbox") - .arg("enter") - .arg(toolbx_container.toolbx_container.name.clone()) - .output(); - - println!("{:?}", output); - - // TODO: update status on worker and add refresh spinner in the meantime - toolbx_container.toolbx_container.update_status(); - } - } - } - true - } -} diff --git a/src/ui/app/widgets.rs b/src/ui/app/widgets.rs deleted file mode 100644 index 6cc42fb..0000000 --- a/src/ui/app/widgets.rs +++ /dev/null @@ -1,42 +0,0 @@ -use relm4::{ - adw::{ - self, - prelude::{BoxExt, GtkWindowExt, OrientableExt, WidgetExt}, - traits::AdwApplicationWindowExt, - }, - gtk::{self, Align, PolicyType, SelectionMode}, - WidgetPlus, Widgets, -}; - -use super::model::AppModel; - -#[relm4::widget(pub)] -impl Widgets for AppWidgets { - view! { - main_window = adw::ApplicationWindow { - set_default_width: 800, - set_default_height: 600, - set_content : main_box = Some(>k::Box) { - set_orientation: gtk::Orientation::Vertical, - append = &adw::HeaderBar { - set_title_widget = Some(>k::Label) { - set_label: "Toolbox Tuner", - } - }, - - append = >k::ScrolledWindow { - set_hexpand: true, - set_vexpand: true, - set_hscrollbar_policy: PolicyType::Never, - set_child = Some(>k::ListBox) { - set_valign: Align::Start, - set_selection_mode: SelectionMode::None, - set_margin_all: 30, - set_css_classes: &["boxed-list"], - factory!(model.toolboxes) - } - } - } - } - } -} diff --git a/src/ui/app/workers.rs b/src/ui/app/workers.rs deleted file mode 100644 index b48e4fd..0000000 --- a/src/ui/app/workers.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::time::Duration; - -use relm4::factory::DynamicIndex; -use relm4::{send, MessageHandler, Sender}; -use tokio::runtime::{Builder, Runtime}; -use tokio::sync::mpsc::{channel, Sender as TokioSender}; - -use crate::util::toolbx::ToolbxContainer; - -use super::{ - messages::AppMsg, - model::{AppModel, ToolbxEntry}, -}; - -// Code adapted from https://relm4.org/book/stable/message_handler.html -pub struct AsyncHandler { - _rt: Runtime, - sender: TokioSender, -} - -#[derive(Debug)] -pub enum AsyncHandlerMsg { - StopToolbx(DynamicIndex, ToolbxEntry), - StartToolbx(DynamicIndex, ToolbxEntry), - UpdateToolbxes, -} - -impl MessageHandler for AsyncHandler { - type Msg = AsyncHandlerMsg; - type Sender = TokioSender; - - fn init(_parent_model: &AppModel, parent_sender: Sender) -> Self { - let (sender, mut rx) = channel::(10); - - let rt = Builder::new_multi_thread() - .worker_threads(8) - .enable_time() - .build() - .unwrap(); - - rt.spawn(async move { - while let Some(msg) = rx.recv().await { - let parent_sender = parent_sender.clone(); - tokio::spawn(async move { - match msg { - AsyncHandlerMsg::UpdateToolbxes => { - let toolboxes = ToolbxContainer::get_toolboxes(); - send! {parent_sender, AppMsg::ToolbxListUpdate(toolboxes)}; - } - AsyncHandlerMsg::StopToolbx(index, mut tbx) => { - tbx.toolbx_container.stop(); - tbx.changing_status = false; - send! {parent_sender, AppMsg::ToolbxContainerChanged(index, tbx)}; - } - AsyncHandlerMsg::StartToolbx(index, mut tbx) => { - tbx.toolbx_container.start(); - tbx.changing_status = false; - send! {parent_sender, AppMsg::ToolbxContainerChanged(index, tbx)}; - } - } - }); - } - }); - - let _sender = sender.clone(); - rt.spawn(async move { - loop { - _sender.send(AsyncHandlerMsg::UpdateToolbxes).await; - tokio::time::sleep(Duration::from_secs(10)).await; - } - }); - - AsyncHandler { _rt: rt, sender } - } - - fn send(&self, msg: Self::Msg) { - self.sender.blocking_send(msg).unwrap(); - } - - fn sender(&self) -> Self::Sender { - self.sender.clone() - } -} diff --git a/src/ui/components.rs b/src/ui/components.rs deleted file mode 100644 index 579706b..0000000 --- a/src/ui/components.rs +++ /dev/null @@ -1,11 +0,0 @@ -use relm4::RelmComponent; -use relm4::RelmMsgHandler; -use relm4::Sender; - -use super::app::model::AppModel; -use super::app::workers::AsyncHandler; - -#[derive(relm4::Components)] -pub struct AppComponents { - pub async_handler: RelmMsgHandler, -} diff --git a/src/ui/ui_strings.rs b/src/ui/ui_strings.rs deleted file mode 100644 index d98f952..0000000 --- a/src/ui/ui_strings.rs +++ /dev/null @@ -1,20 +0,0 @@ -pub const START_ICON: &str = r#"media-playback-start-symbolic"#; -pub const START_TOOLTIP: &str = r#"Start toolbox"#; - -pub const SHUTDOWN_ICON: &str = r#"system-shutdown-symbolic"#; -pub const SHUTDOWN_TOOLTIP: &str = r#"Stop toolbox"#; - -pub const UPDATE_ICON: &str = r#"software-update-available-symbolic"#; -pub const UPDATE_TOOLTIP: &str = r#"Update all applications inside of the toolbox"#; - -pub const APP_ICON: &str = r#"view-grid-symbolic"#; -pub const APP_TOOLTIP: &str = r#"Select applications to showup in the application menu"#; - -pub const TERMINAL_ICON: &str = r#"utilities-terminal-symbolic"#; -pub const TERMINAL_TOOLTIP: &str = r#"Open terminal inside of toolbox"#; - -pub const SETTINGS_ICON: &str = r#"applications-system-symbolic"#; -pub const SETTINGS_TOOLTIP: &str = r#"Open toolbox settings"#; - -pub const FOLDER_PICKER_ICON: &str = r#"folder-open-symbolic"#; -pub const FOLDER_PICKER_TOOLTIP: &str = r#"Select folder dialogue"#; diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index 45cefee..0000000 --- a/src/util.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod toolbx; diff --git a/src/util/toolbx.rs b/src/util/toolbx.rs deleted file mode 100644 index bb0a3f3..0000000 --- a/src/util/toolbx.rs +++ /dev/null @@ -1,427 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc}; - -#[derive(Debug, PartialEq)] -pub enum ToolbxError { - ParseStatusError(String), - JSONSerializationError(String), - CommandExecutionError(String), - CommandUnsuccessfulError(String), -} - -impl std::error::Error for ToolbxError {} - -impl Display for ToolbxError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ToolbxError::ParseStatusError(parse_error) => write!(f, "{}", parse_error), - ToolbxError::CommandExecutionError(command_exec_error) => { - write!(f, "{}", command_exec_error) - } - ToolbxError::JSONSerializationError(msg) => { - write!(f, "{}", msg) - } - ToolbxError::CommandUnsuccessfulError(command_unsuc_error) => { - write!(f, "{}", command_unsuc_error) - } - } - } -} - -#[derive(Debug, PartialEq, Clone)] -pub enum ToolbxStatus { - Running, - Configured, - Created, - Exited, -} - -impl Default for ToolbxStatus { - fn default() -> Self { - ToolbxStatus::Configured - } -} - -impl FromStr for ToolbxStatus { - type Err = ToolbxError; - - fn from_str(s: &str) -> Result { - match s { - "running" => Ok(ToolbxStatus::Running), - "configured" => Ok(ToolbxStatus::Configured), - "created" => Ok(ToolbxStatus::Created), - "exited" => Ok(ToolbxStatus::Exited), - s => Err(ToolbxError::ParseStatusError(format!( - "'{}' is not a valid toolbx status.", - s - ))), - } - } -} - -#[derive(Debug, PartialEq, Default, Clone)] -pub struct ToolbxContainer { - pub id: String, - pub name: String, - pub created: String, - pub status: ToolbxStatus, - pub image: String, -} - -pub type PodmanInspectArray = Vec; - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PodmanInspectInfo { - #[serde(rename = "Id")] - pub id: String, - #[serde(rename = "Created")] - pub created: String, - #[serde(rename = "State")] - pub state: PodManInspectState, - #[serde(rename = "Image")] - pub image: String, - #[serde(rename = "ImageName")] - pub image_name: String, - #[serde(rename = "Name")] - pub name: String, -} - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PodManInspectState { - #[serde(rename = "Status")] - pub status: String, -} - -pub enum ToolboxCreateParameter { - None, - Distro(String), - Image(String), - Release(String), -} - -impl ToolbxContainer { - pub fn new(name: String) -> ToolbxContainer { - ToolbxContainer { - name: name, - ..Default::default() - } - } - - pub fn create(name: String, parameter: ToolboxCreateParameter) { - todo!("Implement actual functionality to create toolbox via commandline") - } - - pub fn get_toolboxes() -> Vec { - let output = run_cmd_toolbx_list_containers(); - println!("{}", output); - parse_cmd_list_containers(output.as_str()) - } - - fn parse_status(output: &str) -> Result { - let result: Result = serde_json::from_str(output); - match result { - Ok(inspect_vec) => match inspect_vec.first() { - Some(info) => Ok(info.clone()), - None => Err(ToolbxError::JSONSerializationError( - "Inspect command returned empty vector.".to_string(), - )), - }, - Err(e) => Err(ToolbxError::JSONSerializationError(e.to_string())), - } - } - - pub fn update_status(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") - .arg("podman") - .arg("container") - .arg("inspect") - .arg(self.name.clone()) - .output() - .expect("Failed to execute command"); - - let output = String::from_utf8_lossy(&output.stdout).to_string(); - let inspect_result = ToolbxContainer::parse_status(output.as_str())?; - self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; - Ok(()) - } - - pub fn stop(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("stop") - .arg(self.name.clone()) - .output(); - - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); - - // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - //Fail: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } - - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Exited; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } - } - - pub fn start(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("start") - .arg(self.name.clone()) - .output(); - - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); - - // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - // Fail: status: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } - - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Running; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } - } -} - -#[test] -fn test_start_1non_existing_container() { - // TODO: create container that exists based on simple image - // run command - // delete container - //let tbx = ToolbxContainer{created: "".to_string(), id: "".to_string(), name: "latex".to_string(), image: "".to_string(), status: ToolbxStatus::Exited}; - - //tbx.stop(); -} - -#[test] -fn test_inspect_parsing() { - let podman_inspect = concat!( - "[{", - "\"Id\": \"ae05203091ab4cdf047a9aeba6af8a7bed8105f7f59d09a35d2b64c837ecac0d\",", - "\"Created\": \"2021-12-10T20:51:43.140418098+01:00\",", - "\"State\": {", - "\"Status\": \"running\"", - "},", - "\"Image\": \"ab8bc106d4a710a7a27c538762864610467b3559f80b413d30e0a1bfcfe272a5\",", - "\"ImageName\": \"registry.fedoraproject.org/fedora-toolbox:35\",", - "\"Name\": \"rust\"", - "}]" - ); - let inspect_info = ToolbxContainer::parse_status(podman_inspect).unwrap(); - assert_eq!("running", inspect_info.state.status); -} - -#[test] -fn test_start_non_existing_container() { - let name = "zy2lM6BdZoTnKHaVPkUJ".to_string(); - let mut tbx = ToolbxContainer { - created: "".to_string(), - id: "".to_string(), - name: name.clone(), - image: "".to_string(), - status: ToolbxStatus::Exited, - }; - - assert_eq!( - Err(ToolbxError::CommandUnsuccessfulError(format!( - "Error: no container with name or ID \"{}\" found: no such container\n", - name - ))), - tbx.start() - ); -} - -pub fn run_cmd_toolbx_list_containers() -> String { - let output = Command::new("flatpak-spawn") - .arg("--host") - .arg("toolbox") - .arg("list") - .arg("--containers") - .output() - .expect("Failed to execute command"); - - println!("{:?}", String::from_utf8_lossy(&output.stdout).to_string()); - - String::from_utf8_lossy(&output.stdout).to_string() -} - -#[test] -#[ignore] -fn test_cmd_list_containers() { - // This requires toolbx to be installed - let toolbox_cmd_container_header = - "CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME"; - assert!(run_cmd_toolbx_list_containers().starts_with(toolbox_cmd_container_header)); -} - -fn tokenize_line_list_containers(line: &str) -> Vec { - let mut tokens = Vec::::new(); - let mut current_token = Vec::::new(); - - let mut whitespace_section = false; - - let mut iter = line.chars().peekable(); - while let Some(&c) = iter.peek() { - match (whitespace_section, c) { - (false, ' ') => { - iter.next(); - if Some(' ') == iter.peek().map(|x| x.clone()) { - whitespace_section = true; - } else { - current_token.push(c); - } - } - (true, ' ') => { - iter.next(); - } - (true, c) => { - whitespace_section = false; - tokens.push(current_token.into_iter().collect()); - current_token = Vec::new(); - current_token.push(c); - iter.next(); - } - (false, c) => { - current_token.push(c); - iter.next(); - } - } - } - tokens.push(current_token.into_iter().collect()); - - tokens -} - -#[test] -fn test_tokenize_line_list_containers() { - let toolbox_cmd_container_header = "ae05203091ab rust 4 months ago \ - running registry.fedoraproject.org/fedora-toolbox:35"; - - let target = vec![ - "ae05203091ab", - "rust", - "4 months ago", - "running", - "registry.fedoraproject.org/fedora-toolbox:35", - ]; - let result = tokenize_line_list_containers(toolbox_cmd_container_header); - assert_eq!(target, result); -} - -fn parse_line_list_containers(line: &str) -> Result { - let tokens = tokenize_line_list_containers(line); - if tokens.len() != 5 { - panic! {"Expected 5 tokens found {} in {:?}", tokens.len(), tokens}; - } - Ok(ToolbxContainer { - id: tokens[0].clone(), - name: tokens[1].clone(), - created: tokens[2].clone(), - status: ToolbxStatus::from_str(&tokens[3])?, - image: tokens[4].clone(), - }) -} - -#[test] -fn test_parse_line_list_containers() { - let toolbox_cmd_container_header = "ae05203091ab rust 4 months ago \ - running registry.fedoraproject.org/fedora-toolbox:35"; - - let target = ToolbxContainer { - id: "ae05203091ab".to_string(), - name: "rust".to_string(), - created: "4 months ago".to_string(), - status: ToolbxStatus::Running, - image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), - }; - let result = parse_line_list_containers(toolbox_cmd_container_header); - assert_eq!(target, result.unwrap()); -} - -fn parse_cmd_list_containers(output: &str) -> Vec { - let lines = output.trim().split("\n").skip(1); - println!("{:?}", lines); - lines.map(parse_line_list_containers).flatten().collect() -} - -#[test] -fn test_parse_cmd_list_containers() { - // This requires toolbx to be installed - let toolbox_cmd_container_header = concat!( - "CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME\n", - "cee1002b5f0b fedora-toolbox-35 2 months ago exited registry.fedoraproject.org/fedora-toolbox:35\n", - "9b611313bf65 latex 4 months ago configured registry.fedoraproject.org/fedora-toolbox:35\n", - "1235203091ab website 4 months ago created registry.fedoraproject.org/fedora-toolbox:35\n", - "ae05203091ab rust 4 months ago running registry.fedoraproject.org/fedora-toolbox:35\n" - ); - - let desired_result = vec![ - ToolbxContainer { - id: "cee1002b5f0b".to_string(), - name: "fedora-toolbox-35".to_string(), - created: "2 months ago".to_string(), - status: ToolbxStatus::Exited, - image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), - }, - ToolbxContainer { - id: "9b611313bf65".to_string(), - name: "latex".to_string(), - created: "4 months ago".to_string(), - status: ToolbxStatus::Configured, - image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), - }, - ToolbxContainer { - id: "1235203091ab".to_string(), - name: "website".to_string(), - created: "4 months ago".to_string(), - status: ToolbxStatus::Created, - image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), - }, - ToolbxContainer { - id: "ae05203091ab".to_string(), - name: "rust".to_string(), - created: "4 months ago".to_string(), - status: ToolbxStatus::Running, - image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), - }, - ]; - - for (result, desired) in zip( - parse_cmd_list_containers(toolbox_cmd_container_header).iter(), - desired_result.iter(), - ) { - assert_eq!(result, desired) - } -} From fbf68d69a332810d74a05709b2289ae4f313a8a6 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Mon, 26 Feb 2024 20:11:47 +0100 Subject: [PATCH 02/36] remove sh file for building and rely on builder --- README.md | 16 +++++++--------- build_install_local.sh | 2 -- 2 files changed, 7 insertions(+), 11 deletions(-) delete mode 100755 build_install_local.sh diff --git a/README.md b/README.md index f3ecb95..7bed2cb 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# Toolbx Tuner +# Toolbox Tuner -Toolbx Tuner is a tool to improve the experience with [toolbx](https://containertoolbx.org/). +Toolbox Tuner is a tool to improve the experience with [toolbox](https://containertoolbx.org/). -![image](https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_light.png) -![image](https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_dark.png) +![image](https://media.githubusercontent.com/media/13hannes11/toolbox-tuner/main/data/resources/screenshots/main_light.png) +![image](https://media.githubusercontent.com/media/13hannes11/toolbox-tuner/main/data/resources/screenshots/main_dark.png) ## Project Roadmap The project is currently only an mvp that only is able to list toolboxes and launch a terminal inside of them. - [x] UI prototype -- [x] [Continuous development releases](https://github.com/13hannes11/toolbx-tuner/releases/tag/dev) +- [x] [Continuous development releases](https://github.com/13hannes11/toolbox-tuner/releases/tag/dev) - [x] Flatpak support - [ ] Publish on Flathub ## Installing the application -The application as of now is only available as a development build. You can download it [here](https://github.com/13hannes11/toolbx-tuner/releases/tag/dev) but be aware of unfinished features and possible instabilities. +The application as of now is only available as a development build. You can download it [here](https://github.com/13hannes11/toolbox-tuner/releases/tag/dev) but be aware of unfinished features and possible instabilities. ## Compiling Source @@ -33,9 +33,7 @@ This project now uses *Gnome Builder* as main build tool and the Flatpak toolcha 2. `flatpak install org.gnome.Sdk` 3. `flatpak install org.freedesktop.Sdk.Extension.rust-stable` 2. Compile with: - * Flatpak Builder by opening the project folder and pressing run or - * Run `build_install_local.sh` - + * Flatpak Builder by opening the project folder and pressing run ### Traditional Compilation diff --git a/build_install_local.sh b/build_install_local.sh deleted file mode 100755 index 65cec68..0000000 --- a/build_install_local.sh +++ /dev/null @@ -1,2 +0,0 @@ -flatpak run org.flatpak.Builder --user --install --force-clean flatpak_app build-aux/org.kuchelmeister.ToolbxTuner.Devel.json - From 9704b8f166033dbb275fe5dce87b73ec32a267ac Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Mon, 26 Feb 2024 20:53:56 +0100 Subject: [PATCH 03/36] run cargo fmt --- src/app.rs | 1 - src/modals/about.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 043ac57..b59ba3f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -163,4 +163,3 @@ impl AppWidgets { } } } - diff --git a/src/modals/about.rs b/src/modals/about.rs index d3f070e..c388ab1 100644 --- a/src/modals/about.rs +++ b/src/modals/about.rs @@ -47,4 +47,3 @@ impl SimpleComponent for AboutDialog { dialog.present(); } } - From 06e9f449950456242dafc82252daf830c6be85c3 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Mon, 26 Feb 2024 20:54:37 +0100 Subject: [PATCH 04/36] fix pipeline --- .github/workflows/build_and_publish.yml | 38 ------------------------- .github/workflows/ci.yml | 2 +- 2 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 .github/workflows/build_and_publish.yml diff --git a/.github/workflows/build_and_publish.yml b/.github/workflows/build_and_publish.yml deleted file mode 100644 index edfc5cf..0000000 --- a/.github/workflows/build_and_publish.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Build (tag and pull_request) and publish (tag) - -on: - push: - tags: - - v*.*.* - pull_request: -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build - run: docker-compose -f containers/docker-compose.yml up - - name: Show dir - run: ls - - name: Upload Artifact - uses: actions/upload-artifact@v2.3.1 - with: - name: executables - path: | - **.AppImage - - publish: - needs: [build] - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/v') - steps: - - uses: actions/download-artifact@v2 - - uses: "marvinpinto/action-automatic-releases@v1.2.1" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - prerelease: false - files: | - **/*.AppImage diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22d0c9f..cb447d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 with: bundle: toolbxtuner.flatpak - manifest-path: build-aux/org.kuchelmeister.ToolbxTuner.Devel.json + manifest-path: build-aux/org.kuchelmeister.ToolboxTuner.Devel.json run-tests: true cache-key: flatpak-builder-${{ github.sha }} - name: ls From 914b5899f104fb93b9ec280a35176fde927799d7 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Mon, 26 Feb 2024 23:40:54 +0100 Subject: [PATCH 05/36] add unsupported dialogue to be shown if not all prerequisits are fulfilled --- Cargo.lock | 173 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/app.rs | 15 +++- src/main.rs | 1 + src/modals/mod.rs | 1 + src/modals/unsupported.rs | 49 +++++++++++ 6 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/modals/unsupported.rs diff --git a/Cargo.lock b/Cargo.lock index 4101e25..467941b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,12 @@ version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cairo-rs" version = "0.17.10" @@ -129,6 +135,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -145,6 +160,16 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flume" version = "0.10.14" @@ -555,6 +580,24 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gvdb" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7139233c0ecb66f285c47a3c1c02b35c8d52a42ca4c7448d0163e5637bb4bd3" +dependencies = [ + "byteorder", + "flate2", + "lazy_static", + "memmap2", + "quick-xml", + "safe-transmute", + "serde", + "serde_json", + "walkdir", + "zvariant", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -583,6 +626,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + [[package]] name = "js-sys" version = "0.3.68" @@ -681,6 +730,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -885,6 +943,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.35" @@ -941,6 +1009,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "relm4-icons" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e28bcc718a587bcfa31b034e0b8f4efe5b70e945b7de9d7d154b45357a0dadc" +dependencies = [ + "gtk4", + "gvdb", +] + [[package]] name = "relm4-macros" version = "0.6.2" @@ -967,6 +1045,27 @@ dependencies = [ "semver", ] +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "safe-transmute" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a01dab6acf992653be49205bdd549f32f17cb2803e8eacf1560bf97259aae8" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -999,6 +1098,17 @@ dependencies = [ "syn 2.0.51", ] +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.5" @@ -1041,6 +1151,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "1.0.109" @@ -1180,6 +1296,7 @@ version = "0.0.1" dependencies = [ "gettext-rs", "relm4", + "relm4-icons", "tracing", "tracing-subscriber", ] @@ -1265,6 +1382,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1341,6 +1468,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1364,3 +1500,40 @@ checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178" dependencies = [ "memchr", ] + +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml index 325cf6f..b9b1df6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ gettext-rs = { version = "0.7", features = ["gettext-system"] } tracing = "0.1" tracing-subscriber = "0.3" relm4 = { version = "0.6.0", features = ["libadwaita", "gnome_44"] } +relm4-icons = { version = "0.6.0", features = ["issue"] } diff --git a/src/app.rs b/src/app.rs index b59ba3f..3f7a361 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,8 +11,10 @@ use gtk::{gio, glib}; use crate::config::{APP_ID, PROFILE}; use crate::modals::about::AboutDialog; +use crate::modals::unsupported::UnsupportedDialog; pub(super) struct App { + unsupported_dialog: Controller, about_dialog: Controller, } @@ -96,7 +98,15 @@ impl SimpleComponent for App { .launch(()) .detach(); - let model = Self { about_dialog }; + let unsupported_dialog = UnsupportedDialog::builder() + .transient_for(root) + .launch(()) + .detach(); + + let model = Self { + about_dialog, + unsupported_dialog, + }; let widgets = view_output!(); @@ -116,6 +126,9 @@ impl SimpleComponent for App { }) }; + let sender = model.unsupported_dialog.sender().clone(); + sender.send(()).unwrap(); + actions.add_action(shortcuts_action); actions.add_action(about_action); actions.register_for_widget(&widgets.main_window); diff --git a/src/main.rs b/src/main.rs index f2739fa..0cbb30f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,6 +42,7 @@ fn main() { app.set_accelerators_for_action::(&["q"]); let app = RelmApp::from_app(app); + relm4_icons::initialize_icons(); app.run::(()); } diff --git a/src/modals/mod.rs b/src/modals/mod.rs index ced7521..5e3d91c 100644 --- a/src/modals/mod.rs +++ b/src/modals/mod.rs @@ -1 +1,2 @@ pub mod about; +pub mod unsupported; diff --git a/src/modals/unsupported.rs b/src/modals/unsupported.rs new file mode 100644 index 0000000..79200f7 --- /dev/null +++ b/src/modals/unsupported.rs @@ -0,0 +1,49 @@ +use adw::StatusPage; +use gtk::prelude::GtkWindowExt; +use relm4::view; +use relm4::{adw, gtk, ComponentParts, ComponentSender, SimpleComponent}; +use relm4_icons::icon_name; +pub struct UnsupportedDialog {} + +impl SimpleComponent for UnsupportedDialog { + type Init = (); + type Widgets = adw::Window; + type Input = (); + type Output = (); + type Root = adw::Window; + + fn init_root() -> Self::Root { + adw::Window::builder().build() + } + + fn init( + _: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self {}; + + view! { + widgets = root.clone() { + set_hide_on_close: true, + set_modal: true, + set_resizable: false, + set_default_width: 400, + + StatusPage::new() { + set_icon_name: Some(icon_name::ISSUE), + set_title: "Missing requirements", + set_description: Some("Make sure Toolbx and Gnome Terminal are installed."), + set_child: Some(>k::Button::with_label("Goodbye!")), + }, + } + } + // TODO: when dialgue closes close application + // TODO: close application on button press + ComponentParts { model, widgets } + } + + fn update_view(&self, dialog: &mut Self::Widgets, _sender: ComponentSender) { + dialog.present(); + } +} From d9130b8e42ab128b784f8a1d51eebb9adce2ad04 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 27 Feb 2024 21:39:02 +0100 Subject: [PATCH 06/36] update actions to newer versions --- .github/workflows/ci.yml | 6 +++--- hooks/pre-commit.hook | 0 2 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 hooks/pre-commit.hook diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb447d3..e21d694 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ name: CI jobs: rustfmt: name: Rustfmt - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 with: @@ -26,9 +26,9 @@ jobs: flatpak: name: Flatpak - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 container: - image: bilelmoussaoui/flatpak-github-actions:gnome-42 + image: bilelmoussaoui/flatpak-github-actions:gnome-45 options: --privileged steps: - name: Install git-lfs diff --git a/hooks/pre-commit.hook b/hooks/pre-commit.hook old mode 100644 new mode 100755 From a2f544dac53283c7ce889a86611daa008fe15640 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Wed, 28 Feb 2024 21:07:25 +0100 Subject: [PATCH 07/36] add closing functionality to dialgoue --- src/app.rs | 5 ++++- src/modals/unsupported.rs | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index 3f7a361..a531bc0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -12,6 +12,7 @@ use gtk::{gio, glib}; use crate::config::{APP_ID, PROFILE}; use crate::modals::about::AboutDialog; use crate::modals::unsupported::UnsupportedDialog; +use crate::modals::unsupported::UnsupportedDialogOutput; pub(super) struct App { unsupported_dialog: Controller, @@ -101,7 +102,9 @@ impl SimpleComponent for App { let unsupported_dialog = UnsupportedDialog::builder() .transient_for(root) .launch(()) - .detach(); + .forward(sender.input_sender(), |msg| match msg { + UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, + }); let model = Self { about_dialog, diff --git a/src/modals/unsupported.rs b/src/modals/unsupported.rs index 79200f7..67f769e 100644 --- a/src/modals/unsupported.rs +++ b/src/modals/unsupported.rs @@ -1,15 +1,21 @@ use adw::StatusPage; -use gtk::prelude::GtkWindowExt; +use gtk::prelude::{ButtonExt, GtkWindowExt}; use relm4::view; use relm4::{adw, gtk, ComponentParts, ComponentSender, SimpleComponent}; use relm4_icons::icon_name; + pub struct UnsupportedDialog {} +#[derive(Debug)] +pub enum UnsupportedDialogOutput { + CloseApplication, +} + impl SimpleComponent for UnsupportedDialog { type Init = (); type Widgets = adw::Window; type Input = (); - type Output = (); + type Output = UnsupportedDialogOutput; type Root = adw::Window; fn init_root() -> Self::Root { @@ -19,7 +25,7 @@ impl SimpleComponent for UnsupportedDialog { fn init( _: Self::Init, root: &Self::Root, - _sender: ComponentSender, + sender: ComponentSender, ) -> ComponentParts { let model = Self {}; @@ -30,16 +36,22 @@ impl SimpleComponent for UnsupportedDialog { set_resizable: false, set_default_width: 400, + StatusPage::new() { set_icon_name: Some(icon_name::ISSUE), set_title: "Missing requirements", - set_description: Some("Make sure Toolbx and Gnome Terminal are installed."), - set_child: Some(>k::Button::with_label("Goodbye!")), + set_description: Some("Make sure Toolbox and Gnome Terminal are installed."), + + #[name = "btn_close"] + gtk::Button::with_label("Goodbye!") { + connect_clicked[sender] => move |_| { + sender.output(UnsupportedDialogOutput::CloseApplication).unwrap() + }, + }, }, } } - // TODO: when dialgue closes close application - // TODO: close application on button press + ComponentParts { model, widgets } } From c9e8e9e22bf92d181ead352f1aa83d21ca174686 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 29 Feb 2024 18:04:41 +0100 Subject: [PATCH 08/36] move runtime to 45 --- build-aux/org.kuchelmeister.ToolboxTuner.Devel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json index 9ce4cd4..14a06c3 100644 --- a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json +++ b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json @@ -1,7 +1,7 @@ { "id": "org.kuchelmeister.ToolboxTuner.Devel", "runtime": "org.gnome.Platform", - "runtime-version": "44", + "runtime-version": "45", "sdk": "org.gnome.Sdk", "sdk-extensions": [ "org.freedesktop.Sdk.Extension.rust-stable", From a8bde9b439ed1d56d7f550a4c989a90a53222299 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 29 Feb 2024 18:39:26 +0100 Subject: [PATCH 09/36] add command to check if required tools are installed --- src/app.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/app.rs b/src/app.rs index a531bc0..9243526 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,7 +1,7 @@ use relm4::{ actions::{RelmAction, RelmActionGroup}, adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender, - Controller, SimpleComponent, + Controller, }; use gtk::prelude::{ @@ -24,15 +24,21 @@ pub(super) enum AppMsg { Quit, } +#[derive(Debug)] +pub(super) enum AppCommandMsg { + PrerequisitsInstalled(bool), +} + relm4::new_action_group!(pub(super) WindowActionGroup, "win"); //relm4::new_stateless_action!(PreferencesAction, WindowActionGroup, "preferences"); relm4::new_stateless_action!(pub(super) ShortcutsAction, WindowActionGroup, "show-help-overlay"); relm4::new_stateless_action!(AboutAction, WindowActionGroup, "about"); #[relm4::component(pub)] -impl SimpleComponent for App { +impl Component for App { type Init = (); type Input = AppMsg; + type CommandOutput = AppCommandMsg; type Output = (); type Widgets = AppWidgets; @@ -129,8 +135,10 @@ impl SimpleComponent for App { }) }; - let sender = model.unsupported_dialog.sender().clone(); - sender.send(()).unwrap(); + sender.spawn_oneshot_command(|| { + // TODO: actually check for compatibility + AppCommandMsg::PrerequisitsInstalled(true) + }); actions.add_action(shortcuts_action); actions.add_action(about_action); @@ -141,12 +149,28 @@ impl SimpleComponent for App { ComponentParts { model, widgets } } - fn update(&mut self, message: Self::Input, _sender: ComponentSender) { + fn update(&mut self, message: Self::Input, _sender: ComponentSender, _root: &Self::Root) { match message { AppMsg::Quit => main_application().quit(), } } + fn update_cmd( + &mut self, + message: Self::CommandOutput, + _sender: ComponentSender, + _: &Self::Root, + ) { + match message { + AppCommandMsg::PrerequisitsInstalled(false) => { + self.unsupported_dialog.sender().clone().send(()).unwrap() + } + AppCommandMsg::PrerequisitsInstalled(true) => { + // TODO: start process of fetching toolboxes + } + } + } + fn shutdown(&mut self, widgets: &mut Self::Widgets, _output: relm4::Sender) { widgets.save_window_size().unwrap(); } From da5fcc988784815aa52ae9036818f5a1625e8a4b Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sat, 2 Mar 2024 19:18:18 +0100 Subject: [PATCH 10/36] added simple factory --- src/app.rs | 19 +++++++--- src/factories/container_list.rs | 64 +++++++++++++++++++++++++++++++++ src/factories/mod.rs | 1 + src/main.rs | 2 ++ 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/factories/container_list.rs create mode 100644 src/factories/mod.rs diff --git a/src/app.rs b/src/app.rs index 9243526..de65a92 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,3 +1,4 @@ +use relm4::factory::FactoryVecDeque; use relm4::{ actions::{RelmAction, RelmActionGroup}, adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender, @@ -10,6 +11,7 @@ use gtk::prelude::{ use gtk::{gio, glib}; use crate::config::{APP_ID, PROFILE}; +use crate::factories::container_list::Container; use crate::modals::about::AboutDialog; use crate::modals::unsupported::UnsupportedDialog; use crate::modals::unsupported::UnsupportedDialogOutput; @@ -17,10 +19,11 @@ use crate::modals::unsupported::UnsupportedDialogOutput; pub(super) struct App { unsupported_dialog: Controller, about_dialog: Controller, + containers: FactoryVecDeque, } #[derive(Debug)] -pub(super) enum AppMsg { +pub enum AppMsg { Quit, } @@ -85,10 +88,10 @@ impl Component for App { } }, - gtk::Label { - set_label: "Hello world!", - add_css_class: "title-header", - set_vexpand: true, + + #[local_ref] + container_box -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, } } @@ -112,11 +115,16 @@ impl Component for App { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); + let mut containers = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + containers.guard().push_back(3); + let model = Self { about_dialog, unsupported_dialog, + containers, }; + let container_box = model.containers.widget(); let widgets = view_output!(); let mut actions = RelmActionGroup::::new(); @@ -203,3 +211,4 @@ impl AppWidgets { } } } + diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs new file mode 100644 index 0000000..02f9fe2 --- /dev/null +++ b/src/factories/container_list.rs @@ -0,0 +1,64 @@ +use crate::app::AppMsg; +use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use relm4::factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent}; + +#[derive(Debug)] +pub struct Container { + value: u8, +} + +#[derive(Debug)] +pub enum ContainerMsg { + Start, +} + +#[relm4::factory(pub)] +impl FactoryComponent for Container { + type Init = u8; + type Input = ContainerMsg; + type Output = (); + type CommandOutput = (); + type Widgets = ContainerWidgets; + type ParentInput = AppMsg; + type ParentWidget = gtk::Box; + + view! { + root = gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + + #[name(label)] + gtk::Label { + #[watch] + set_label: &self.value.to_string(), + set_width_chars: 3, + }, + + #[name(add_button)] + gtk::Button { + set_label: "+", + connect_clicked => ContainerMsg::Start, + }, + + #[name(remove_button)] + gtk::Button { + set_label: "-", + connect_clicked => ContainerMsg::Start, + }, + } + } + + fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { + Self { value } + } + + fn update(&mut self, msg: Self::Input, _sender: FactorySender) { + match msg { + ContainerMsg::Start => { + self.value = self.value.wrapping_add(1); + } + } + } +} + diff --git a/src/factories/mod.rs b/src/factories/mod.rs new file mode 100644 index 0000000..3bda8c0 --- /dev/null +++ b/src/factories/mod.rs @@ -0,0 +1 @@ +pub mod container_list; diff --git a/src/main.rs b/src/main.rs index 0cbb30f..a190548 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #[rustfmt::skip] mod config; mod app; +mod factories; mod modals; mod setup; @@ -46,3 +47,4 @@ fn main() { app.run::(()); } + From 3b20535b5a41c8cfa3c6a40a10f0c60efb06a0cf Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sat, 2 Mar 2024 19:34:02 +0100 Subject: [PATCH 11/36] move factory to use listbox --- src/app.rs | 14 +++++++++----- src/factories/container_list.rs | 22 +++++++++------------- src/main.rs | 1 - 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/app.rs b/src/app.rs index de65a92..d4fff48 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,6 @@ +use crate::gtk::Align; use relm4::factory::FactoryVecDeque; +use relm4::RelmWidgetExt; use relm4::{ actions::{RelmAction, RelmActionGroup}, adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender, @@ -89,10 +91,13 @@ impl Component for App { }, + #[local_ref] - container_box -> gtk::Box { - set_orientation: gtk::Orientation::Vertical, - } + container_box -> gtk::ListBox { + set_valign: Align::Start, + set_margin_all: 30, + set_css_classes: &["boxed-list"], + }, } } @@ -115,7 +120,7 @@ impl Component for App { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); - let mut containers = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + let mut containers = FactoryVecDeque::new(gtk::ListBox::default(), sender.input_sender()); containers.guard().push_back(3); let model = Self { @@ -211,4 +216,3 @@ impl AppWidgets { } } } - diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 02f9fe2..2abbae4 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,5 +1,8 @@ use crate::app::AppMsg; use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use relm4::adw; +use relm4::adw::prelude::ActionRowExt; +use relm4::adw::prelude::PreferencesRowExt; use relm4::factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque}; use relm4::{gtk, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent}; @@ -21,28 +24,22 @@ impl FactoryComponent for Container { type CommandOutput = (); type Widgets = ContainerWidgets; type ParentInput = AppMsg; - type ParentWidget = gtk::Box; + type ParentWidget = gtk::ListBox; view! { - root = gtk::Box { - set_orientation: gtk::Orientation::Horizontal, - set_spacing: 10, + root = adw::ActionRow { + #[watch] + set_title: &self.value.to_string(), - #[name(label)] - gtk::Label { - #[watch] - set_label: &self.value.to_string(), - set_width_chars: 3, - }, #[name(add_button)] - gtk::Button { + add_prefix = >k::Button { set_label: "+", connect_clicked => ContainerMsg::Start, }, #[name(remove_button)] - gtk::Button { + add_suffix = >k::Button { set_label: "-", connect_clicked => ContainerMsg::Start, }, @@ -61,4 +58,3 @@ impl FactoryComponent for Container { } } } - diff --git a/src/main.rs b/src/main.rs index a190548..c660f2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,4 +47,3 @@ fn main() { app.run::(()); } - From 5c5241cdc1c75df535ac043a1acb8f9e299eaa5d Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 10 Mar 2024 20:36:35 +0100 Subject: [PATCH 12/36] convert to hashmap isntead of list --- src/app.rs | 9 +++++---- src/factories/container_list.rs | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app.rs b/src/app.rs index d4fff48..c50d261 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,5 @@ use crate::gtk::Align; -use relm4::factory::FactoryVecDeque; +use relm4::factory::FactoryHashMap; use relm4::RelmWidgetExt; use relm4::{ actions::{RelmAction, RelmActionGroup}, @@ -21,7 +21,7 @@ use crate::modals::unsupported::UnsupportedDialogOutput; pub(super) struct App { unsupported_dialog: Controller, about_dialog: Controller, - containers: FactoryVecDeque, + containers: FactoryHashMap, } #[derive(Debug)] @@ -120,8 +120,9 @@ impl Component for App { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); - let mut containers = FactoryVecDeque::new(gtk::ListBox::default(), sender.input_sender()); - containers.guard().push_back(3); + let mut containers = FactoryHashMap::new(gtk::ListBox::default(), sender.input_sender()); + containers.insert("123".to_string(), 2); + containers.insert("124".to_string(), 3); let model = Self { about_dialog, diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 2abbae4..e378533 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -8,6 +8,7 @@ use relm4::{gtk, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, Simple #[derive(Debug)] pub struct Container { + hash: String, value: u8, } @@ -25,29 +26,27 @@ impl FactoryComponent for Container { type Widgets = ContainerWidgets; type ParentInput = AppMsg; type ParentWidget = gtk::ListBox; + type Index = String; view! { root = adw::ActionRow { #[watch] - set_title: &self.value.to_string(), - + set_title: &self.hash, #[name(add_button)] - add_prefix = >k::Button { - set_label: "+", - connect_clicked => ContainerMsg::Start, - }, - - #[name(remove_button)] add_suffix = >k::Button { - set_label: "-", + #[watch] + set_label: &self.value.to_string(), connect_clicked => ContainerMsg::Start, }, } } - fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { - Self { value } + fn init_model(value: Self::Init, index: &Self::Index, _sender: FactorySender) -> Self { + Self { + hash: index.clone(), + value, + } } fn update(&mut self, msg: Self::Input, _sender: FactorySender) { From 9e95347226fa38665cee76da197502ba73ca4e96 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 10 Mar 2024 20:43:38 +0100 Subject: [PATCH 13/36] add json~ to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 142a702..3e4ae1e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ /.vscode .flatpak-builder/ *.AppImage +*.json~ From 8c3db04c3ece3e05f5ba48dc890e352df1e4ffd1 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 17 Mar 2024 17:37:38 +0100 Subject: [PATCH 14/36] migrate to relm 0.8.1 --- Cargo.lock | 383 +++++++++++++++++--------------- Cargo.toml | 4 +- icons.toml | 7 + src/app.rs | 12 +- src/factories/container_list.rs | 1 - src/main.rs | 30 ++- src/modals/about.rs | 2 +- src/modals/unsupported.rs | 6 +- src/setup.rs | 39 ---- 9 files changed, 250 insertions(+), 234 deletions(-) create mode 100644 icons.toml delete mode 100644 src/setup.rs diff --git a/Cargo.lock b/Cargo.lock index 467941b..8f7014f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,20 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" - -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.51", -] +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "autocfg" @@ -66,9 +55,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block" @@ -78,9 +67,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byteorder" @@ -90,23 +79,22 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cairo-rs" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" +checksum = "2650f66005301bd33cc486dec076e1293c4cecf768bc7ba9bf5d2b1be339b99c" dependencies = [ "bitflags", "cairo-sys-rs", "glib", "libc", - "once_cell", "thiserror", ] [[package]] name = "cairo-sys-rs" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" +checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64" dependencies = [ "glib-sys", "libc", @@ -115,9 +103,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.88" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-expr" @@ -172,14 +160,13 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.14" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ "futures-core", "futures-sink", "nanorand", - "pin-project", "spin", ] @@ -245,7 +232,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", ] [[package]] @@ -280,23 +267,21 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" +checksum = "f6a23f8a0b5090494fd04924662d463f8386cc678dd3915015a838c1a3679b92" dependencies = [ - "bitflags", "gdk-pixbuf-sys", "gio", "glib", "libc", - "once_cell", ] [[package]] name = "gdk-pixbuf-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" +checksum = "3dcbd04c1b2c4834cc008b4828bc917d062483b88d26effde6342e5622028f96" dependencies = [ "gio-sys", "glib-sys", @@ -307,11 +292,10 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" +checksum = "9100b25604183f2fd97f55ef087fae96ab4934d7215118a35303e422688e6e4b" dependencies = [ - "bitflags", "cairo-rs", "gdk-pixbuf", "gdk4-sys", @@ -323,9 +307,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" +checksum = "d0b76874c40bb8d1c7d03a7231e23ac75fa577a456cd53af32ec17ec8f121626" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -379,11 +363,10 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "gio" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" +checksum = "2eae10b27b6dd27e22ed0d812c6387deba295e6fc004a8b379e459b663b05a02" dependencies = [ - "bitflags", "futures-channel", "futures-core", "futures-io", @@ -391,7 +374,6 @@ dependencies = [ "gio-sys", "glib", "libc", - "once_cell", "pin-project-lite", "smallvec", "thiserror", @@ -399,22 +381,22 @@ dependencies = [ [[package]] name = "gio-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" +checksum = "bcf8e1d9219bb294636753d307b030c1e8a032062cba74f493c431a5c8b81ce4" dependencies = [ "glib-sys", "gobject-sys", "libc", "system-deps", - "winapi", + "windows-sys", ] [[package]] name = "glib" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b" +checksum = "ab9e86540b5d8402e905ad4ce7d6aa544092131ab564f3102175af176b90a053" dependencies = [ "bitflags", "futures-channel", @@ -428,31 +410,28 @@ dependencies = [ "gobject-sys", "libc", "memchr", - "once_cell", "smallvec", "thiserror", ] [[package]] name = "glib-macros" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" +checksum = "0f5897ca27a83e4cdc7b4666850bade0a2e73e17689aabafcc9acddad9d823b8" dependencies = [ - "anyhow", "heck", - "proc-macro-crate", - "proc-macro-error", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] name = "glib-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0" +checksum = "630f097773d7c7a0bb3258df4e8157b47dc98bbfa0e60ad9ab56174813feced4" dependencies = [ "libc", "system-deps", @@ -460,9 +439,9 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" +checksum = "c85e2b1080b9418dd0c58b498da3a5c826030343e0ef07bde6a955d28de54979" dependencies = [ "glib-sys", "libc", @@ -471,9 +450,9 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" +checksum = "99e4d388e96c5f29e2b2f67045d229ddf826d0a8d6d282f94ed3b34452222c91" dependencies = [ "glib", "graphene-sys", @@ -482,9 +461,9 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" +checksum = "236ed66cc9b18d8adf233716f75de803d0bf6fc806f60d14d948974a12e240d0" dependencies = [ "glib-sys", "libc", @@ -494,11 +473,10 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" +checksum = "c65036fc8f99579e8cb37b12487969b707ab23ec8ab953682ff347cbd15d396e" dependencies = [ - "bitflags", "cairo-rs", "gdk4", "glib", @@ -510,9 +488,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" +checksum = "bd24c814379f9c3199dc53e52253ee8d0f657eae389ab282c330505289d24738" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -526,11 +504,10 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.6.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" +checksum = "aa82753b8c26277e4af1446c70e35b19aad4fb794a7b143859e7eeb9a4025d83" dependencies = [ - "bitflags", "cairo-rs", "field-offset", "futures-channel", @@ -543,18 +520,17 @@ dependencies = [ "gtk4-macros", "gtk4-sys", "libc", - "once_cell", "pango", ] [[package]] name = "gtk4-macros" -version = "0.6.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" +checksum = "40300bf071d2fcd4c94eacc09e84ec6fe73129d2ceb635cf7e55b026b5443567" dependencies = [ "anyhow", - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro-error", "proc-macro2", "quote", @@ -563,9 +539,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" +checksum = "0db1b104138f087ccdc81d2c332de5dd049b89de3d384437cc1093b17cd2da18" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -582,14 +558,12 @@ dependencies = [ [[package]] name = "gvdb" -version = "0.4.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7139233c0ecb66f285c47a3c1c02b35c8d52a42ca4c7448d0163e5637bb4bd3" +checksum = "0bb9136c388a1e7b3017d18fe7c2f263b0a2b13f215c48e8eb44935d413ce0f9" dependencies = [ "byteorder", "flate2", - "lazy_static", - "memmap2", "quick-xml", "safe-transmute", "serde", @@ -612,15 +586,15 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown", @@ -634,9 +608,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -649,11 +623,10 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libadwaita" -version = "0.4.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" +checksum = "91b4990248b9e1ec5e72094a2ccaea70ec3809f88f6fd52192f2af306b87c5d9" dependencies = [ - "bitflags", "gdk-pixbuf", "gdk4", "gio", @@ -666,9 +639,9 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.4.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" +checksum = "23a748e4e92be1265cd9e93d569c0b5dfc7814107985aa6743d670ab281ea1a8" dependencies = [ "gdk4-sys", "gio-sys", @@ -711,9 +684,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "malloc_buf" @@ -730,15 +703,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "memmap2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.9.0" @@ -838,23 +802,21 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pango" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" +checksum = "7809e8af4df8d024a066106b72ca6bc7253a484ae3867041a96103ef8a13188d" dependencies = [ - "bitflags", "gio", "glib", "libc", - "once_cell", "pango-sys", ] [[package]] name = "pango-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" +checksum = "f52ef6a881c19fbfe3b1484df5cad411acaaba29dbec843941c3110d19f340ea" dependencies = [ "glib-sys", "gobject-sys", @@ -862,26 +824,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.51", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -910,6 +852,15 @@ dependencies = [ "toml_edit 0.19.15", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -936,18 +887,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", "serde", @@ -976,9 +927,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -993,11 +944,10 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relm4" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81" +checksum = "e6e0e187b58db367305e8486d3228158251da1c8ba1e18baa9de61894e822649" dependencies = [ - "async-trait", "flume", "fragile", "futures", @@ -1011,23 +961,25 @@ dependencies = [ [[package]] name = "relm4-icons" -version = "0.6.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e28bcc718a587bcfa31b034e0b8f4efe5b70e945b7de9d7d154b45357a0dadc" +checksum = "8603f50e9ed5ca2e3759a9c6033e4058c7b984f1bd22b1fc3b1a162c5612eb64" dependencies = [ "gtk4", "gvdb", + "serde", + "toml", ] [[package]] name = "relm4-macros" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" +checksum = "0774e846889823aa5766f5b62cface3189a5b36280e65b2faaa6df0319da1726" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", ] [[package]] @@ -1095,7 +1047,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", ] [[package]] @@ -1170,9 +1122,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.51" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -1181,9 +1133,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.2.0" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331" +checksum = "e8e9199467bcbc77c6a13cc6e32a6af21721ab8c96aa0261856c4fda5a4433f0" dependencies = [ "cfg-expr", "heck", @@ -1206,22 +1158,22 @@ checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", ] [[package]] @@ -1247,14 +1199,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.6", + "toml_edit 0.22.7", ] [[package]] @@ -1279,15 +1231,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.2", + "winnow 0.6.5", ] [[package]] @@ -1320,7 +1283,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", ] [[package]] @@ -1384,9 +1347,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -1400,9 +1363,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1410,24 +1373,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1435,22 +1398,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.53", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "winapi" @@ -1483,6 +1446,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + [[package]] name = "winnow" version = "0.5.40" @@ -1494,9 +1523,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.2" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] @@ -1520,7 +1549,7 @@ version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index b9b1df6..300049e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,5 @@ lto = true gettext-rs = { version = "0.7", features = ["gettext-system"] } tracing = "0.1" tracing-subscriber = "0.3" -relm4 = { version = "0.6.0", features = ["libadwaita", "gnome_44"] } -relm4-icons = { version = "0.6.0", features = ["issue"] } +relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_44"] } +relm4-icons = { version = "0.8.1" } diff --git a/icons.toml b/icons.toml new file mode 100644 index 0000000..bf80968 --- /dev/null +++ b/icons.toml @@ -0,0 +1,7 @@ +# Recommended: Specify your app ID *OR* your base resource path for more robust icon loading +app_id = "org.kuchelmeister.ToolboxTuner" + +# List of icon names you found (shipped with this crate) +# Note: the file ending `-symbolic.svg` isn't part of the icon name. +icons = ["issue"] + diff --git a/src/app.rs b/src/app.rs index c50d261..1ede9b4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -59,9 +59,11 @@ impl Component for App { view! { main_window = adw::ApplicationWindow::new(&main_application()) { + set_visible: true, + connect_close_request[sender] => move |_| { sender.input(AppMsg::Quit); - gtk::Inhibit(true) + glib::Propagation::Stop }, #[wrap(Some)] @@ -105,22 +107,22 @@ impl Component for App { fn init( _init: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let about_dialog = AboutDialog::builder() - .transient_for(root) + .transient_for(&root) .launch(()) .detach(); let unsupported_dialog = UnsupportedDialog::builder() - .transient_for(root) + .transient_for(&root) .launch(()) .forward(sender.input_sender(), |msg| match msg { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); - let mut containers = FactoryHashMap::new(gtk::ListBox::default(), sender.input_sender()); + let mut containers = FactoryHashMap::builder().launch_default().detach(); containers.insert("123".to_string(), 2); containers.insert("124".to_string(), 3); diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index e378533..c2458ca 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -24,7 +24,6 @@ impl FactoryComponent for Container { type Output = (); type CommandOutput = (); type Widgets = ContainerWidgets; - type ParentInput = AppMsg; type ParentWidget = gtk::ListBox; type Index = String; diff --git a/src/main.rs b/src/main.rs index c660f2d..1d0f8b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,41 @@ -#[rustfmt::skip] -mod config; mod app; +mod config; mod factories; mod modals; -mod setup; +use crate::config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; +use gettextrs::{gettext, LocaleCategory}; use gtk::prelude::ApplicationExt; +use gtk::{gio, glib}; use relm4::{ actions::{AccelsPlus, RelmAction, RelmActionGroup}, gtk, main_application, RelmApp, }; use app::App; -use setup::setup; relm4::new_action_group!(AppActionGroup, "app"); relm4::new_stateless_action!(QuitAction, AppActionGroup, "quit"); fn main() { + gtk::init().unwrap(); // Enable logging tracing_subscriber::fmt() .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL) .with_max_level(tracing::Level::INFO) .init(); - setup(); + // setup gettext + gettextrs::setlocale(LocaleCategory::LcAll, ""); + gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); + gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); + + glib::set_application_name(&gettext("Toolbox Tuner")); + + let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file"); + gio::resources_register(&res); + + gtk::Window::set_default_icon_name(APP_ID); let app = main_application(); app.set_resource_base_path(Some("/org/kuchelmeister/ToolboxTuner/")); @@ -45,5 +56,12 @@ fn main() { let app = RelmApp::from_app(app); relm4_icons::initialize_icons(); - app.run::(()); + let data = res + .lookup_data( + "/org/kuchelmeister/ToolboxTuner/style.css", + gio::ResourceLookupFlags::NONE, + ) + .unwrap(); + app.set_global_css(&glib::GString::from_utf8_checked(data.to_vec()).unwrap()); + app.visible_on_activate(false).run::(()); } diff --git a/src/modals/about.rs b/src/modals/about.rs index c388ab1..e128d22 100644 --- a/src/modals/about.rs +++ b/src/modals/about.rs @@ -33,7 +33,7 @@ impl SimpleComponent for AboutDialog { fn init( _: Self::Init, - root: &Self::Root, + root: Self::Root, _sender: ComponentSender, ) -> ComponentParts { let model = Self {}; diff --git a/src/modals/unsupported.rs b/src/modals/unsupported.rs index 67f769e..a1303c1 100644 --- a/src/modals/unsupported.rs +++ b/src/modals/unsupported.rs @@ -2,7 +2,7 @@ use adw::StatusPage; use gtk::prelude::{ButtonExt, GtkWindowExt}; use relm4::view; use relm4::{adw, gtk, ComponentParts, ComponentSender, SimpleComponent}; -use relm4_icons::icon_name; +use relm4_icons::icon_names; pub struct UnsupportedDialog {} @@ -24,7 +24,7 @@ impl SimpleComponent for UnsupportedDialog { fn init( _: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = Self {}; @@ -38,7 +38,7 @@ impl SimpleComponent for UnsupportedDialog { StatusPage::new() { - set_icon_name: Some(icon_name::ISSUE), + set_icon_name: Some(icon_names::ISSUE), set_title: "Missing requirements", set_description: Some("Make sure Toolbox and Gnome Terminal are installed."), diff --git a/src/setup.rs b/src/setup.rs deleted file mode 100644 index 2bff9a2..0000000 --- a/src/setup.rs +++ /dev/null @@ -1,39 +0,0 @@ -use relm4::gtk; - -use gettextrs::{gettext, LocaleCategory}; -use gtk::{gio, glib}; - -use crate::config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; - -pub fn setup() { - // Initialize GTK - gtk::init().unwrap(); - - setup_gettext(); - - glib::set_application_name(&gettext("Toolbox Tuner")); - - let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file"); - gio::resources_register(&res); - - setup_css(&res); - - gtk::Window::set_default_icon_name(APP_ID); -} - -fn setup_gettext() { - // Prepare i18n - gettextrs::setlocale(LocaleCategory::LcAll, ""); - gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); - gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); -} - -fn setup_css(res: &gio::Resource) { - let data = res - .lookup_data( - "/org/kuchelmeister/ToolboxTuner/style.css", - gio::ResourceLookupFlags::NONE, - ) - .unwrap(); - relm4::set_global_css(&glib::GString::from_utf8_checked(data.to_vec()).unwrap()); -} From f9d2fb9c0b7cc4310bbfa35deea834efc82ac1d3 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 17 Mar 2024 17:43:10 +0100 Subject: [PATCH 15/36] use different filenames for modules instead of mod.rs --- src/{factories/mod.rs => factories.rs} | 0 src/{modals/mod.rs => modals.rs} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{factories/mod.rs => factories.rs} (100%) rename src/{modals/mod.rs => modals.rs} (100%) diff --git a/src/factories/mod.rs b/src/factories.rs similarity index 100% rename from src/factories/mod.rs rename to src/factories.rs diff --git a/src/modals/mod.rs b/src/modals.rs similarity index 100% rename from src/modals/mod.rs rename to src/modals.rs From 1594bff156fe86c442617fa64ad62e57c5d1dcaa Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 17 Mar 2024 17:46:32 +0100 Subject: [PATCH 16/36] move runtime to 45 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 300049e..19c3fb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,5 @@ lto = true gettext-rs = { version = "0.7", features = ["gettext-system"] } tracing = "0.1" tracing-subscriber = "0.3" -relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_44"] } +relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_45"] } relm4-icons = { version = "0.8.1" } From b52232a4cb9d144479cdfe829e625f076f5430ea Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 17 Mar 2024 17:55:01 +0100 Subject: [PATCH 17/36] remove unused imports --- src/factories/container_list.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index c2458ca..68c30e3 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,10 +1,9 @@ -use crate::app::AppMsg; -use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use gtk::prelude::ButtonExt; use relm4::adw; use relm4::adw::prelude::ActionRowExt; use relm4::adw::prelude::PreferencesRowExt; -use relm4::factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque}; -use relm4::{gtk, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent}; +use relm4::factory::{FactoryComponent, FactorySender}; +use relm4::gtk; #[derive(Debug)] pub struct Container { From 5f2819f0b899099f6cad52534041871391474f1e Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 17 Mar 2024 18:15:16 +0100 Subject: [PATCH 18/36] add some more icons --- icons.toml | 2 +- src/factories/container_list.rs | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/icons.toml b/icons.toml index bf80968..a47d1d5 100644 --- a/icons.toml +++ b/icons.toml @@ -3,5 +3,5 @@ app_id = "org.kuchelmeister.ToolboxTuner" # List of icon names you found (shipped with this crate) # Note: the file ending `-symbolic.svg` isn't part of the icon name. -icons = ["issue"] +icons = ["issue", "play", "pause", "terminal"] diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 68c30e3..569b59a 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -4,6 +4,7 @@ use relm4::adw::prelude::ActionRowExt; use relm4::adw::prelude::PreferencesRowExt; use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; +use relm4_icons::icon_names; #[derive(Debug)] pub struct Container { @@ -29,12 +30,18 @@ impl FactoryComponent for Container { view! { root = adw::ActionRow { #[watch] - set_title: &self.hash, + set_title: format!{"{}: {}", self.hash, self.value.to_string()}.as_str(), + + #[name(play_button)] + add_prefix = >k::Button { + // TODO: make component with state that either is waiting, play or pause + set_icon_name: icon_names::PLAY, + connect_clicked => ContainerMsg::Start, + }, #[name(add_button)] add_suffix = >k::Button { - #[watch] - set_label: &self.value.to_string(), + set_icon_name: icon_names::TERMINAL, connect_clicked => ContainerMsg::Start, }, } From e998b6f1a94ab7917d02c6bb9513a595b0a8a367 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 19 Mar 2024 17:21:00 +0100 Subject: [PATCH 19/36] disable selection for listbox --- src/app.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 1ede9b4..011b1f9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -96,6 +96,7 @@ impl Component for App { #[local_ref] container_box -> gtk::ListBox { + set_selection_mode: gtk::SelectionMode::None, set_valign: Align::Start, set_margin_all: 30, set_css_classes: &["boxed-list"], @@ -124,7 +125,13 @@ impl Component for App { let mut containers = FactoryHashMap::builder().launch_default().detach(); containers.insert("123".to_string(), 2); - containers.insert("124".to_string(), 3); + containers.insert("abc".to_string(), 3); + containers.insert("45435".to_string(), 3); + containers.insert("1dsal;k1;23".to_string(), 3); + containers.insert("afdsaf".to_string(), 3); + containers.insert("5344".to_string(), 3); + containers.insert("1242344".to_string(), 3); + containers.insert("1265464".to_string(), 3); let model = Self { about_dialog, From 5da62888d1d39cf43acd4fceaf70f7f27c56d455 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 19 Mar 2024 17:31:24 +0100 Subject: [PATCH 20/36] add scrolled window to allow more toolboxes' --- src/app.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index 011b1f9..55b7a17 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,6 @@ use crate::gtk::Align; use relm4::factory::FactoryHashMap; +use relm4::gtk::PolicyType; use relm4::RelmWidgetExt; use relm4::{ actions::{RelmAction, RelmActionGroup}, @@ -92,14 +93,19 @@ impl Component for App { } }, + gtk::ScrolledWindow { + set_hexpand: true, + set_vexpand: true, + set_hscrollbar_policy: PolicyType::Never, - - #[local_ref] - container_box -> gtk::ListBox { + #[local_ref] + container_box -> gtk::ListBox { set_selection_mode: gtk::SelectionMode::None, set_valign: Align::Start, set_margin_all: 30, set_css_classes: &["boxed-list"], + }, + }, } From 7c7f07e670f7168879f1ad10109b4dce70918f8f Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 19 Mar 2024 18:08:11 +0100 Subject: [PATCH 21/36] transfer styling from old application --- src/app.rs | 1 + src/factories/container_list.rs | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 55b7a17..83ba84d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -100,6 +100,7 @@ impl Component for App { #[local_ref] container_box -> gtk::ListBox { + set_size_request: (200, -1), set_selection_mode: gtk::SelectionMode::None, set_valign: Align::Start, set_margin_all: 30, diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 569b59a..8a15551 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -4,6 +4,7 @@ use relm4::adw::prelude::ActionRowExt; use relm4::adw::prelude::PreferencesRowExt; use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; +use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; #[derive(Debug)] @@ -36,13 +37,25 @@ impl FactoryComponent for Container { add_prefix = >k::Button { // TODO: make component with state that either is waiting, play or pause set_icon_name: icon_names::PLAY, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], connect_clicked => ContainerMsg::Start, }, - #[name(add_button)] - add_suffix = >k::Button { - set_icon_name: icon_names::TERMINAL, - connect_clicked => ContainerMsg::Start, + add_suffix = >k::Box{ + gtk::AspectFrame{ + set_ratio: 1.0, + #[name(add_button)] + gtk::Button { + set_icon_name: icon_names::TERMINAL, + set_margin_start: 10, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["flat"], + connect_clicked => ContainerMsg::Start, + }, + }, }, } } From 92315c5652e0afeb53db31981e8bf694b265772a Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 19 Mar 2024 18:16:33 +0100 Subject: [PATCH 22/36] wrap play button in aspecframe to keep from weirdly resizing when parent size increases --- src/app.rs | 5 +++++ src/factories/container_list.rs | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index 83ba84d..e58dfb0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -139,6 +139,11 @@ impl Component for App { containers.insert("5344".to_string(), 3); containers.insert("1242344".to_string(), 3); containers.insert("1265464".to_string(), 3); + containers.insert( + "126222222222222222222222222222222222222222233333333333333333333333333333333325464" + .to_string(), + 3, + ); let model = Self { about_dialog, diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 8a15551..a8533b4 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -33,14 +33,19 @@ impl FactoryComponent for Container { #[watch] set_title: format!{"{}: {}", self.hash, self.value.to_string()}.as_str(), - #[name(play_button)] - add_prefix = >k::Button { - // TODO: make component with state that either is waiting, play or pause - set_icon_name: icon_names::PLAY, - set_margin_top: 10, - set_margin_bottom: 10, - set_css_classes: &["circular"], - connect_clicked => ContainerMsg::Start, + add_prefix = >k::Box{ + gtk::AspectFrame{ + set_ratio: 1.0, + #[name(play_button)] + gtk::Button { + // TODO: make component with state that either is waiting, play or pause + set_icon_name: icon_names::PLAY, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], + connect_clicked => ContainerMsg::Start, + }, + }, }, add_suffix = >k::Box{ From 308ad5ccfdf6638e55cb4b071e2f65ca35dbd545 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 00:41:13 +0200 Subject: [PATCH 23/36] add populate factory using toolboxes on machine --- Cargo.lock | 14 +- Cargo.toml | 2 + .../org.kuchelmeister.ToolboxTuner.Devel.json | 7 +- src/app.rs | 25 +- src/factories/container_list.rs | 23 +- src/main.rs | 1 + src/util.rs | 1 + src/util/toolbox.rs | 427 ++++++++++++++++++ 8 files changed, 470 insertions(+), 30 deletions(-) create mode 100644 src/util.rs create mode 100644 src/util/toolbox.rs diff --git a/Cargo.lock b/Cargo.lock index 8f7014f..5a57cc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1032,18 +1032,18 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", @@ -1052,9 +1052,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -1260,6 +1260,8 @@ dependencies = [ "gettext-rs", "relm4", "relm4-icons", + "serde", + "serde_json", "tracing", "tracing-subscriber", ] diff --git a/Cargo.toml b/Cargo.toml index 19c3fb3..77b4106 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,5 @@ tracing = "0.1" tracing-subscriber = "0.3" relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_45"] } relm4-icons = { version = "0.8.1" } +serde = { version = "1.0.199", features = ["derive"] } +serde_json = "1.0.116" diff --git a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json index 14a06c3..baf0556 100644 --- a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json +++ b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json @@ -9,13 +9,14 @@ ], "command": "toolbox-tuner", "finish-args": [ - "--share=ipc", + "--talk-name=org.freedesktop.Flatpak", "--socket=fallback-x11", "--socket=wayland", "--device=dri", - "--env=RUST_LOG=toolbox_tuner=debug", + "--env=RUST_LOG=toolbxtuner=debug", "--env=G_MESSAGES_DEBUG=none", - "--env=RUST_BACKTRACE=1" + "--env=RUST_BACKTRACE=1", + "--share=ipc" ], "build-options": { "append-path": "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm15/bin", diff --git a/src/app.rs b/src/app.rs index e58dfb0..a5a32e5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,5 @@ use crate::gtk::Align; +use crate::util::toolbox::ToolbxContainer; use relm4::factory::FactoryHashMap; use relm4::gtk::PolicyType; use relm4::RelmWidgetExt; @@ -39,6 +40,7 @@ relm4::new_action_group!(pub(super) WindowActionGroup, "win"); //relm4::new_stateless_action!(PreferencesAction, WindowActionGroup, "preferences"); relm4::new_stateless_action!(pub(super) ShortcutsAction, WindowActionGroup, "show-help-overlay"); relm4::new_stateless_action!(AboutAction, WindowActionGroup, "about"); +use crate::factories::container_list::ContainerInit; #[relm4::component(pub)] impl Component for App { @@ -130,20 +132,17 @@ impl Component for App { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); + let toolboxes = ToolbxContainer::get_toolboxes(); + let mut containers = FactoryHashMap::builder().launch_default().detach(); - containers.insert("123".to_string(), 2); - containers.insert("abc".to_string(), 3); - containers.insert("45435".to_string(), 3); - containers.insert("1dsal;k1;23".to_string(), 3); - containers.insert("afdsaf".to_string(), 3); - containers.insert("5344".to_string(), 3); - containers.insert("1242344".to_string(), 3); - containers.insert("1265464".to_string(), 3); - containers.insert( - "126222222222222222222222222222222222222222233333333333333333333333333333333325464" - .to_string(), - 3, - ); + toolboxes.iter().for_each(|toolbox| { + &containers.insert( + toolbox.id.clone(), + ContainerInit { + name: toolbox.name.clone(), + }, + ); + }); let model = Self { about_dialog, diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index a8533b4..d3555e6 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -10,17 +10,23 @@ use relm4_icons::icon_names; #[derive(Debug)] pub struct Container { hash: String, - value: u8, + value: String, } #[derive(Debug)] pub enum ContainerMsg { Start, + Stop, + OpenTerminal, +} + +pub struct ContainerInit { + pub name: String, } #[relm4::factory(pub)] impl FactoryComponent for Container { - type Init = u8; + type Init = ContainerInit; type Input = ContainerMsg; type Output = (); type CommandOutput = (); @@ -31,7 +37,8 @@ impl FactoryComponent for Container { view! { root = adw::ActionRow { #[watch] - set_title: format!{"{}: {}", self.hash, self.value.to_string()}.as_str(), + set_title: &self.value, + set_subtitle: &self.hash, add_prefix = >k::Box{ gtk::AspectFrame{ @@ -58,7 +65,7 @@ impl FactoryComponent for Container { set_margin_top: 10, set_margin_bottom: 10, set_css_classes: &["flat"], - connect_clicked => ContainerMsg::Start, + connect_clicked => ContainerMsg::OpenTerminal, }, }, }, @@ -68,15 +75,15 @@ impl FactoryComponent for Container { fn init_model(value: Self::Init, index: &Self::Index, _sender: FactorySender) -> Self { Self { hash: index.clone(), - value, + value: value.name.clone(), } } fn update(&mut self, msg: Self::Input, _sender: FactorySender) { match msg { - ContainerMsg::Start => { - self.value = self.value.wrapping_add(1); - } + ContainerMsg::Start => {} + ContainerMsg::Stop => {} + ContainerMsg::OpenTerminal => {} } } } diff --git a/src/main.rs b/src/main.rs index 1d0f8b9..7778180 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ mod app; mod config; mod factories; mod modals; +mod util; use crate::config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; use gettextrs::{gettext, LocaleCategory}; diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..b763831 --- /dev/null +++ b/src/util.rs @@ -0,0 +1 @@ +pub mod toolbox; diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs new file mode 100644 index 0000000..bb0a3f3 --- /dev/null +++ b/src/util/toolbox.rs @@ -0,0 +1,427 @@ +use serde::{Deserialize, Serialize}; +use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc}; + +#[derive(Debug, PartialEq)] +pub enum ToolbxError { + ParseStatusError(String), + JSONSerializationError(String), + CommandExecutionError(String), + CommandUnsuccessfulError(String), +} + +impl std::error::Error for ToolbxError {} + +impl Display for ToolbxError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ToolbxError::ParseStatusError(parse_error) => write!(f, "{}", parse_error), + ToolbxError::CommandExecutionError(command_exec_error) => { + write!(f, "{}", command_exec_error) + } + ToolbxError::JSONSerializationError(msg) => { + write!(f, "{}", msg) + } + ToolbxError::CommandUnsuccessfulError(command_unsuc_error) => { + write!(f, "{}", command_unsuc_error) + } + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub enum ToolbxStatus { + Running, + Configured, + Created, + Exited, +} + +impl Default for ToolbxStatus { + fn default() -> Self { + ToolbxStatus::Configured + } +} + +impl FromStr for ToolbxStatus { + type Err = ToolbxError; + + fn from_str(s: &str) -> Result { + match s { + "running" => Ok(ToolbxStatus::Running), + "configured" => Ok(ToolbxStatus::Configured), + "created" => Ok(ToolbxStatus::Created), + "exited" => Ok(ToolbxStatus::Exited), + s => Err(ToolbxError::ParseStatusError(format!( + "'{}' is not a valid toolbx status.", + s + ))), + } + } +} + +#[derive(Debug, PartialEq, Default, Clone)] +pub struct ToolbxContainer { + pub id: String, + pub name: String, + pub created: String, + pub status: ToolbxStatus, + pub image: String, +} + +pub type PodmanInspectArray = Vec; + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PodmanInspectInfo { + #[serde(rename = "Id")] + pub id: String, + #[serde(rename = "Created")] + pub created: String, + #[serde(rename = "State")] + pub state: PodManInspectState, + #[serde(rename = "Image")] + pub image: String, + #[serde(rename = "ImageName")] + pub image_name: String, + #[serde(rename = "Name")] + pub name: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PodManInspectState { + #[serde(rename = "Status")] + pub status: String, +} + +pub enum ToolboxCreateParameter { + None, + Distro(String), + Image(String), + Release(String), +} + +impl ToolbxContainer { + pub fn new(name: String) -> ToolbxContainer { + ToolbxContainer { + name: name, + ..Default::default() + } + } + + pub fn create(name: String, parameter: ToolboxCreateParameter) { + todo!("Implement actual functionality to create toolbox via commandline") + } + + pub fn get_toolboxes() -> Vec { + let output = run_cmd_toolbx_list_containers(); + println!("{}", output); + parse_cmd_list_containers(output.as_str()) + } + + fn parse_status(output: &str) -> Result { + let result: Result = serde_json::from_str(output); + match result { + Ok(inspect_vec) => match inspect_vec.first() { + Some(info) => Ok(info.clone()), + None => Err(ToolbxError::JSONSerializationError( + "Inspect command returned empty vector.".to_string(), + )), + }, + Err(e) => Err(ToolbxError::JSONSerializationError(e.to_string())), + } + } + + pub fn update_status(&mut self) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("podman") + .arg("container") + .arg("inspect") + .arg(self.name.clone()) + .output() + .expect("Failed to execute command"); + + let output = String::from_utf8_lossy(&output.stdout).to_string(); + let inspect_result = ToolbxContainer::parse_status(output.as_str())?; + self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; + Ok(()) + } + + pub fn stop(&mut self) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("stop") + .arg(self.name.clone()) + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + + // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + //Fail: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } + + if output.status.code() == Some(0) { + self.status = ToolbxStatus::Exited; + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } + } + + pub fn start(&mut self) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("start") + .arg(self.name.clone()) + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + + // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + // Fail: status: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } + + if output.status.code() == Some(0) { + self.status = ToolbxStatus::Running; + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } + } +} + +#[test] +fn test_start_1non_existing_container() { + // TODO: create container that exists based on simple image + // run command + // delete container + //let tbx = ToolbxContainer{created: "".to_string(), id: "".to_string(), name: "latex".to_string(), image: "".to_string(), status: ToolbxStatus::Exited}; + + //tbx.stop(); +} + +#[test] +fn test_inspect_parsing() { + let podman_inspect = concat!( + "[{", + "\"Id\": \"ae05203091ab4cdf047a9aeba6af8a7bed8105f7f59d09a35d2b64c837ecac0d\",", + "\"Created\": \"2021-12-10T20:51:43.140418098+01:00\",", + "\"State\": {", + "\"Status\": \"running\"", + "},", + "\"Image\": \"ab8bc106d4a710a7a27c538762864610467b3559f80b413d30e0a1bfcfe272a5\",", + "\"ImageName\": \"registry.fedoraproject.org/fedora-toolbox:35\",", + "\"Name\": \"rust\"", + "}]" + ); + let inspect_info = ToolbxContainer::parse_status(podman_inspect).unwrap(); + assert_eq!("running", inspect_info.state.status); +} + +#[test] +fn test_start_non_existing_container() { + let name = "zy2lM6BdZoTnKHaVPkUJ".to_string(); + let mut tbx = ToolbxContainer { + created: "".to_string(), + id: "".to_string(), + name: name.clone(), + image: "".to_string(), + status: ToolbxStatus::Exited, + }; + + assert_eq!( + Err(ToolbxError::CommandUnsuccessfulError(format!( + "Error: no container with name or ID \"{}\" found: no such container\n", + name + ))), + tbx.start() + ); +} + +pub fn run_cmd_toolbx_list_containers() -> String { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("toolbox") + .arg("list") + .arg("--containers") + .output() + .expect("Failed to execute command"); + + println!("{:?}", String::from_utf8_lossy(&output.stdout).to_string()); + + String::from_utf8_lossy(&output.stdout).to_string() +} + +#[test] +#[ignore] +fn test_cmd_list_containers() { + // This requires toolbx to be installed + let toolbox_cmd_container_header = + "CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME"; + assert!(run_cmd_toolbx_list_containers().starts_with(toolbox_cmd_container_header)); +} + +fn tokenize_line_list_containers(line: &str) -> Vec { + let mut tokens = Vec::::new(); + let mut current_token = Vec::::new(); + + let mut whitespace_section = false; + + let mut iter = line.chars().peekable(); + while let Some(&c) = iter.peek() { + match (whitespace_section, c) { + (false, ' ') => { + iter.next(); + if Some(' ') == iter.peek().map(|x| x.clone()) { + whitespace_section = true; + } else { + current_token.push(c); + } + } + (true, ' ') => { + iter.next(); + } + (true, c) => { + whitespace_section = false; + tokens.push(current_token.into_iter().collect()); + current_token = Vec::new(); + current_token.push(c); + iter.next(); + } + (false, c) => { + current_token.push(c); + iter.next(); + } + } + } + tokens.push(current_token.into_iter().collect()); + + tokens +} + +#[test] +fn test_tokenize_line_list_containers() { + let toolbox_cmd_container_header = "ae05203091ab rust 4 months ago \ + running registry.fedoraproject.org/fedora-toolbox:35"; + + let target = vec![ + "ae05203091ab", + "rust", + "4 months ago", + "running", + "registry.fedoraproject.org/fedora-toolbox:35", + ]; + let result = tokenize_line_list_containers(toolbox_cmd_container_header); + assert_eq!(target, result); +} + +fn parse_line_list_containers(line: &str) -> Result { + let tokens = tokenize_line_list_containers(line); + if tokens.len() != 5 { + panic! {"Expected 5 tokens found {} in {:?}", tokens.len(), tokens}; + } + Ok(ToolbxContainer { + id: tokens[0].clone(), + name: tokens[1].clone(), + created: tokens[2].clone(), + status: ToolbxStatus::from_str(&tokens[3])?, + image: tokens[4].clone(), + }) +} + +#[test] +fn test_parse_line_list_containers() { + let toolbox_cmd_container_header = "ae05203091ab rust 4 months ago \ + running registry.fedoraproject.org/fedora-toolbox:35"; + + let target = ToolbxContainer { + id: "ae05203091ab".to_string(), + name: "rust".to_string(), + created: "4 months ago".to_string(), + status: ToolbxStatus::Running, + image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), + }; + let result = parse_line_list_containers(toolbox_cmd_container_header); + assert_eq!(target, result.unwrap()); +} + +fn parse_cmd_list_containers(output: &str) -> Vec { + let lines = output.trim().split("\n").skip(1); + println!("{:?}", lines); + lines.map(parse_line_list_containers).flatten().collect() +} + +#[test] +fn test_parse_cmd_list_containers() { + // This requires toolbx to be installed + let toolbox_cmd_container_header = concat!( + "CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME\n", + "cee1002b5f0b fedora-toolbox-35 2 months ago exited registry.fedoraproject.org/fedora-toolbox:35\n", + "9b611313bf65 latex 4 months ago configured registry.fedoraproject.org/fedora-toolbox:35\n", + "1235203091ab website 4 months ago created registry.fedoraproject.org/fedora-toolbox:35\n", + "ae05203091ab rust 4 months ago running registry.fedoraproject.org/fedora-toolbox:35\n" + ); + + let desired_result = vec![ + ToolbxContainer { + id: "cee1002b5f0b".to_string(), + name: "fedora-toolbox-35".to_string(), + created: "2 months ago".to_string(), + status: ToolbxStatus::Exited, + image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), + }, + ToolbxContainer { + id: "9b611313bf65".to_string(), + name: "latex".to_string(), + created: "4 months ago".to_string(), + status: ToolbxStatus::Configured, + image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), + }, + ToolbxContainer { + id: "1235203091ab".to_string(), + name: "website".to_string(), + created: "4 months ago".to_string(), + status: ToolbxStatus::Created, + image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), + }, + ToolbxContainer { + id: "ae05203091ab".to_string(), + name: "rust".to_string(), + created: "4 months ago".to_string(), + status: ToolbxStatus::Running, + image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), + }, + ]; + + for (result, desired) in zip( + parse_cmd_list_containers(toolbox_cmd_container_header).iter(), + desired_result.iter(), + ) { + assert_eq!(result, desired) + } +} From 500d1593696cfe851a63bfffa53ced5b798703de Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 22:18:10 +0200 Subject: [PATCH 24/36] upgrade to higher gnome version --- Cargo.toml | 2 +- .../org.kuchelmeister.ToolboxTuner.Devel.json | 52 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 77b4106..1f05349 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ lto = true gettext-rs = { version = "0.7", features = ["gettext-system"] } tracing = "0.1" tracing-subscriber = "0.3" -relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_45"] } +relm4 = { version = "0.8.1", features = ["libadwaita", "gnome_46", "macros"] } relm4-icons = { version = "0.8.1" } serde = { version = "1.0.199", features = ["derive"] } serde_json = "1.0.116" diff --git a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json index baf0556..49c84b4 100644 --- a/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json +++ b/build-aux/org.kuchelmeister.ToolboxTuner.Devel.json @@ -1,14 +1,14 @@ { - "id": "org.kuchelmeister.ToolboxTuner.Devel", - "runtime": "org.gnome.Platform", - "runtime-version": "45", - "sdk": "org.gnome.Sdk", - "sdk-extensions": [ + "id" : "org.kuchelmeister.ToolboxTuner.Devel", + "runtime" : "org.gnome.Platform", + "runtime-version" : "46", + "sdk" : "org.gnome.Sdk", + "sdk-extensions" : [ "org.freedesktop.Sdk.Extension.rust-stable", "org.freedesktop.Sdk.Extension.llvm15" ], - "command": "toolbox-tuner", - "finish-args": [ + "command" : "toolbox-tuner", + "finish-args" : [ "--talk-name=org.freedesktop.Flatpak", "--socket=fallback-x11", "--socket=wayland", @@ -18,36 +18,36 @@ "--env=RUST_BACKTRACE=1", "--share=ipc" ], - "build-options": { - "append-path": "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm15/bin", - "prepend-ld-library-path": "/usr/lib/sdk/llvm15/lib", - "build-args": [ + "build-options" : { + "append-path" : "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm15/bin", + "prepend-ld-library-path" : "/usr/lib/sdk/llvm15/lib", + "build-args" : [ "--share=network" ], - "env": { - "CARGO_REGISTRIES_CRATES_IO_PROTOCOL": "sparse", - "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER": "clang", - "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold", - "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER": "clang", - "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold" + "env" : { + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER" : "clang", + "CARGO_REGISTRIES_CRATES_IO_PROTOCOL" : "sparse", + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS" : "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER" : "clang", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS" : "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold" }, - "test-args": [ + "test-args" : [ "--socket=x11", "--share=network" ] }, - "modules": [ + "modules" : [ { - "name": "toolbox-tuner", - "buildsystem": "meson", - "run-tests": true, - "config-opts": [ + "name" : "toolbox-tuner", + "buildsystem" : "meson", + "run-tests" : true, + "config-opts" : [ "-Dprofile=development" ], - "sources": [ + "sources" : [ { - "type": "dir", - "path": "../" + "type" : "dir", + "path" : "../" } ] } From ceecb4d6cf56125540d8542932f1c814d6ec2f8b Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 22:20:14 +0200 Subject: [PATCH 25/36] periodically update toolboxes and show spinner when this is happening --- src/app.rs | 76 +++++++++++++++++++++++++++++++++++---------- src/util/toolbox.rs | 2 +- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/app.rs b/src/app.rs index a5a32e5..04c3e12 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,7 @@ use crate::gtk::Align; +use crate::gtk::Spinner; use crate::util::toolbox::ToolbxContainer; +use relm4::adw::prelude::PreferencesGroupExt; use relm4::factory::FactoryHashMap; use relm4::gtk::PolicyType; use relm4::RelmWidgetExt; @@ -8,6 +10,9 @@ use relm4::{ adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender, Controller, }; +use std::collections::HashSet; +use std::thread::sleep; +use std::time::Duration; use gtk::prelude::{ ApplicationExt, ApplicationWindowExt, GtkWindowExt, OrientableExt, SettingsExt, WidgetExt, @@ -24,6 +29,7 @@ pub(super) struct App { unsupported_dialog: Controller, about_dialog: Controller, containers: FactoryHashMap, + refresh_spinner: Spinner, } #[derive(Debug)] @@ -34,6 +40,7 @@ pub enum AppMsg { #[derive(Debug)] pub(super) enum AppCommandMsg { PrerequisitsInstalled(bool), + UpdateToolboxes(Vec), } relm4::new_action_group!(pub(super) WindowActionGroup, "win"); @@ -100,13 +107,22 @@ impl Component for App { set_vexpand: true, set_hscrollbar_policy: PolicyType::Never, - #[local_ref] - container_box -> gtk::ListBox { - set_size_request: (200, -1), - set_selection_mode: gtk::SelectionMode::None, - set_valign: Align::Start, + adw::PreferencesGroup{ + set_title: "Toolboxes", set_margin_all: 30, - set_css_classes: &["boxed-list"], + + + set_header_suffix: Some( + &model.refresh_spinner + ), + + #[local_ref] + container_box -> gtk::ListBox { + set_size_request: (200, -1), + set_selection_mode: gtk::SelectionMode::None, + set_valign: Align::Start, + set_css_classes: &["boxed-list"], + }, }, }, @@ -132,22 +148,15 @@ impl Component for App { UnsupportedDialogOutput::CloseApplication => AppMsg::Quit, }); - let toolboxes = ToolbxContainer::get_toolboxes(); + let containers = FactoryHashMap::builder().launch_default().detach(); - let mut containers = FactoryHashMap::builder().launch_default().detach(); - toolboxes.iter().for_each(|toolbox| { - &containers.insert( - toolbox.id.clone(), - ContainerInit { - name: toolbox.name.clone(), - }, - ); - }); + let refresh_spinner = gtk::Spinner::new(); let model = Self { about_dialog, unsupported_dialog, containers, + refresh_spinner, }; let container_box = model.containers.widget(); @@ -192,15 +201,48 @@ impl Component for App { fn update_cmd( &mut self, message: Self::CommandOutput, - _sender: ComponentSender, + sender: ComponentSender, _: &Self::Root, ) { match message { AppCommandMsg::PrerequisitsInstalled(false) => { self.unsupported_dialog.sender().clone().send(()).unwrap() } + AppCommandMsg::PrerequisitsInstalled(true) => { // TODO: start process of fetching toolboxes + self.refresh_spinner.set_spinning(true); + sender.spawn_oneshot_command(|| { + AppCommandMsg::UpdateToolboxes(ToolbxContainer::get_toolboxes()) + }) + } + AppCommandMsg::UpdateToolboxes(toolboxes) => { + let mut updated_containers = HashSet::::new(); + toolboxes.iter().for_each(|toolbox| { + self.containers.insert( + toolbox.id.clone(), + ContainerInit { + name: toolbox.name.clone(), + }, + ); + updated_containers.insert(toolbox.id.clone()); + }); + let obsolete_containers: Vec = self + .containers + .iter() + .map(|(hash, _)| hash.clone()) + .filter(|hash| !updated_containers.contains(hash)) + .collect(); + obsolete_containers.into_iter().for_each(|hash| { + self.containers.remove(&hash); + }); + + self.refresh_spinner.set_spinning(false); + + sender.spawn_oneshot_command(|| { + sleep(Duration::from_millis(2000)); + AppCommandMsg::PrerequisitsInstalled(true) + }); } } } diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index bb0a3f3..7d939ba 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc}; +use std::{fmt::Display, process::Command, str::FromStr}; #[derive(Debug, PartialEq)] pub enum ToolbxError { From 30de9d12b01d04f5abdef8fb6079d8a6a99bde6f Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 22:23:46 +0200 Subject: [PATCH 26/36] add seperate message for initiating refresh --- src/app.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 04c3e12..51c4507 100644 --- a/src/app.rs +++ b/src/app.rs @@ -41,6 +41,7 @@ pub enum AppMsg { pub(super) enum AppCommandMsg { PrerequisitsInstalled(bool), UpdateToolboxes(Vec), + InitiateRefresh, } relm4::new_action_group!(pub(super) WindowActionGroup, "win"); @@ -209,7 +210,7 @@ impl Component for App { self.unsupported_dialog.sender().clone().send(()).unwrap() } - AppCommandMsg::PrerequisitsInstalled(true) => { + AppCommandMsg::PrerequisitsInstalled(true) | AppCommandMsg::InitiateRefresh => { // TODO: start process of fetching toolboxes self.refresh_spinner.set_spinning(true); sender.spawn_oneshot_command(|| { @@ -241,7 +242,7 @@ impl Component for App { sender.spawn_oneshot_command(|| { sleep(Duration::from_millis(2000)); - AppCommandMsg::PrerequisitsInstalled(true) + AppCommandMsg::InitiateRefresh }); } } From 76a38bd882ada5a14d696a170dfe32b4826f20ab Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 23:54:12 +0200 Subject: [PATCH 27/36] use the view macro better and use property binding --- src/app.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app.rs b/src/app.rs index 51c4507..de7e816 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,4 @@ use crate::gtk::Align; -use crate::gtk::Spinner; use crate::util::toolbox::ToolbxContainer; use relm4::adw::prelude::PreferencesGroupExt; use relm4::factory::FactoryHashMap; @@ -29,7 +28,7 @@ pub(super) struct App { unsupported_dialog: Controller, about_dialog: Controller, containers: FactoryHashMap, - refresh_spinner: Spinner, + spinning: bool, } #[derive(Debug)] @@ -113,9 +112,12 @@ impl Component for App { set_margin_all: 30, - set_header_suffix: Some( - &model.refresh_spinner - ), + + #[wrap(Some)] + set_header_suffix: refresh_spinner = >k::Spinner { + #[watch] + set_spinning: model.spinning + }, #[local_ref] container_box -> gtk::ListBox { @@ -151,13 +153,11 @@ impl Component for App { let containers = FactoryHashMap::builder().launch_default().detach(); - let refresh_spinner = gtk::Spinner::new(); - let model = Self { about_dialog, unsupported_dialog, containers, - refresh_spinner, + spinning: true, }; let container_box = model.containers.widget(); @@ -212,7 +212,7 @@ impl Component for App { AppCommandMsg::PrerequisitsInstalled(true) | AppCommandMsg::InitiateRefresh => { // TODO: start process of fetching toolboxes - self.refresh_spinner.set_spinning(true); + self.spinning = true; sender.spawn_oneshot_command(|| { AppCommandMsg::UpdateToolboxes(ToolbxContainer::get_toolboxes()) }) @@ -238,7 +238,7 @@ impl Component for App { self.containers.remove(&hash); }); - self.refresh_spinner.set_spinning(false); + self.spinning = false; sender.spawn_oneshot_command(|| { sleep(Duration::from_millis(2000)); From 2015ae60632d188528ad49734cee1318367f77e7 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sun, 28 Apr 2024 23:54:52 +0200 Subject: [PATCH 28/36] remove obsolete todo --- src/app.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index de7e816..8a13118 100644 --- a/src/app.rs +++ b/src/app.rs @@ -211,7 +211,6 @@ impl Component for App { } AppCommandMsg::PrerequisitsInstalled(true) | AppCommandMsg::InitiateRefresh => { - // TODO: start process of fetching toolboxes self.spinning = true; sender.spawn_oneshot_command(|| { AppCommandMsg::UpdateToolboxes(ToolbxContainer::get_toolboxes()) From b889e803153c75d05a4c963e6a0ab024f917d293 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 30 May 2024 17:40:12 +0200 Subject: [PATCH 29/36] change icon based on container status --- src/app.rs | 17 +++++++++++------ src/factories/container_list.rs | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8a13118..ac7b065 100644 --- a/src/app.rs +++ b/src/app.rs @@ -13,17 +13,18 @@ use std::collections::HashSet; use std::thread::sleep; use std::time::Duration; +use crate::config::{APP_ID, PROFILE}; +use crate::factories::container_list::Container; +use crate::factories::container_list::ContainerStatus; +use crate::modals::about::AboutDialog; +use crate::modals::unsupported::UnsupportedDialog; +use crate::modals::unsupported::UnsupportedDialogOutput; +use crate::util::toolbox::ToolbxStatus; use gtk::prelude::{ ApplicationExt, ApplicationWindowExt, GtkWindowExt, OrientableExt, SettingsExt, WidgetExt, }; use gtk::{gio, glib}; -use crate::config::{APP_ID, PROFILE}; -use crate::factories::container_list::Container; -use crate::modals::about::AboutDialog; -use crate::modals::unsupported::UnsupportedDialog; -use crate::modals::unsupported::UnsupportedDialogOutput; - pub(super) struct App { unsupported_dialog: Controller, about_dialog: Controller, @@ -223,6 +224,10 @@ impl Component for App { toolbox.id.clone(), ContainerInit { name: toolbox.name.clone(), + status: match toolbox.status { + ToolbxStatus::Running => ContainerStatus::Running, + _ => ContainerStatus::NotRunning, + }, }, ); updated_containers.insert(toolbox.id.clone()); diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index d3555e6..2902595 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -7,10 +7,17 @@ use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; +#[derive(Debug)] +pub enum ContainerStatus { + Running, + NotRunning, +} + #[derive(Debug)] pub struct Container { hash: String, value: String, + status: ContainerStatus, } #[derive(Debug)] @@ -22,6 +29,7 @@ pub enum ContainerMsg { pub struct ContainerInit { pub name: String, + pub status: ContainerStatus, } #[relm4::factory(pub)] @@ -38,6 +46,7 @@ impl FactoryComponent for Container { root = adw::ActionRow { #[watch] set_title: &self.value, + #[watch] set_subtitle: &self.hash, add_prefix = >k::Box{ @@ -45,8 +54,11 @@ impl FactoryComponent for Container { set_ratio: 1.0, #[name(play_button)] gtk::Button { - // TODO: make component with state that either is waiting, play or pause - set_icon_name: icon_names::PLAY, + #[watch] + set_icon_name: match &self.status { + ContainerStatus::NotRunning => icon_names::PLAY, + ContainerStatus::Running => icon_names::PAUSE, + }, set_margin_top: 10, set_margin_bottom: 10, set_css_classes: &["circular"], @@ -76,6 +88,7 @@ impl FactoryComponent for Container { Self { hash: index.clone(), value: value.name.clone(), + status: value.status, } } From d98f27229d83cd053aa508b2eea1dd46947aa084 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 30 May 2024 18:02:34 +0200 Subject: [PATCH 30/36] change to use multiple buttons to make state handling easier --- src/factories/container_list.rs | 37 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 2902595..b752987 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -7,7 +7,7 @@ use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ContainerStatus { Running, NotRunning, @@ -52,25 +52,38 @@ impl FactoryComponent for Container { add_prefix = >k::Box{ gtk::AspectFrame{ set_ratio: 1.0, - #[name(play_button)] - gtk::Button { - #[watch] - set_icon_name: match &self.status { - ContainerStatus::NotRunning => icon_names::PLAY, - ContainerStatus::Running => icon_names::PAUSE, + gtk::Box{ + gtk::Button { + #[watch] + set_visible: self.status == ContainerStatus::NotRunning, + set_icon_name: icon_names::PLAY, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], + connect_clicked => ContainerMsg::Start, + }, + gtk::Button { + #[watch] + set_visible: self.status == ContainerStatus::Running, + set_icon_name: icon_names::PAUSE, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], + connect_clicked => ContainerMsg::Stop, }, - set_margin_top: 10, - set_margin_bottom: 10, - set_css_classes: &["circular"], - connect_clicked => ContainerMsg::Start, }, }, }, + add_prefix = >k::Box{ + gtk::AspectFrame{ + set_ratio: 1.0, + + }, + }, add_suffix = >k::Box{ gtk::AspectFrame{ set_ratio: 1.0, - #[name(add_button)] gtk::Button { set_icon_name: icon_names::TERMINAL, set_margin_start: 10, From 8b3ca5cad3e15adf590cc62a93800539c1f85e1a Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 30 May 2024 18:45:50 +0200 Subject: [PATCH 31/36] add stopping and starting function for toolboxes --- src/factories/container_list.rs | 51 ++++++++++++-- src/util/toolbox.rs | 114 ++++++++++++++++---------------- 2 files changed, 102 insertions(+), 63 deletions(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index b752987..7605822 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,3 +1,5 @@ +use crate::util::toolbox::start_toolbox_container; +use crate::util::toolbox::stop_toolbox_container; use gtk::prelude::ButtonExt; use relm4::adw; use relm4::adw::prelude::ActionRowExt; @@ -6,11 +8,11 @@ use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; - #[derive(Debug, PartialEq)] pub enum ContainerStatus { Running, NotRunning, + Refreshing, } #[derive(Debug)] @@ -27,6 +29,12 @@ pub enum ContainerMsg { OpenTerminal, } +#[derive(Debug)] +pub enum CommandMessage { + SetStarted, + SetStopped, +} + pub struct ContainerInit { pub name: String, pub status: ContainerStatus, @@ -37,7 +45,7 @@ impl FactoryComponent for Container { type Init = ContainerInit; type Input = ContainerMsg; type Output = (); - type CommandOutput = (); + type CommandOutput = CommandMessage; type Widgets = ContainerWidgets; type ParentWidget = gtk::ListBox; type Index = String; @@ -53,6 +61,18 @@ impl FactoryComponent for Container { gtk::AspectFrame{ set_ratio: 1.0, gtk::Box{ + gtk::Button { + #[watch] + set_visible: self.status == ContainerStatus::Refreshing, + #[wrap(Some)] + set_child = >k::Spinner { + #[watch] + set_spinning: self.status == ContainerStatus::Refreshing, + }, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], + }, gtk::Button { #[watch] set_visible: self.status == ContainerStatus::NotRunning, @@ -105,11 +125,32 @@ impl FactoryComponent for Container { } } - fn update(&mut self, msg: Self::Input, _sender: FactorySender) { + fn update(&mut self, msg: Self::Input, sender: FactorySender) { match msg { - ContainerMsg::Start => {} - ContainerMsg::Stop => {} + ContainerMsg::Start => { + self.status = ContainerStatus::Refreshing; + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || match start_toolbox_container(&hash) { + Ok(_) => CommandMessage::SetStarted, + Err(_) => CommandMessage::SetStopped, + }); + } + ContainerMsg::Stop => { + self.status = ContainerStatus::Refreshing; + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || match stop_toolbox_container(&hash) { + Ok(_) => CommandMessage::SetStopped, + Err(_) => CommandMessage::SetStarted, + }); + } ContainerMsg::OpenTerminal => {} } } + + fn update_cmd(&mut self, message: Self::CommandOutput, sender: FactorySender) { + match message { + CommandMessage::SetStarted => self.status = ContainerStatus::Running, + CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning, + }; + } } diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 7d939ba..78e42c4 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -147,71 +147,69 @@ impl ToolbxContainer { self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; Ok(()) } +} - pub fn stop(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("stop") - .arg(self.name.clone()) - .output(); +pub fn stop_toolbox_container(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("stop") + .arg(hash) + .output(); - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); - - // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - //Fail: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } - - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Exited; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); } + let output = output.unwrap(); - pub fn start(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("start") - .arg(self.name.clone()) - .output(); + // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + //Fail: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} - // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - // Fail: status: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } +pub fn start_toolbox_container(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("start") + .arg(hash) + .output(); - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Running; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + + // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + // Fail: status: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } + + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) } } From 78088fd86a526355f1f2a252135ec99fe54afa23 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sat, 1 Jun 2024 00:32:57 +0200 Subject: [PATCH 32/36] update metainfo --- data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in index ae187f0..acbff88 100644 --- a/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in +++ b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in @@ -4,24 +4,24 @@ @app-id@ CC0 GPL-3.0-or-later - Toolbx Tuner - Manage and enhance your toolbxes (containertoolboxes) + Toolbox Tuner + Manage and enhance toolboxes (containertoolbx.org)

An application to manage and enhance your containertoolboxes.

Main application window showing multiple toolboxes - https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_light.png + https://media.githubusercontent.com/media/13hannes11/toolbox-tuner/main/data/resources/screenshots/main_light.png Main application window in dark mode - https://media.githubusercontent.com/media/13hannes11/toolbx-tuner/main/data/resources/screenshots/main_dark.png + https://github.com/13hannes11/toolbox-tuner/blob/main/data/resources/screenshots/main_dark.png #a3f6f1 - #60ada6 + #2a9f94 From 2f286697d679d67f5d454a0f335ba38ffe0fd6c5 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Sat, 1 Jun 2024 01:12:10 +0200 Subject: [PATCH 33/36] update screenshots and add screenshot mode --- ...kuchelmeister.ToolboxTuner.Screenshot.json | 55 +++++++++++++++++++ ...helmeister.ToolboxTuner.metainfo.xml.in.in | 4 +- data/resources/screenshots/main_dark.png | 4 +- data/resources/screenshots/main_light.png | 4 +- meson.build | 4 ++ meson_options.txt | 3 +- src/app.rs | 14 +++-- 7 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 build-aux/org.kuchelmeister.ToolboxTuner.Screenshot.json diff --git a/build-aux/org.kuchelmeister.ToolboxTuner.Screenshot.json b/build-aux/org.kuchelmeister.ToolboxTuner.Screenshot.json new file mode 100644 index 0000000..fe6bf17 --- /dev/null +++ b/build-aux/org.kuchelmeister.ToolboxTuner.Screenshot.json @@ -0,0 +1,55 @@ +{ + "id" : "org.kuchelmeister.ToolboxTuner.Screenshot", + "runtime" : "org.gnome.Platform", + "runtime-version" : "46", + "sdk" : "org.gnome.Sdk", + "sdk-extensions" : [ + "org.freedesktop.Sdk.Extension.rust-stable", + "org.freedesktop.Sdk.Extension.llvm15" + ], + "command" : "toolbox-tuner", + "finish-args" : [ + "--talk-name=org.freedesktop.Flatpak", + "--socket=fallback-x11", + "--socket=wayland", + "--device=dri", + "--env=RUST_LOG=toolbxtuner=debug", + "--env=G_MESSAGES_DEBUG=none", + "--env=RUST_BACKTRACE=1", + "--share=ipc" + ], + "build-options" : { + "append-path" : "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm15/bin", + "prepend-ld-library-path" : "/usr/lib/sdk/llvm15/lib", + "build-args" : [ + "--share=network" + ], + "env" : { + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER" : "clang", + "CARGO_REGISTRIES_CRATES_IO_PROTOCOL" : "sparse", + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS" : "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER" : "clang", + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS" : "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold" + }, + "test-args" : [ + "--socket=x11", + "--share=network" + ] + }, + "modules" : [ + { + "name" : "toolbox-tuner", + "buildsystem" : "meson", + "run-tests" : true, + "sources" : [ + { + "type" : "dir", + "path" : "../" + } + ], + "config-opts" : [ + "-Dprofile=screenshot" + ] + } + ] +} diff --git a/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in index acbff88..ca4d462 100644 --- a/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in +++ b/data/org.kuchelmeister.ToolboxTuner.metainfo.xml.in.in @@ -12,11 +12,11 @@ Main application window showing multiple toolboxes - https://media.githubusercontent.com/media/13hannes11/toolbox-tuner/main/data/resources/screenshots/main_light.png + https://media.githubusercontent.com/media/13hannes11/toolbox-tuner/main/data/resources/screenshots/main_light.png Main application window in dark mode - https://github.com/13hannes11/toolbox-tuner/blob/main/data/resources/screenshots/main_dark.png + https://github.com/13hannes11/toolbox-tuner/blob/main/data/resources/screenshots/main_dark.png diff --git a/data/resources/screenshots/main_dark.png b/data/resources/screenshots/main_dark.png index 7e2533f..c160077 100644 --- a/data/resources/screenshots/main_dark.png +++ b/data/resources/screenshots/main_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1638708f85d9dfcf9d1a5327909eb3dd6aec9c0b9814aada8f56347bbff3ab6 -size 146402 +oid sha256:201a9582e4f0f67ddc9d8e2b7184119ae13c60d4c98e0b3778a77d6acb813d16 +size 29471 diff --git a/data/resources/screenshots/main_light.png b/data/resources/screenshots/main_light.png index c68f49b..0c4c8b2 100644 --- a/data/resources/screenshots/main_light.png +++ b/data/resources/screenshots/main_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d7c2389a17b8a4f8f1edf79993957554a6f8c76d0b75f0aa7182415cfc916be -size 146187 +oid sha256:2713f577da9ba226d6a1813b1bab0c55e28cb388e786c69b6681528830cb3ae3 +size 29570 diff --git a/meson.build b/meson.build index f0086df..4642994 100644 --- a/meson.build +++ b/meson.build @@ -42,6 +42,10 @@ if get_option('profile') == 'development' version_suffix = '-@0@'.format(vcs_tag) endif application_id = '@0@.@1@'.format(base_id, profile) +elif get_option('profile') == 'screenshot' + profile = 'Screenshot' + version_suffix = '' + application_id = base_id else profile = '' version_suffix = '' diff --git a/meson_options.txt b/meson_options.txt index f882783..43a9858 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,7 +3,8 @@ option( type: 'combo', choices: [ 'default', - 'development' + 'development', + 'screenshot', ], value: 'default', description: 'The build profile for Toolbox Tuner. One of "default" or "development".' diff --git a/src/app.rs b/src/app.rs index ac7b065..abbd6a4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -262,17 +262,23 @@ impl AppWidgets { let settings = gio::Settings::new(APP_ID); let (width, height) = self.main_window.default_size(); - settings.set_int("window-width", width)?; - settings.set_int("window-height", height)?; - - settings.set_boolean("is-maximized", self.main_window.is_maximized())?; + if PROFILE != "Screenshot" { + settings.set_int("window-width", width)?; + settings.set_int("window-height", height)?; + settings.set_boolean("is-maximized", self.main_window.is_maximized())?; + } Ok(()) } fn load_window_size(&self) { let settings = gio::Settings::new(APP_ID); + if PROFILE == "Screenshot" { + self.main_window.set_default_size(778, 478); + return; + } + let width = settings.int("window-width"); let height = settings.int("window-height"); let is_maximized = settings.boolean("is-maximized"); From 74a64fb198e8340c8a86a8366440a19f94e2f31f Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 2 Jul 2024 18:17:39 +0200 Subject: [PATCH 34/36] add functionality to open terminal inside toolbox --- src/factories/container_list.rs | 45 ++++++++++++++++++++++++++++++++- src/util/toolbox.rs | 25 ++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 7605822..7cb9673 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,3 +1,4 @@ +use crate::util::toolbox::open_toolbox_container_in_terminal; use crate::util::toolbox::start_toolbox_container; use crate::util::toolbox::stop_toolbox_container; use gtk::prelude::ButtonExt; @@ -8,6 +9,8 @@ use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; +use std::collections::HashSet; + #[derive(Debug, PartialEq)] pub enum ContainerStatus { Running, @@ -15,11 +18,17 @@ pub enum ContainerStatus { Refreshing, } +#[derive(Debug, PartialEq, Hash, Eq)] +pub enum ContainerOperation { + LaunchingTerminal, +} + #[derive(Debug)] pub struct Container { hash: String, value: String, status: ContainerStatus, + running_operations: HashSet, } #[derive(Debug)] @@ -33,6 +42,7 @@ pub enum ContainerMsg { pub enum CommandMessage { SetStarted, SetStopped, + FinishLaunchTerminal, } pub struct ContainerInit { @@ -103,6 +113,8 @@ impl FactoryComponent for Container { add_suffix = >k::Box{ gtk::AspectFrame{ + #[watch] + set_visible: !self.running_operations.contains(&ContainerOperation::LaunchingTerminal), set_ratio: 1.0, gtk::Button { set_icon_name: icon_names::TERMINAL, @@ -112,6 +124,23 @@ impl FactoryComponent for Container { set_css_classes: &["flat"], connect_clicked => ContainerMsg::OpenTerminal, }, + + }, + gtk::AspectFrame{ + #[watch] + set_visible: self.running_operations.contains(&ContainerOperation::LaunchingTerminal), + set_ratio: 1.0, + gtk::Button { + set_margin_start: 10, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["flat"], + #[wrap(Some)] + set_child = >k::Spinner { + #[watch] + set_spinning: self.running_operations.contains(&ContainerOperation::LaunchingTerminal), + }, + }, }, }, } @@ -122,6 +151,7 @@ impl FactoryComponent for Container { hash: index.clone(), value: value.name.clone(), status: value.status, + running_operations: HashSet::new(), } } @@ -143,7 +173,16 @@ impl FactoryComponent for Container { Err(_) => CommandMessage::SetStarted, }); } - ContainerMsg::OpenTerminal => {} + ContainerMsg::OpenTerminal => { + self.running_operations + .insert(ContainerOperation::LaunchingTerminal); + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || { + match open_toolbox_container_in_terminal(&hash) { + _ => CommandMessage::FinishLaunchTerminal, + } + }); + } } } @@ -151,6 +190,10 @@ impl FactoryComponent for Container { match message { CommandMessage::SetStarted => self.status = ContainerStatus::Running, CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning, + CommandMessage::FinishLaunchTerminal => { + self.running_operations + .remove(&ContainerOperation::LaunchingTerminal); + } }; } } diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 78e42c4..1f49500 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -149,6 +149,31 @@ impl ToolbxContainer { } } +pub fn open_toolbox_container_in_terminal(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("gnome-terminal") + .arg("--") + .arg("toolbox") + .arg("enter") + .arg(hash) + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} + pub fn stop_toolbox_container(hash: &str) -> Result<(), ToolbxError> { let output = Command::new("flatpak-spawn") .arg("--host") //Command::new("podman") From 84dfa4e93527196190a34660c637f089199ddd09 Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 2 Jul 2024 18:20:54 +0200 Subject: [PATCH 35/36] remove unused functionality --- src/factories/container_list.rs | 2 +- src/util/toolbox.rs | 77 --------------------------------- 2 files changed, 1 insertion(+), 78 deletions(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 7cb9673..7dadbab 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -186,7 +186,7 @@ impl FactoryComponent for Container { } } - fn update_cmd(&mut self, message: Self::CommandOutput, sender: FactorySender) { + fn update_cmd(&mut self, message: Self::CommandOutput, _sender: FactorySender) { match message { CommandMessage::SetStarted => self.status = ContainerStatus::Running, CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning, diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 1f49500..827c8e1 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -4,7 +4,6 @@ use std::{fmt::Display, process::Command, str::FromStr}; #[derive(Debug, PartialEq)] pub enum ToolbxError { ParseStatusError(String), - JSONSerializationError(String), CommandExecutionError(String), CommandUnsuccessfulError(String), } @@ -18,9 +17,6 @@ impl Display for ToolbxError { ToolbxError::CommandExecutionError(command_exec_error) => { write!(f, "{}", command_exec_error) } - ToolbxError::JSONSerializationError(msg) => { - write!(f, "{}", msg) - } ToolbxError::CommandUnsuccessfulError(command_unsuc_error) => { write!(f, "{}", command_unsuc_error) } @@ -68,85 +64,12 @@ pub struct ToolbxContainer { pub image: String, } -pub type PodmanInspectArray = Vec; - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PodmanInspectInfo { - #[serde(rename = "Id")] - pub id: String, - #[serde(rename = "Created")] - pub created: String, - #[serde(rename = "State")] - pub state: PodManInspectState, - #[serde(rename = "Image")] - pub image: String, - #[serde(rename = "ImageName")] - pub image_name: String, - #[serde(rename = "Name")] - pub name: String, -} - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PodManInspectState { - #[serde(rename = "Status")] - pub status: String, -} - -pub enum ToolboxCreateParameter { - None, - Distro(String), - Image(String), - Release(String), -} - impl ToolbxContainer { - pub fn new(name: String) -> ToolbxContainer { - ToolbxContainer { - name: name, - ..Default::default() - } - } - - pub fn create(name: String, parameter: ToolboxCreateParameter) { - todo!("Implement actual functionality to create toolbox via commandline") - } - pub fn get_toolboxes() -> Vec { let output = run_cmd_toolbx_list_containers(); println!("{}", output); parse_cmd_list_containers(output.as_str()) } - - fn parse_status(output: &str) -> Result { - let result: Result = serde_json::from_str(output); - match result { - Ok(inspect_vec) => match inspect_vec.first() { - Some(info) => Ok(info.clone()), - None => Err(ToolbxError::JSONSerializationError( - "Inspect command returned empty vector.".to_string(), - )), - }, - Err(e) => Err(ToolbxError::JSONSerializationError(e.to_string())), - } - } - - pub fn update_status(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") - .arg("podman") - .arg("container") - .arg("inspect") - .arg(self.name.clone()) - .output() - .expect("Failed to execute command"); - - let output = String::from_utf8_lossy(&output.stdout).to_string(); - let inspect_result = ToolbxContainer::parse_status(output.as_str())?; - self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; - Ok(()) - } } pub fn open_toolbox_container_in_terminal(hash: &str) -> Result<(), ToolbxError> { From 4ba1e6c6addd9253ef92f52545ed154ad40bb05a Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Tue, 2 Jul 2024 18:54:10 +0200 Subject: [PATCH 36/36] add detection of installed tools in host environment --- src/app.rs | 8 +++++-- src/util.rs | 1 + src/util/prerequisit.rs | 51 +++++++++++++++++++++++++++++++++++++++++ src/util/toolbox.rs | 3 ++- 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/util/prerequisit.rs diff --git a/src/app.rs b/src/app.rs index abbd6a4..ed8bc28 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,7 @@ use crate::gtk::Align; +use crate::util::prerequisit::get_installed_terminals; +use crate::util::prerequisit::is_toolbox_installed; + use crate::util::toolbox::ToolbxContainer; use relm4::adw::prelude::PreferencesGroupExt; use relm4::factory::FactoryHashMap; @@ -181,8 +184,9 @@ impl Component for App { }; sender.spawn_oneshot_command(|| { - // TODO: actually check for compatibility - AppCommandMsg::PrerequisitsInstalled(true) + let terminals = get_installed_terminals().unwrap_or_default(); + let toolbox_installed = is_toolbox_installed().unwrap_or(false); + AppCommandMsg::PrerequisitsInstalled(terminals.len() > 0 && toolbox_installed) }); actions.add_action(shortcuts_action); diff --git a/src/util.rs b/src/util.rs index b763831..ac9dcba 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1 +1,2 @@ +pub mod prerequisit; pub mod toolbox; diff --git a/src/util/prerequisit.rs b/src/util/prerequisit.rs new file mode 100644 index 0000000..5213ce1 --- /dev/null +++ b/src/util/prerequisit.rs @@ -0,0 +1,51 @@ +use crate::util::toolbox::ToolbxError; +use std::process::Command; + +pub enum TerminalType { + GnomeTerminal, +} + +pub fn get_installed_terminals() -> Result, ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("gnome-terminal") + .arg("--version") + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + + if output.status.code() == Some(0) { + Ok(vec![TerminalType::GnomeTerminal]) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} + +pub fn is_toolbox_installed() -> Result { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("toolbox") + .arg("--version") + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + if output.status.code() == Some(0) { + Ok(true) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 827c8e1..a4002bc 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -1,4 +1,3 @@ -use serde::{Deserialize, Serialize}; use std::{fmt::Display, process::Command, str::FromStr}; #[derive(Debug, PartialEq)] @@ -138,6 +137,7 @@ pub fn start_toolbox_container(hash: &str) -> Result<(), ToolbxError> { .output(); if output.is_err() { + dbg!(&output); return Err(ToolbxError::CommandExecutionError( output.unwrap_err().to_string(), )); @@ -155,6 +155,7 @@ pub fn start_toolbox_container(hash: &str) -> Result<(), ToolbxError> { if output.status.code() == Some(0) { Ok(()) } else { + dbg!(&output); Err(ToolbxError::CommandUnsuccessfulError( String::from_utf8_lossy(&output.stderr).into_owned(), ))