From 20c0a3ab730cd890dceab9859c79132e0f0441ac Mon Sep 17 00:00:00 2001
From: Andrey Kutejko <andy128k@gmail.com>
Date: Sat, 10 Aug 2024 17:00:34 +0200
Subject: [PATCH] Update dependencies

---
 Cargo.lock                          | 302 +++++++++++++++-------------
 Cargo.toml                          |  10 +-
 src/application.rs                  |  10 +-
 src/format/revelation/xml.rs        |   4 +-
 src/main_window.rs                  |  94 +++++----
 src/ui/dashboard.rs                 |  24 ++-
 src/ui/dialogs/generic_dialog.rs    |  28 ++-
 src/ui/dialogs/shortcuts.rs         |  20 +-
 src/ui/edit_object.rs               |  10 +-
 src/ui/edit_record/dialog.rs        |  34 +++-
 src/ui/edit_record/record_form.rs   |  10 +-
 src/ui/edit_record/record_widget.rs |  33 +--
 src/ui/file_pane.rs                 | 101 ++++++----
 src/ui/group_selector.rs            |  18 +-
 src/ui/list_item_factory.rs         |  60 ++++--
 src/ui/nav_bar.rs                   |  37 ++--
 src/ui/open_file.rs                 |  13 +-
 src/ui/password_editor/mod.rs       |  34 ++--
 src/ui/record_type_popover.rs       |  12 +-
 src/ui/record_view/item.rs          |  77 ++++---
 src/ui/record_view/view.rs          |  70 ++++---
 src/ui/search_bar.rs                |  73 +++++--
 src/ui/search_pane.rs               |  26 ++-
 src/ui/toast.rs                     |  50 +++--
 24 files changed, 707 insertions(+), 443 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 50e1ee01..c18abe71 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -21,9 +21,9 @@ dependencies = [
 
 [[package]]
 name = "anstream"
-version = "0.6.14"
+version = "0.6.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
 dependencies = [
  "anstyle",
  "anstyle-parse",
@@ -36,33 +36,33 @@ dependencies = [
 
 [[package]]
 name = "anstyle"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
 
 [[package]]
 name = "anstyle-parse"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
 dependencies = [
  "utf8parse",
 ]
 
 [[package]]
 name = "anstyle-query"
-version = "1.1.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
 dependencies = [
  "windows-sys 0.52.0",
 ]
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.3"
+version = "3.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
 dependencies = [
  "anstyle",
  "windows-sys 0.52.0",
@@ -76,9 +76,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
 
 [[package]]
 name = "awesome-glib"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b58ebe0a455f59bd6956c3361a1a1f4b51b368446248bef09adeca35807a6312"
+checksum = "f9b99f531a7217a90850d740013746ca3bc651fc58b534d8454487a4f624aff6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -87,18 +87,18 @@ dependencies = [
 
 [[package]]
 name = "awesome-gtk"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6cc35c025d550e19e05c194babf7596c2f3950ec3a7b6f49059dc98a3ce49f0"
+checksum = "b14c908b98dbafa3325268f520429462d4c49a6d27c98c59d2ed7df63e3f6169"
 dependencies = [
  "gtk4",
 ]
 
 [[package]]
 name = "bitflags"
-version = "2.5.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
 name = "block-padding"
@@ -109,11 +109,17 @@ dependencies = [
  "generic-array",
 ]
 
+[[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.19.4"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ac2a4d0e69036cf0062976f6efcba1aaee3e448594e6514bb2ddf87acce562"
+checksum = "797fd5a634dcb0ad0d7d583df794deb0a236d88e759cd34b7da20198c6c9d145"
 dependencies = [
  "bitflags",
  "cairo-sys-rs",
@@ -124,9 +130,9 @@ dependencies = [
 
 [[package]]
 name = "cairo-sys-rs"
-version = "0.19.2"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64"
+checksum = "428290f914b9b86089f60f5d8a9f6e440508e1bcff23b25afd51502b0a2da88f"
 dependencies = [
  "glib-sys",
  "libc",
@@ -144,9 +150,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.0.99"
+version = "1.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
+checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
 
 [[package]]
 name = "cfg-expr"
@@ -176,9 +182,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.7"
+version = "4.5.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
+checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -186,9 +192,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.7"
+version = "4.5.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
+checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
 dependencies = [
  "anstream",
  "anstyle",
@@ -198,9 +204,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.5"
+version = "4.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
+checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -210,15 +216,15 @@ dependencies = [
 
 [[package]]
 name = "clap_lex"
-version = "0.7.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
 
 [[package]]
 name = "colorchoice"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
 
 [[package]]
 name = "cpufeatures"
@@ -250,9 +256,9 @@ dependencies = [
 
 [[package]]
 name = "embed-resource"
-version = "2.4.2"
+version = "2.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d"
+checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602"
 dependencies = [
  "cc",
  "memchr",
@@ -369,9 +375,9 @@ dependencies = [
 
 [[package]]
 name = "gdk-pixbuf"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "624eaba126021103c7339b2e179ae4ee8cdab842daab419040710f38ed9f8699"
+checksum = "28bb53ecb56857c683c9ec859908e076dd3969c7d67598bd8b1ce095d211304a"
 dependencies = [
  "gdk-pixbuf-sys",
  "gio",
@@ -381,9 +387,9 @@ dependencies = [
 
 [[package]]
 name = "gdk-pixbuf-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4efa05a4f83c8cc50eb4d883787b919b85e5f1d8dd10b5a1df53bf5689782379"
+checksum = "9f6681a0c1330d1d3968bec1529f7172d62819ef0bdbb0d18022320654158b03"
 dependencies = [
  "gio-sys",
  "glib-sys",
@@ -394,9 +400,9 @@ dependencies = [
 
 [[package]]
 name = "gdk4"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db265c9dd42d6a371e09e52deab3a84808427198b86ac792d75fd35c07990a07"
+checksum = "4b7d7237c1487ed4b300aac7744efcbf1319e12d60d7afcd6f505414bd5b5dea"
 dependencies = [
  "cairo-rs",
  "gdk-pixbuf",
@@ -409,9 +415,9 @@ dependencies = [
 
 [[package]]
 name = "gdk4-sys"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9418fb4e8a67074919fe7604429c45aa74eb9df82e7ca529767c6d4e9dc66dd"
+checksum = "a67576c8ec012156d7f680e201a807b4432a77babb3157e0555e990ab6bcd878"
 dependencies = [
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
@@ -447,9 +453,9 @@ dependencies = [
 
 [[package]]
 name = "gio"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c49f117d373ffcc98a35d114db5478bc223341cff53e39a5d6feced9e2ddffe"
+checksum = "398e3da68749fdc32783cbf7521ec3f65c9cf946db8c7774f8460af49e52c6e2"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -465,9 +471,9 @@ dependencies = [
 
 [[package]]
 name = "gio-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cd743ba4714d671ad6b6234e8ab2a13b42304d0e13ab7eba1dcdd78a7d6d4ef"
+checksum = "e4feb96b31c32730ea3e1e89aecd2e4e37ecb1c473ad8f685e3430a159419f63"
 dependencies = [
  "glib-sys",
  "gobject-sys",
@@ -478,9 +484,9 @@ dependencies = [
 
 [[package]]
 name = "glib"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b664491bc77ab55daa6714a592cdbe1a55e28abec09cb50e87689b90de456ff4"
+checksum = "fee90a615ce05be7a32932cfb8adf2c4bbb4700e80d37713c981fb24c0c56238"
 dependencies = [
  "bitflags",
  "futures-channel",
@@ -500,18 +506,18 @@ dependencies = [
 
 [[package]]
 name = "glib-build-tools"
-version = "0.19.0"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "108f374fff60efd14b0d70d8916e7213aed18d7dd071ba3e9334ed2dac1dc86a"
+checksum = "7029c2651d9b5d5a3eea93ec8a1995665c6d3a69ce9bf6042ad9064d134736d8"
 dependencies = [
  "gio",
 ]
 
 [[package]]
 name = "glib-macros"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d405205a405182f95e637710850a8e82f25ba01fdd6baebc82dabeaf0883376"
+checksum = "4da558d8177c0c8c54368818b508a4244e1286fce2858cef4e547023f0cfa5ef"
 dependencies = [
  "heck",
  "proc-macro-crate",
@@ -522,9 +528,9 @@ dependencies = [
 
 [[package]]
 name = "glib-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c2dc18d3a82b0006d470b13304fbbb3e0a9bd4884cf985a60a7ed733ac2c4a5"
+checksum = "4958c26e5a01c9af00dea669a97369eccbec29a8e6d125c24ea2d85ee7467b60"
 dependencies = [
  "libc",
  "system-deps",
@@ -532,9 +538,9 @@ dependencies = [
 
 [[package]]
 name = "gobject-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e697e252d6e0416fd1d9e169bda51c0f1c926026c39ca21fbe8b1bb5c3b8b9e"
+checksum = "c6908864f5ffff15b56df7e90346863904f49b949337ed0456b9287af61903b8"
 dependencies = [
  "glib-sys",
  "libc",
@@ -543,9 +549,9 @@ dependencies = [
 
 [[package]]
 name = "graphene-rs"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5fb86031d24d9ec0a2a15978fc7a65d545a2549642cf1eb7c3dda358da42bcf"
+checksum = "630e940ad5824f90221d6579043a9cd1f8bec86b4a17faaf7827d58eb16e8c1f"
 dependencies = [
  "glib",
  "graphene-sys",
@@ -554,9 +560,9 @@ dependencies = [
 
 [[package]]
 name = "graphene-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f530e0944bccba4b55065e9c69f4975ad691609191ebac16e13ab8e1f27af05"
+checksum = "6fb8fade7b754982f47ebbed241fd2680816fdd4598321784da10b9e1168836a"
 dependencies = [
  "glib-sys",
  "libc",
@@ -566,9 +572,9 @@ dependencies = [
 
 [[package]]
 name = "gsk4"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7563884bf6939f4468e5d94654945bdd9afcaf8c3ba4c5dd17b5342b747221be"
+checksum = "1f3cf2091e1af185b347b3450817d93dea6fe435df7abd4c2cd7fb5bcb4cfda8"
 dependencies = [
  "cairo-rs",
  "gdk4",
@@ -581,9 +587,9 @@ dependencies = [
 
 [[package]]
 name = "gsk4-sys"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23024bf2636c38bbd1f822f58acc9d1c25b28da896ff0f291a1a232d4272b3dc"
+checksum = "6aa69614a26d8760c186c3690f1b0fbb917572ca23ef83137445770ceddf8cde"
 dependencies = [
  "cairo-sys-rs",
  "gdk4-sys",
@@ -597,9 +603,9 @@ dependencies = [
 
 [[package]]
 name = "gtk4"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b04e11319b08af11358ab543105a9e49b0c491faca35e2b8e7e36bfba8b671ab"
+checksum = "eaffc6c743c9160514cc9b67eace364e5dc5798369fa809cdb04e035c21c5c5d"
 dependencies = [
  "cairo-rs",
  "field-offset",
@@ -618,9 +624,9 @@ dependencies = [
 
 [[package]]
 name = "gtk4-macros"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec655a7ef88d8ce9592899deb8b2d0fa50bab1e6dd69182deb764e643c522408"
+checksum = "188211f546ce5801f6d0245c37b6249143a2cb4fa040e54829ca1e76796e9f09"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -630,9 +636,9 @@ dependencies = [
 
 [[package]]
 name = "gtk4-sys"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c8aa86b7f85ea71d66ea88c1d4bae1cfacf51ca4856274565133838d77e57b5"
+checksum = "1114a207af8ada02cf4658a76692f4190f06f093380d5be07e3ca8b43aa7c666"
 dependencies = [
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
@@ -661,9 +667,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
 name = "indexmap"
-version = "2.2.6"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -690,9 +696,9 @@ dependencies = [
 
 [[package]]
 name = "is_terminal_polyfill"
-version = "1.70.0"
+version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 
 [[package]]
 name = "libc"
@@ -717,9 +723,9 @@ dependencies = [
 
 [[package]]
 name = "pango"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f0d328648058085cfd6897c9ae4272884098a926f3a833cd50c8c73e6eccecd"
+checksum = "54768854025df6903061d0084fd9702a253ddfd60db7d9b751d43b76689a7f0a"
 dependencies = [
  "gio",
  "glib",
@@ -729,9 +735,9 @@ dependencies = [
 
 [[package]]
 name = "pango-sys"
-version = "0.19.8"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff03da4fa086c0b244d4a4587d3e20622a3ecdb21daea9edf66597224c634ba0"
+checksum = "b07cc57d10cee4ec661f718a6902cee18c2f4cfae08e87e5a390525946913390"
 dependencies = [
  "glib-sys",
  "gobject-sys",
@@ -780,9 +786,12 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.17"
+version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
 
 [[package]]
 name = "proc-macro-crate"
@@ -804,9 +813,9 @@ dependencies = [
 
 [[package]]
 name = "quick-xml"
-version = "0.33.0"
+version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca7dd09b5f4a9029c35e323b086d0a68acdc673317b9c4d002c6f1d4a7278c6"
+checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc"
 dependencies = [
  "memchr",
 ]
@@ -867,18 +876,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.203"
+version = "1.0.205"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
+checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.203"
+version = "1.0.205"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
+checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -887,9 +896,9 @@ dependencies = [
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.6"
+version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
+checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
 dependencies = [
  "serde",
 ]
@@ -917,9 +926,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.67"
+version = "2.0.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
+checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -928,9 +937,9 @@ dependencies = [
 
 [[package]]
 name = "system-deps"
-version = "6.2.2"
+version = "7.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
+checksum = "6c81f13d9a334a6c242465140bd262fae382b752ff2011c4f7419919a9c97922"
 dependencies = [
  "cfg-expr",
  "heck",
@@ -941,24 +950,24 @@ dependencies = [
 
 [[package]]
 name = "target-lexicon"
-version = "0.12.14"
+version = "0.12.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
 
 [[package]]
 name = "thiserror"
-version = "1.0.61"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
+checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.61"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
+checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -967,21 +976,21 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.14"
+version = "0.8.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
 dependencies = [
  "serde",
  "serde_spanned",
  "toml_datetime",
- "toml_edit 0.22.14",
+ "toml_edit 0.22.20",
 ]
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.6"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
 dependencies = [
  "serde",
 ]
@@ -999,15 +1008,15 @@ dependencies = [
 
 [[package]]
 name = "toml_edit"
-version = "0.22.14"
+version = "0.22.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
+checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
 dependencies = [
  "indexmap",
  "serde",
  "serde_spanned",
  "toml_datetime",
- "winnow 0.6.13",
+ "winnow 0.6.18",
 ]
 
 [[package]]
@@ -1036,9 +1045,9 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
 
 [[package]]
 name = "version_check"
-version = "0.9.4"
+version = "0.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
 
 [[package]]
 name = "vswhom"
@@ -1081,7 +1090,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets 0.52.5",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -1101,18 +1110,18 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.5",
- "windows_aarch64_msvc 0.52.5",
- "windows_i686_gnu 0.52.5",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
  "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.5",
- "windows_x86_64_gnu 0.52.5",
- "windows_x86_64_gnullvm 0.52.5",
- "windows_x86_64_msvc 0.52.5",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
 ]
 
 [[package]]
@@ -1123,9 +1132,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
 [[package]]
 name = "windows_aarch64_msvc"
@@ -1135,9 +1144,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
 [[package]]
 name = "windows_i686_gnu"
@@ -1147,15 +1156,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 
 [[package]]
 name = "windows_i686_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[package]]
 name = "windows_i686_msvc"
@@ -1165,9 +1174,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
 [[package]]
 name = "windows_x86_64_gnu"
@@ -1177,9 +1186,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
@@ -1189,9 +1198,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
 name = "windows_x86_64_msvc"
@@ -1201,9 +1210,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "winnow"
@@ -1216,9 +1225,9 @@ dependencies = [
 
 [[package]]
 name = "winnow"
-version = "0.6.13"
+version = "0.6.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
+checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
 dependencies = [
  "memchr",
 ]
@@ -1232,3 +1241,24 @@ dependencies = [
  "cfg-if",
  "windows-sys 0.48.0",
 ]
+
+[[package]]
+name = "zerocopy"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "byteorder",
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
index f6616f45..1bc7ef8a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,19 +17,19 @@ aes = "0.8"
 cbc = "0.1"
 deflate = "1"
 inflate = "0.4"
-quick-xml = "0.33"
+quick-xml = "0.36"
 
 toml = "0.8"
 serde = { version = "1", features = ["derive"] }
 
-gtk = { package = "gtk4", version = "0.8", features = ["v4_12"] }
-awesome-glib = "0.4"
-awesome-gtk = "0.4"
+gtk = { package = "gtk4", version = "0.9", features = ["v4_12"] }
+awesome-glib = "0.5"
+awesome-gtk = "0.5"
 
 clap = { version = "4.5.4", features = ["derive"] }
 
 [build-dependencies]
-glib-build-tools = "0.19"
+glib-build-tools = "0.20"
 
 [target.'cfg(target_os = "windows")'.build-dependencies]
 embed-resource = "2"
diff --git a/src/application.rs b/src/application.rs
index 3c1d0750..668e0867 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -64,11 +64,13 @@ mod imp {
 
             let files = files.to_owned();
             let hint = hint.to_owned();
-            glib::MainContext::default().spawn_local(
-                glib::clone!(@weak self as imp => async move {
+            glib::MainContext::default().spawn_local(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                async move {
                     imp.on_open(&files, &hint).await;
-                }),
-            );
+                }
+            ));
         }
     }
 
diff --git a/src/format/revelation/xml.rs b/src/format/revelation/xml.rs
index 321cc373..1e48797d 100644
--- a/src/format/revelation/xml.rs
+++ b/src/format/revelation/xml.rs
@@ -196,7 +196,9 @@ fn read_attribute<R: BufRead>(
     for attr in atts.with_checks(false) {
         let attr = attr?;
         if attr.key.as_ref() == name {
-            let value = attr.decode_and_unescape_value(reader)?.to_string();
+            let value = attr
+                .decode_and_unescape_value(reader.decoder())?
+                .to_string();
             return Ok(Some(value));
         }
     }
diff --git a/src/main_window.rs b/src/main_window.rs
index cce39388..4b1b6e52 100644
--- a/src/main_window.rs
+++ b/src/main_window.rs
@@ -159,55 +159,73 @@ mod imp {
             });
             *self.delete_handler.borrow_mut() = Some(delete_handler);
 
-            self.search_bar
-                .connect_search(glib::clone!(@weak win => move |event| {
+            self.search_bar.connect_search(glib::clone!(
+                #[weak]
+                win,
+                move |event| {
                     glib::MainContext::default().spawn_local(async move {
                         win.search(&event).await;
                     });
-                }));
-            self.search_bar.connect_configure(
-                glib::clone!(@weak self as imp => move |search_config| {
-                    imp.config_service.get().unwrap()
-                        .update(|config| {
-                            config.search_in_secrets = search_config.search_in_secrets;
-                        });
-                }),
-            );
-            self.search_bar
-                .connect_search_closed(glib::clone!(@weak self as imp => move || {
+                }
+            ));
+            self.search_bar.connect_configure(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |search_config| {
+                    imp.config_service.get().unwrap().update(|config| {
+                        config.search_in_secrets = search_config.search_in_secrets;
+                    });
+                }
+            ));
+            self.search_bar.connect_search_closed(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move || {
                     imp.search_reset();
                     imp.set_mode(imp::AppMode::FileOpened);
-                }));
+                }
+            ));
 
-            self.file_pane.connect_edit_record(
-                glib::clone!(@weak win => move |_, position, record_node| {
+            self.file_pane.connect_edit_record(glib::clone!(
+                #[weak]
+                win,
+                move |_, position, record_node| {
                     glib::MainContext::default().spawn_local(async move {
                         win.action_edit(position, record_node).await;
                     });
-                }),
-            );
-            self.file_pane
-                .connect_file_changed(glib::clone!(@weak win => move |_| {
+                }
+            ));
+            self.file_pane.connect_file_changed(glib::clone!(
+                #[weak]
+                win,
+                move |_| {
                     win.set_changed(true);
-                }));
-            self.file_pane.connect_user_notification(
-                glib::clone!(@weak self as imp => move |_, message| {
+                }
+            ));
+            self.file_pane.connect_user_notification(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_, message| {
                     imp.toast.notify(message);
-                }),
-            );
+                }
+            ));
 
-            self.search_pane.connect_edit_record(
-                glib::clone!(@weak win => move |_, position, record_node| {
+            self.search_pane.connect_edit_record(glib::clone!(
+                #[weak]
+                win,
+                move |_, position, record_node| {
                     glib::MainContext::default().spawn_local(async move {
                         win.action_edit(position, record_node).await;
                     });
-                }),
-            );
-            self.search_pane.connect_user_notification(
-                glib::clone!(@weak self as imp => move |_, message| {
+                }
+            ));
+            self.search_pane.connect_user_notification(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_, message| {
                     imp.toast.notify(message);
-                }),
-            );
+                }
+            ));
         }
     }
 
@@ -511,11 +529,13 @@ impl PSMainWindow {
 
         let config = config_service.get();
         win.imp().search_bar.configure(config.search_in_secrets);
-        config_service
-            .on_change
-            .subscribe(glib::clone!(@weak win => move |new_config| {
+        config_service.on_change.subscribe(glib::clone!(
+            #[weak]
+            win,
+            move |new_config| {
                 win.imp().search_bar.configure(new_config.search_in_secrets);
-            }));
+            }
+        ));
 
         win.present();
         win.imp().set_mode(imp::AppMode::Initial);
diff --git a/src/ui/dashboard.rs b/src/ui/dashboard.rs
index 11be2b00..867ecc90 100644
--- a/src/ui/dashboard.rs
+++ b/src/ui/dashboard.rs
@@ -105,9 +105,13 @@ pub fn file_row(
         .child(&grid)
         .build();
 
-    remove_button.connect_clicked(glib::clone!(@weak row => move |_| {
-        on_remove(&row, &filename);
-    }));
+    remove_button.connect_clicked(glib::clone!(
+        #[weak]
+        row,
+        move |_| {
+            on_remove(&row, &filename);
+        }
+    ));
 
     set_group_title(&row, "Recent files");
 
@@ -194,10 +198,16 @@ impl PSDashboard {
         for filename in cache.recent_files() {
             if let Some(row) = file_row(
                 filename,
-                glib::clone!(@weak self.listbox as listbox, @strong cache => move |row, filename| {
-                    cache.remove_file(filename);
-                    listbox.remove(row);
-                }),
+                glib::clone!(
+                    #[weak(rename_to = listbox)]
+                    self.listbox,
+                    #[strong]
+                    cache,
+                    move |row, filename| {
+                        cache.remove_file(filename);
+                        listbox.remove(row);
+                    }
+                ),
             ) {
                 self.listbox.append(&row);
                 if first_row.is_none() {
diff --git a/src/ui/dialogs/generic_dialog.rs b/src/ui/dialogs/generic_dialog.rs
index ea3db026..ca45512a 100644
--- a/src/ui/dialogs/generic_dialog.rs
+++ b/src/ui/dialogs/generic_dialog.rs
@@ -56,14 +56,18 @@ mod imp {
             *self.sender.borrow_mut() = Some(sender.clone());
             *self.receiver.borrow_mut() = Some(receiver);
 
-            self.cancel_button.connect_clicked(
-                glib::clone!(@weak self as imp => move |_| imp.send(gtk::ResponseType::Cancel)),
-            );
+            self.cancel_button.connect_clicked(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_| imp.send(gtk::ResponseType::Cancel)
+            ));
             header.pack_start(&self.cancel_button);
 
-            self.ok_button.connect_clicked(
-                glib::clone!(@weak self as imp => move |_| imp.send(gtk::ResponseType::Ok)),
-            );
+            self.ok_button.connect_clicked(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_| imp.send(gtk::ResponseType::Ok)
+            ));
             header.pack_end(&self.ok_button);
 
             self.obj().set_modal(true);
@@ -72,8 +76,12 @@ mod imp {
             self.obj().set_icon_name(Some("password-storage"));
 
             let key_controller = gtk::EventControllerKey::new();
-            key_controller.connect_key_pressed(
-                glib::clone!(@weak self as imp => @default-return glib::Propagation::Proceed, move |_controller, key, _keycode, modifier| {
+            key_controller.connect_key_pressed(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                #[upgrade_or]
+                glib::Propagation::Proceed,
+                move |_controller, key, _keycode, modifier| {
                     const NO_MODIFIER: gdk::ModifierType = gdk::ModifierType::empty();
                     match (key, modifier) {
                         (gdk::Key::Escape, NO_MODIFIER)
@@ -88,8 +96,8 @@ mod imp {
                         }
                         _ => glib::Propagation::Proceed,
                     }
-                }),
-            );
+                }
+            ));
             self.obj().add_controller(key_controller);
         }
     }
diff --git a/src/ui/dialogs/shortcuts.rs b/src/ui/dialogs/shortcuts.rs
index 4b908922..f01e5fe0 100644
--- a/src/ui/dialogs/shortcuts.rs
+++ b/src/ui/dialogs/shortcuts.rs
@@ -16,20 +16,24 @@ pub fn shortcuts_window(
     window.set_transient_for(parent);
 
     let key_controller = gtk::EventControllerKey::new();
-    key_controller.connect_key_pressed(
-        glib::clone!(@weak window => @default-return glib::Propagation::Proceed, move |_controller, key, _keycode, modifier| {
+    key_controller.connect_key_pressed(glib::clone!(
+        #[weak]
+        window,
+        #[upgrade_or]
+        glib::Propagation::Proceed,
+        move |_controller, key, _keycode, modifier| {
             const NO_MODIFIER: gdk::ModifierType = gdk::ModifierType::empty();
             match (key, modifier) {
-                (gdk::Key::Escape, NO_MODIFIER) |
-                (gdk::Key::w, PRIMARY_MODIFIER) |
-                (gdk::Key::W, PRIMARY_MODIFIER) => {
+                (gdk::Key::Escape, NO_MODIFIER)
+                | (gdk::Key::w, PRIMARY_MODIFIER)
+                | (gdk::Key::W, PRIMARY_MODIFIER) => {
                     window.close();
                     glib::Propagation::Stop
-                },
+                }
                 _ => glib::Propagation::Proceed,
             }
-        }),
-    );
+        }
+    ));
     window.add_controller(key_controller);
 
     let grid = gtk::Grid::builder()
diff --git a/src/ui/edit_object.rs b/src/ui/edit_object.rs
index 0e0fb801..ab03e1f6 100644
--- a/src/ui/edit_object.rs
+++ b/src/ui/edit_object.rs
@@ -22,9 +22,13 @@ pub async fn edit_object<T: 'static, W: FormWidget<T> + 'static>(
     dlg.set_child(Some(&form));
 
     dlg.set_ok_sensitive(widget.get_value().is_some());
-    widget.connect_changed(Box::new(glib::clone!(@weak dlg => move |value| {
-        dlg.set_ok_sensitive(value.is_some());
-    })));
+    widget.connect_changed(Box::new(glib::clone!(
+        #[weak]
+        dlg,
+        move |value| {
+            dlg.set_ok_sensitive(value.is_some());
+        }
+    )));
 
     widget.set_value(object);
 
diff --git a/src/ui/edit_record/dialog.rs b/src/ui/edit_record/dialog.rs
index 6e5db239..ae9b5ecd 100644
--- a/src/ui/edit_record/dialog.rs
+++ b/src/ui/edit_record/dialog.rs
@@ -147,11 +147,15 @@ impl RecordWidget {
             callback: RefCell::new(Box::new(no_op)),
         }));
 
-        open_button.connect_clicked(glib::clone!(@weak widget => move |_| {
-            glib::MainContext::default().spawn_local(async move {
-                widget.open().await;
-            });
-        }));
+        open_button.connect_clicked(glib::clone!(
+            #[weak]
+            widget,
+            move |_| {
+                glib::MainContext::default().spawn_local(async move {
+                    widget.open().await;
+                });
+            }
+        ));
 
         widget
     }
@@ -172,9 +176,13 @@ impl RecordWidget {
 
             let popover = RecordTypePopoverBuilder::default()
                 .record_types(&convert_to_types)
-                .on_activate(glib::clone!(@weak self as this => move |dest_record_type| {
-                    this.convert_to(dest_record_type);
-                }))
+                .on_activate(glib::clone!(
+                    #[weak(rename_to = this)]
+                    self,
+                    move |dest_record_type| {
+                        this.convert_to(dest_record_type);
+                    }
+                ))
                 .build();
 
             self.0.convert_button.set_popover(Some(&popover));
@@ -187,9 +195,13 @@ impl RecordWidget {
             self.0.grid.remove(&old_form);
         }
         let mut form = RecordForm::new(record_type, &self.0.names);
-        form.connect_changed(Box::new(glib::clone!(@weak self as this => move |value| {
-            this.0.callback.borrow()(value);
-        })));
+        form.connect_changed(Box::new(glib::clone!(
+            #[weak(rename_to = this)]
+            self,
+            move |value| {
+                this.0.callback.borrow()(value);
+            }
+        )));
         let form_widget = form.get_widget();
         *self.0.form.borrow_mut() = Some(form);
 
diff --git a/src/ui/edit_record/record_form.rs b/src/ui/edit_record/record_form.rs
index 4db544d1..03f6e26b 100644
--- a/src/ui/edit_record/record_form.rs
+++ b/src/ui/edit_record/record_form.rs
@@ -83,9 +83,13 @@ mod imp {
                     .build();
                 self.grid.attach(&label_widget, 0, index as i32, 1, 1);
 
-                widget.connect_changed(Box::new(glib::clone!(@weak self as this => move |_| {
-                    this.obj().emit_by_name::<()>("record-changed", &[]);
-                })));
+                widget.connect_changed(Box::new(glib::clone!(
+                    #[weak(rename_to = this)]
+                    self,
+                    move |_| {
+                        this.obj().emit_by_name::<()>("record-changed", &[]);
+                    }
+                )));
                 self.grid
                     .attach(&widget.get_widget(), 1, index as i32, 1, 1);
 
diff --git a/src/ui/edit_record/record_widget.rs b/src/ui/edit_record/record_widget.rs
index e6aeeef6..558e4ae4 100644
--- a/src/ui/edit_record/record_widget.rs
+++ b/src/ui/edit_record/record_widget.rs
@@ -79,12 +79,13 @@ mod imp {
                 .build();
             self.grid.attach(&separator, 1, 0, 1, 5);
 
-            self.open_button
-                .connect_clicked(glib::clone!(@weak self as imp => move |_| {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.open().await
-                    });
-                }));
+            self.open_button.connect_clicked(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_| {
+                    glib::MainContext::default().spawn_local(async move { imp.open().await });
+                }
+            ));
         }
 
         fn signals() -> &'static [glib::subclass::Signal] {
@@ -121,9 +122,13 @@ mod imp {
 
                 let popover = RecordTypePopoverBuilder::default()
                     .record_types(&convert_to_types)
-                    .on_activate(glib::clone!(@weak self as this => move |dest_record_type| {
-                        this.convert_to(dest_record_type);
-                    }))
+                    .on_activate(glib::clone!(
+                        #[weak(rename_to = this)]
+                        self,
+                        move |dest_record_type| {
+                            this.convert_to(dest_record_type);
+                        }
+                    ))
                     .build();
 
                 self.convert_button.set_popover(Some(&popover));
@@ -136,9 +141,13 @@ mod imp {
                 self.grid.remove(&old_form);
             }
             let form = RecordForm::new(record_type, &self.names.borrow());
-            form.connect_record_changed(glib::clone!(@weak self as this => move |_| {
-                this.obj().emit_by_name::<()>("record-changed", &[]);
-            }));
+            form.connect_record_changed(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |_| {
+                    this.obj().emit_by_name::<()>("record-changed", &[]);
+                }
+            ));
             *self.form.borrow_mut() = Some(form.clone());
 
             form.set_hexpand(true);
diff --git a/src/ui/file_pane.rs b/src/ui/file_pane.rs
index 56814caa..1d2e8bee 100644
--- a/src/ui/file_pane.rs
+++ b/src/ui/file_pane.rs
@@ -124,54 +124,71 @@ mod imp {
             grid.attach(&action_bar, 0, 2, 1, 1);
             grid.set_parent(&*obj);
 
-            self.view.connect_selection_changed(
-                glib::clone!(@weak obj => move |selected_records| {
+            self.view.connect_selection_changed(glib::clone!(
+                #[weak]
+                obj,
+                move |selected_records| {
                     obj.selection_changed(selected_records);
-                }),
-            );
+                }
+            ));
 
-            self.view
-                .connect_record_activated(glib::clone!(@weak self as imp => move |position| {
+            self.view.connect_record_activated(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |position| {
                     glib::MainContext::default().spawn_local(async move {
                         imp.row_activated(position).await;
                     });
-                }));
+                }
+            ));
 
-            self.nav_bar
-                .connect_go_home(glib::clone!(@weak self as imp => move || {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.go_home().await
-                    });
-                }));
-            self.nav_bar
-                .connect_go_path(glib::clone!(@weak self as imp => move |position| {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.go_path(position).await
-                    });
-                }));
-            self.nav_bar
-                .connect_go_up(glib::clone!(@weak self as imp => move || {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.go_up().await
-                    });
-                }));
-            self.view
-                .connect_go_home(glib::clone!(@weak self as imp => move || {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.go_home().await
-                    });
-                }));
-            self.view
-                .connect_go_up(glib::clone!(@weak self as imp => move || {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.go_up().await
-                    });
-                }));
-            self.view.connect_move_record(
-                glib::clone!(@weak self as imp => move |_, src, dst, opt| {
-                    imp.move_record(src.downcast_ref().unwrap(), dst.downcast_ref().unwrap(), opt);
-                }),
-            );
+            self.nav_bar.connect_go_home(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move || {
+                    glib::MainContext::default().spawn_local(async move { imp.go_home().await });
+                }
+            ));
+            self.nav_bar.connect_go_path(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |position| {
+                    glib::MainContext::default()
+                        .spawn_local(async move { imp.go_path(position).await });
+                }
+            ));
+            self.nav_bar.connect_go_up(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move || {
+                    glib::MainContext::default().spawn_local(async move { imp.go_up().await });
+                }
+            ));
+            self.view.connect_go_home(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move || {
+                    glib::MainContext::default().spawn_local(async move { imp.go_home().await });
+                }
+            ));
+            self.view.connect_go_up(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move || {
+                    glib::MainContext::default().spawn_local(async move { imp.go_up().await });
+                }
+            ));
+            self.view.connect_move_record(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_, src, dst, opt| {
+                    imp.move_record(
+                        src.downcast_ref().unwrap(),
+                        dst.downcast_ref().unwrap(),
+                        opt,
+                    );
+                }
+            ));
 
             self.set_view_model(&self.file.borrow().records);
 
diff --git a/src/ui/group_selector.rs b/src/ui/group_selector.rs
index 9f9d643a..34aa112f 100644
--- a/src/ui/group_selector.rs
+++ b/src/ui/group_selector.rs
@@ -179,19 +179,23 @@ pub async fn select_group(
             .build(),
     );
 
-    tree_view.connect_activate(
-        glib::clone!(@weak dlg => move |_, _| dlg.emit_response(gtk::ResponseType::Ok)),
-    );
+    tree_view.connect_activate(glib::clone!(
+        #[weak]
+        dlg,
+        move |_, _| dlg.emit_response(gtk::ResponseType::Ok)
+    ));
 
     let scrolled_window = scrolled(&tree_view);
     scrolled_window.set_size_request(500, 400);
     dlg.set_child(Some(&scrolled_window));
 
-    selection_model.connect_selection_changed(
-        glib::clone!(@weak dlg => move |selection_model, _, _| {
+    selection_model.connect_selection_changed(glib::clone!(
+        #[weak]
+        dlg,
+        move |selection_model, _, _| {
             dlg.set_ok_sensitive(get_selected_record(selection_model).is_some());
-        }),
-    );
+        }
+    ));
 
     match dlg.run().await {
         Some(gtk::ResponseType::Ok) => get_selected_record(&selection_model),
diff --git a/src/ui/list_item_factory.rs b/src/ui/list_item_factory.rs
index 6ebb2651..0684e9af 100644
--- a/src/ui/list_item_factory.rs
+++ b/src/ui/list_item_factory.rs
@@ -12,34 +12,50 @@ pub trait PSListItemFactory: Sized + 'static {
     fn into_factory(self) -> gtk::ListItemFactory {
         let this = Rc::new(self);
         let factory = gtk::SignalListItemFactory::new();
-        factory.connect_setup(glib::clone!(@strong this => move |_factory, item| {
-            if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
-                let child = this.setup();
-                list_item.set_child(Some(&child));
+        factory.connect_setup(glib::clone!(
+            #[strong]
+            this,
+            move |_factory, item| {
+                if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
+                    let child = this.setup();
+                    list_item.set_child(Some(&child));
+                }
             }
-        }));
-        factory.connect_bind(glib::clone!(@strong this => move |_factory, item| {
-            if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
-                if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
-                    this.bind(list_item, &child);
-                };
+        ));
+        factory.connect_bind(glib::clone!(
+            #[strong]
+            this,
+            move |_factory, item| {
+                if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
+                    if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
+                        this.bind(list_item, &child);
+                    };
+                }
             }
-        }));
-        factory.connect_unbind(glib::clone!(@strong this => move |_factory, item| {
-            if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
-                if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
-                    this.unbind(list_item, &child);
+        ));
+        factory.connect_unbind(glib::clone!(
+            #[strong]
+            this,
+            move |_factory, item| {
+                if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
+                    if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
+                        this.unbind(list_item, &child);
+                    }
                 }
             }
-        }));
-        factory.connect_teardown(glib::clone!(@strong this => move |_factory, item| {
-            if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
-                if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
-                    this.teardown(list_item, &child);
+        ));
+        factory.connect_teardown(glib::clone!(
+            #[strong]
+            this,
+            move |_factory, item| {
+                if let Some(list_item) = item.downcast_ref::<gtk::ListItem>() {
+                    if let Some(child) = list_item.child().and_downcast::<Self::Child>() {
+                        this.teardown(list_item, &child);
+                    }
+                    list_item.set_child(gtk::Widget::NONE);
                 }
-                list_item.set_child(gtk::Widget::NONE);
             }
-        }));
+        ));
         factory.upcast()
     }
 }
diff --git a/src/ui/nav_bar.rs b/src/ui/nav_bar.rs
index 223e40c0..35bedc50 100644
--- a/src/ui/nav_bar.rs
+++ b/src/ui/nav_bar.rs
@@ -106,10 +106,13 @@ mod imp {
             obj.set_margin_start(5);
             obj.set_margin_end(5);
 
-            self.home_button
-                .connect_clicked(glib::clone!(@weak obj => move |_| {
+            self.home_button.connect_clicked(glib::clone!(
+                #[weak]
+                obj,
+                move |_| {
                     obj.emit_go_home();
-                }));
+                }
+            ));
             obj.grid_attach(&self.home_button).set_column(0);
 
             let sw = gtk::ScrolledWindow::builder()
@@ -122,15 +125,21 @@ mod imp {
                 .build();
             obj.grid_attach(&sw).set_column(1);
 
-            self.list_view
-                .connect_activate(glib::clone!(@weak obj => move |_, position| {
+            self.list_view.connect_activate(glib::clone!(
+                #[weak]
+                obj,
+                move |_, position| {
                     obj.emit_go_path(position);
-                }));
+                }
+            ));
 
-            self.up_button
-                .connect_clicked(glib::clone!(@weak obj => move |_| {
+            self.up_button.connect_clicked(glib::clone!(
+                #[weak]
+                obj,
+                move |_| {
                     obj.emit_go_up();
-                }));
+                }
+            ));
             obj.grid_attach(&self.up_button).set_column(2);
         }
 
@@ -192,11 +201,13 @@ impl PSNavBar {
         self.imp().disconnect_model_change_handler();
         self.imp()
             .model_change_handler
-            .set(Some(model.connect_items_changed(
-                glib::clone!(@weak self as this => move |model, _, _, _| {
+            .set(Some(model.connect_items_changed(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |model, _, _, _| {
                     this.imp().model_changed(model);
-                }),
-            )));
+                }
+            ))));
         self.imp().model_changed(model);
     }
 }
diff --git a/src/ui/open_file.rs b/src/ui/open_file.rs
index 2e31026f..926e1b9f 100644
--- a/src/ui/open_file.rs
+++ b/src/ui/open_file.rs
@@ -99,12 +99,13 @@ mod imp {
                 move |_| sender.send(gtk::ResponseType::Accept)
             });
 
-            self.entry.connect_changed(
-                glib::clone!(@weak self.open_button as open_button => move |e| {
-                    let text_length = e.chars(0, -1).len();
-                    open_button.set_sensitive(text_length > 0);
-                }),
-            );
+            self.entry.connect_changed(glib::clone!(
+                #[weak(rename_to = open_button)]
+                self.open_button,
+                move |entry| {
+                    open_button.set_sensitive(entry.text_length() > 0);
+                }
+            ));
 
             self.entry.connect_activate({
                 let sender = ResponseSender::new(&sender);
diff --git a/src/ui/password_editor/mod.rs b/src/ui/password_editor/mod.rs
index 8bc37cae..db6565c9 100644
--- a/src/ui/password_editor/mod.rs
+++ b/src/ui/password_editor/mod.rs
@@ -46,31 +46,39 @@ impl PasswordEditor {
             .width_request(300)
             .hexpand(true)
             .build();
-        entry.connect_changed(glib::clone!(@weak level => move |e| {
-            let strength = get_value(e)
-                .map(|text| password_entropy(&AsciiClassifier, text.as_bytes()).into());
-            level.set_strength(strength);
-        }));
+        entry.connect_changed(glib::clone!(
+            #[weak]
+            level,
+            move |e| {
+                let strength = get_value(e)
+                    .map(|text| password_entropy(&AsciiClassifier, text.as_bytes()).into());
+                level.set_strength(strength);
+            }
+        ));
 
         let visibility_toggle = gtk::ToggleButton::builder()
             .icon_name("eye")
             .tooltip_text("Reveal password")
             .has_frame(false)
             .build();
-        visibility_toggle.connect_clicked(glib::clone!(@weak entry => move |t| {
-            entry.set_visibility(t.is_active());
-        }));
+        visibility_toggle.connect_clicked(glib::clone!(
+            #[weak]
+            entry,
+            move |t| entry.set_visibility(t.is_active())
+        ));
 
         let generate_button = gtk::Button::builder()
             .icon_name("random")
             .tooltip_text("Generate password")
             .has_frame(false)
             .build();
-        generate_button.connect_clicked(glib::clone!(@weak entry => move |_| {
-            glib::MainContext::default().spawn_local(
-                generate_password_clicked(entry)
-            );
-        }));
+        generate_button.connect_clicked(glib::clone!(
+            #[weak]
+            entry,
+            move |_| {
+                glib::MainContext::default().spawn_local(generate_password_clicked(entry));
+            }
+        ));
 
         let container = gtk::Grid::builder()
             .row_spacing(5)
diff --git a/src/ui/record_type_popover.rs b/src/ui/record_type_popover.rs
index 5e6106dc..c614f0ab 100644
--- a/src/ui/record_type_popover.rs
+++ b/src/ui/record_type_popover.rs
@@ -52,12 +52,16 @@ impl<'b> RecordTypePopoverBuilder<'b> {
                 if let Some(ref action_name_func) = action_name_func {
                     button.set_detailed_action_name(&(action_name_func)(record_type));
                 }
-                button.connect_clicked(
-                    glib::clone!(@weak popover, @strong on_activate => move |_| {
+                button.connect_clicked(glib::clone!(
+                    #[weak]
+                    popover,
+                    #[strong]
+                    on_activate,
+                    move |_| {
                         popover.popdown();
                         on_activate(record_type);
-                    }),
-                );
+                    }
+                ));
                 button.upcast()
             })
             .collect();
diff --git a/src/ui/record_view/item.rs b/src/ui/record_view/item.rs
index 2ec60260..6b0242ae 100644
--- a/src/ui/record_view/item.rs
+++ b/src/ui/record_view/item.rs
@@ -96,21 +96,24 @@ mod imp {
             self.open.set_parent(&*obj);
 
             self.context_click.set_button(GDK_BUTTON_SECONDARY as u32);
-            self.context_click.connect_pressed(
-                glib::clone!(@weak self as imp => move |_gesture, _n, x, y| imp.on_context_click(x, y)),
-            );
+            self.context_click.connect_pressed(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_gesture, _n, x, y| imp.on_context_click(x, y)
+            ));
             obj.add_controller(self.context_click.clone());
 
             let open_click = gtk::GestureClick::builder()
                 .button(GDK_BUTTON_PRIMARY as u32)
                 .build();
-            open_click.connect_pressed(
-                glib::clone!(@weak self as imp => move |_gesture, _n, _x, _y| {
-                    glib::MainContext::default().spawn_local(async move {
-                        imp.on_open_clicked().await
-                    });
-                }),
-            );
+            open_click.connect_pressed(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_gesture, _n, _x, _y| {
+                    glib::MainContext::default()
+                        .spawn_local(async move { imp.on_open_clicked().await });
+                }
+            ));
             self.open.add_controller(open_click);
         }
 
@@ -149,27 +152,49 @@ mod imp {
             let drag_source = gtk::DragSource::builder()
                 .actions(gdk::DragAction::MOVE)
                 .build();
-            drag_source.connect_prepare(
-                glib::clone!(@weak self as imp => @default-return None, move |_source, _x, _y| imp.drag_prepare()),
-            );
-            drag_source.connect_drag_begin(glib::clone!(@weak self as imp => move |source, _drag| source.set_icon(imp.drag_begin().as_ref(), 0, 0)));
+            drag_source.connect_prepare(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                #[upgrade_or]
+                None,
+                move |_source, _x, _y| imp.drag_prepare()
+            ));
+            drag_source.connect_drag_begin(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |source, _drag| source.set_icon(imp.drag_begin().as_ref(), 0, 0)
+            ));
             self.obj().add_controller(drag_source);
 
             let drop_target =
                 gtk::DropTarget::new(self.record_type().get_type(), gdk::DragAction::MOVE);
             drop_target.set_preload(true);
-            drop_target.connect_enter(
-                glib::clone!(@weak self as imp => @default-return gdk::DragAction::empty(), move |target, x, y| imp.drop_motion(target, x, y)),
-            );
-            drop_target.connect_motion(
-                glib::clone!(@weak self as imp => @default-return gdk::DragAction::empty(), move |target, x, y| imp.drop_motion(target, x, y)),
-            );
-            drop_target.connect_leave(
-                glib::clone!(@weak self as imp => move |_target| imp.set_drop_style(None)),
-            );
-            drop_target.connect_drop(
-                glib::clone!(@weak self as imp => @default-return false, move |_target, value, x, y| imp.drop(value, x, y)),
-            );
+            drop_target.connect_enter(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                #[upgrade_or]
+                gdk::DragAction::empty(),
+                move |target, x, y| imp.drop_motion(target, x, y)
+            ));
+            drop_target.connect_motion(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                #[upgrade_or]
+                gdk::DragAction::empty(),
+                move |target, x, y| imp.drop_motion(target, x, y)
+            ));
+            drop_target.connect_leave(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_target| imp.set_drop_style(None)
+            ));
+            drop_target.connect_drop(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                #[upgrade_or]
+                false,
+                move |_target, value, x, y| imp.drop(value, x, y)
+            ));
             self.obj().add_controller(drop_target);
         }
 
diff --git a/src/ui/record_view/view.rs b/src/ui/record_view/view.rs
index fe992232..6890a55c 100644
--- a/src/ui/record_view/view.rs
+++ b/src/ui/record_view/view.rs
@@ -52,40 +52,52 @@ mod imp {
             obj.set_layout_manager(Some(gtk::BinLayout::new()));
 
             let factory = gtk::SignalListItemFactory::new();
-            factory.connect_setup(
-                glib::clone!(@weak self as this => move |_factory, item| this.setup_item(item)),
-            );
-            factory.connect_bind(
-                glib::clone!(@weak self as this => move |_factory, item| this.bind_item(item)),
-            );
-            factory.connect_unbind(
-                glib::clone!(@weak self as this => move |_factory, item| this.unbind_item(item)),
-            );
-            factory.connect_teardown(
-                glib::clone!(@weak self as this => move |_factory, item| this.teardown_item(item)),
-            );
+            factory.connect_setup(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |_factory, item| this.setup_item(item)
+            ));
+            factory.connect_bind(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |_factory, item| this.bind_item(item)
+            ));
+            factory.connect_unbind(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |_factory, item| this.unbind_item(item)
+            ));
+            factory.connect_teardown(glib::clone!(
+                #[weak(rename_to = this)]
+                self,
+                move |_factory, item| this.teardown_item(item)
+            ));
             self.list_view.set_factory(Some(&factory));
             self.list_view.set_model(Some(&self.selection));
 
-            self.list_view.connect_activate(
-                glib::clone!(@weak obj => move |_list_view, position| {
+            self.list_view.connect_activate(glib::clone!(
+                #[weak]
+                obj,
+                move |_list_view, position| {
                     obj.emit_record_activated(position);
-                }),
-            );
+                }
+            ));
 
             let key_controller = gtk::EventControllerKey::new();
-            key_controller.connect_key_pressed(
-                glib::clone!(@weak obj => @default-return glib::Propagation::Proceed, move |_controller, key, _keycode, modifier| {
-                    obj.on_key_press(key, modifier)
-                }),
-            );
+            key_controller.connect_key_pressed(glib::clone!(
+                #[weak]
+                obj,
+                #[upgrade_or]
+                glib::Propagation::Proceed,
+                move |_controller, key, _keycode, modifier| obj.on_key_press(key, modifier)
+            ));
             self.list_view.add_controller(key_controller);
 
-            self.selection.connect_selection_changed(
-                glib::clone!(@weak obj => move |selection, _pos, _n| {
-                    obj.emit_selection_changed(&selection.selection())
-                }),
-            );
+            self.selection.connect_selection_changed(glib::clone!(
+                #[weak]
+                obj,
+                move |selection, _pos, _n| obj.emit_selection_changed(&selection.selection())
+            ));
 
             scrolled(&self.list_view).set_parent(&*obj);
         }
@@ -137,7 +149,11 @@ mod imp {
             let popup_model = self.popup_model.clone();
             child.connect_context_menu(move |_record| popup_model.borrow().clone());
             let obj = self.obj();
-            child.connect_move_record(glib::clone!(@weak obj => move |_, src, dst, opt| obj.emit_move_record(src, dst, opt)));
+            child.connect_move_record(glib::clone!(
+                #[weak]
+                obj,
+                move |_, src, dst, opt| obj.emit_move_record(src, dst, opt)
+            ));
             list_item.set_child(Some(&child));
         }
 
diff --git a/src/ui/search_bar.rs b/src/ui/search_bar.rs
index 61d4f268..de135aa3 100644
--- a/src/ui/search_bar.rs
+++ b/src/ui/search_bar.rs
@@ -60,14 +60,18 @@ mod imp {
             self.entry.set_width_request(300);
 
             let next = create_button("go-down-symbolic");
-            next.connect_clicked(
-                glib::clone!(@weak self as this => move |_| this.entry.emit_next_match()),
-            );
+            next.connect_clicked(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_| imp.entry.emit_next_match()
+            ));
 
             let prev = create_button("go-up-symbolic");
-            prev.connect_clicked(
-                glib::clone!(@weak self as this => move |_| this.entry.emit_previous_match()),
-            );
+            prev.connect_clicked(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |_| imp.entry.emit_previous_match()
+            ));
 
             self.search_in_secrets
                 .set_label(Some("Search in secrets (passwords)"));
@@ -96,21 +100,48 @@ mod imp {
 
             self.bar.set_child(Some(&bx));
 
-            self.entry.connect_search_changed(glib::clone!(@weak self as this => move |entry| {
-                this.obj().emit_search(SearchEventType::Change, entry.text(), this.search_in_secrets.is_active());
-            }));
-            self.entry
-                .connect_next_match(glib::clone!(@weak self as this => move |entry| {
-                    this.obj().emit_search(SearchEventType::Next, entry.text(), this.search_in_secrets.is_active());
-                }));
-            self.entry
-                .connect_previous_match(glib::clone!(@weak self as this => move |entry| {
-                    this.obj().emit_search(SearchEventType::Prev, entry.text(), this.search_in_secrets.is_active());
-                }));
-            self.search_in_secrets
-                .connect_toggled(glib::clone!(@weak self as this => move |b| {
-                    this.obj().emit_configure(SearchConfig { search_in_secrets:  b.is_active() });
-                }));
+            self.entry.connect_search_changed(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |entry| {
+                    imp.obj().emit_search(
+                        SearchEventType::Change,
+                        entry.text(),
+                        imp.search_in_secrets.is_active(),
+                    );
+                }
+            ));
+            self.entry.connect_next_match(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |entry| {
+                    imp.obj().emit_search(
+                        SearchEventType::Next,
+                        entry.text(),
+                        imp.search_in_secrets.is_active(),
+                    );
+                }
+            ));
+            self.entry.connect_previous_match(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |entry| {
+                    imp.obj().emit_search(
+                        SearchEventType::Prev,
+                        entry.text(),
+                        imp.search_in_secrets.is_active(),
+                    );
+                }
+            ));
+            self.search_in_secrets.connect_toggled(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |b| {
+                    imp.obj().emit_configure(SearchConfig {
+                        search_in_secrets: b.is_active(),
+                    });
+                }
+            ));
         }
 
         fn signals() -> &'static [glib::subclass::Signal] {
diff --git a/src/ui/search_pane.rs b/src/ui/search_pane.rs
index f600674e..1d726438 100644
--- a/src/ui/search_pane.rs
+++ b/src/ui/search_pane.rs
@@ -85,21 +85,29 @@ mod imp {
             grid.attach(&action_bar, 0, 1, 1, 1);
             grid.set_parent(&*obj);
 
-            self.view.connect_selection_changed(
-                glib::clone!(@weak obj => move |selected_records| {
+            self.view.connect_selection_changed(glib::clone!(
+                #[weak]
+                obj,
+                move |selected_records| {
                     obj.selection_changed(selected_records);
-                }),
-            );
+                }
+            ));
 
-            self.view
-                .connect_record_activated(glib::clone!(@weak self as imp => move |position| {
+            self.view.connect_record_activated(glib::clone!(
+                #[weak(rename_to = imp)]
+                self,
+                move |position| {
                     glib::MainContext::default().spawn_local(async move {
                         imp.row_activated(position).await;
                     });
-                }));
+                }
+            ));
 
-            self.view
-                .connect_go_home(glib::clone!(@weak obj => move || obj.emit_go_home()));
+            self.view.connect_go_home(glib::clone!(
+                #[weak]
+                obj,
+                move || obj.emit_go_home()
+            ));
 
             let shortcuts = gtk::ShortcutController::new();
             shortcuts.add_shortcut(
diff --git a/src/ui/toast.rs b/src/ui/toast.rs
index e74cc4d5..e8c2478c 100644
--- a/src/ui/toast.rs
+++ b/src/ui/toast.rs
@@ -43,25 +43,43 @@ impl Default for Toast {
             close_at: Rc::new(Cell::new(Instant::now())),
         };
 
-        event_controller.connect_enter(glib::clone!(@weak toast => move |_, _, _| {
-            toast.close_at.set(far_future());
-        }));
-
-        event_controller.connect_leave(glib::clone!(@weak toast => move |_| {
-            toast.close_at.set(future());
-        }));
-
-        close_button.connect_clicked(glib::clone!(@weak toast => move |_| {
-            toast.close_at.set(Instant::now());
-            toast.revealer.set_reveal_child(false);
-        }));
+        event_controller.connect_enter(glib::clone!(
+            #[weak]
+            toast,
+            move |_, _, _| {
+                toast.close_at.set(far_future());
+            }
+        ));
+
+        event_controller.connect_leave(glib::clone!(
+            #[weak]
+            toast,
+            move |_| {
+                toast.close_at.set(future());
+            }
+        ));
+
+        close_button.connect_clicked(glib::clone!(
+            #[weak]
+            toast,
+            move |_| {
+                toast.close_at.set(Instant::now());
+                toast.revealer.set_reveal_child(false);
+            }
+        ));
 
         glib::timeout_add_local(
             Duration::from_millis(100),
-            glib::clone!(@weak toast => @default-return glib::ControlFlow::Break, move || {
-                toast.tick();
-                glib::ControlFlow::Continue
-            }),
+            glib::clone!(
+                #[weak]
+                toast,
+                #[upgrade_or]
+                glib::ControlFlow::Break,
+                move || {
+                    toast.tick();
+                    glib::ControlFlow::Continue
+                }
+            ),
         );
 
         toast