[gnome-tour/wip/cdavis/gtk4] Port to GTK4 + libadwaita + gtk4-rs




commit 02ec0e34628f24d3349b894e877135fed4da6c9f
Author: Christopher Davis <christopherdavis gnome org>
Date:   Sun Sep 5 21:48:34 2021 -0700

    Port to GTK4 + libadwaita + gtk4-rs
    
    This commit upgrades our rust dependencies and ports
    Tour to libadwaita+GTK4. As part of porting we now use
    GtkPicture instead of GtkImage, and AdwClamps to hold pages
    in place.
    
    This port is part of https://gitlab.gnome.org/GNOME/Initiatives/-/issues/26 and handles 
https://gitlab.gnome.org/GNOME/Initiatives/-/issues/32
    
    Fixes https://gitlab.gnome.org/GNOME/gnome-tour/-/issues/36

 Cargo.lock                   | 548 ++++++++++++++++++++++++-------------------
 Cargo.toml                   |  11 +-
 data/resources/style.css     |   2 -
 meson.build                  |   4 +-
 src/application.rs           |  18 +-
 src/main.rs                  |   1 +
 src/static_resources.rs.in   |   4 +-
 src/utils.rs                 |   3 +-
 src/widgets/pages/image.rs   |  31 +--
 src/widgets/pages/welcome.rs |  46 ++--
 src/widgets/paginator.rs     |  94 ++++----
 src/widgets/window.rs        |  18 +-
 12 files changed, 415 insertions(+), 365 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 4c9fb89..6b901f0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,7 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+version = 3
+
 [[package]]
 name = "aho-corasick"
 version = "0.7.15"
@@ -15,32 +17,6 @@ version = "1.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
 
-[[package]]
-name = "atk"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "812b4911e210bd51b24596244523c856ca749e6223c50a7fbbba3f89ee37c426"
-dependencies = [
- "atk-sys",
- "bitflags",
- "glib",
- "glib-sys",
- "gobject-sys",
- "libc",
-]
-
-[[package]]
-name = "atk-sys"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f530e4af131d94cc4fa15c5c9d0348f0ef28bac64ba660b6b2a1cf2605dedfce"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -72,28 +48,26 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
 
 [[package]]
 name = "cairo-rs"
-version = "0.9.1"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c5c0f2e047e8ca53d0ff249c54ae047931d7a6ebe05d00af73e0ffeb6e34bdb8"
+checksum = "f859ade407c19810ae920b4fafab92189ed312adad490d08fb16b5f49f1e2207"
 dependencies = [
  "bitflags",
  "cairo-sys-rs",
  "glib",
- "glib-sys",
- "gobject-sys",
  "libc",
  "thiserror",
 ]
 
 [[package]]
 name = "cairo-sys-rs"
-version = "0.10.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2ed2639b9ad5f1d6efa76de95558e11339e7318426d84ac4890b86c03e828ca7"
+checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
 dependencies = [
  "glib-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
@@ -102,6 +76,24 @@ version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
 
+[[package]]
+name = "cfg-expr"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571"
+dependencies = [
+ "smallvec",
+]
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -128,18 +120,13 @@ dependencies = [
 ]
 
 [[package]]
-name = "futures"
-version = "0.3.12"
+name = "field-offset"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
+checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92"
 dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
+ "memoffset",
+ "rustc_version",
 ]
 
 [[package]]
@@ -149,7 +136,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
 dependencies = [
  "futures-core",
- "futures-sink",
 ]
 
 [[package]]
@@ -175,24 +161,6 @@ version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
 
-[[package]]
-name = "futures-macro"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
-dependencies = [
- "proc-macro-hack",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
-
 [[package]]
 name = "futures-task"
 version = "0.3.12"
@@ -208,83 +176,69 @@ version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
 dependencies = [
- "futures-channel",
  "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
  "futures-task",
- "memchr",
  "pin-project-lite",
  "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
  "slab",
 ]
 
 [[package]]
-name = "gdk"
-version = "0.13.2"
+name = "gdk-pixbuf"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "db00839b2a68a7a10af3fa28dfb3febaba3a20c3a9ac2425a33b7df1f84a6b7d"
+checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f"
 dependencies = [
- "bitflags",
- "cairo-rs",
- "cairo-sys-rs",
- "gdk-pixbuf",
- "gdk-sys",
+ "gdk-pixbuf-sys",
  "gio",
- "gio-sys",
  "glib",
- "glib-sys",
- "gobject-sys",
  "libc",
- "pango",
 ]
 
 [[package]]
-name = "gdk-pixbuf"
-version = "0.9.0"
+name = "gdk-pixbuf-sys"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "8f6dae3cb99dd49b758b88f0132f8d401108e63ae8edd45f432d42cdff99998a"
+checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590"
 dependencies = [
- "gdk-pixbuf-sys",
- "gio",
  "gio-sys",
- "glib",
  "glib-sys",
  "gobject-sys",
  "libc",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
-name = "gdk-pixbuf-sys"
-version = "0.10.0"
+name = "gdk4"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3bfe468a7f43e97b8d193a762b6c5cf67a7d36cacbc0b9291dbcae24bfea1e8f"
+checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81"
 dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
+ "bitflags",
+ "cairo-rs",
+ "gdk-pixbuf",
+ "gdk4-sys",
+ "gio",
+ "glib",
  "libc",
- "system-deps",
+ "pango",
 ]
 
 [[package]]
-name = "gdk-sys"
-version = "0.10.0"
+name = "gdk4-sys"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0a9653cfc500fd268015b1ac055ddbc3df7a5c9ea3f4ccef147b3957bd140d69"
+checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18"
 dependencies = [
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
  "gio-sys",
  "glib-sys",
  "gobject-sys",
+ "graphene-sys",
  "libc",
  "pango-sys",
- "pkg-config",
- "system-deps",
+ "system-deps 4.0.0",
 ]
 
 [[package]]
@@ -320,20 +274,16 @@ dependencies = [
 
 [[package]]
 name = "gio"
-version = "0.9.1"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1fb60242bfff700772dae5d9e3a1f7aa2e4ebccf18b89662a16acb2822568561"
+checksum = "81a4c12fcba7a6402ae843a0085ec16d3658a87901763b6a7f0a7c5d60e555a5"
 dependencies = [
  "bitflags",
- "futures",
  "futures-channel",
  "futures-core",
  "futures-io",
- "futures-util",
  "gio-sys",
  "glib",
- "glib-sys",
- "gobject-sys",
  "libc",
  "once_cell",
  "thiserror",
@@ -341,45 +291,44 @@ dependencies = [
 
 [[package]]
 name = "gio-sys"
-version = "0.10.1"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac"
+checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
  "winapi",
 ]
 
 [[package]]
 name = "glib"
-version = "0.10.3"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0c685013b7515e668f1b57a165b009d4d28cb139a8a989bbd699c10dad29d0c5"
+checksum = "d4a930b7208e6e0ab839eea5f65ac2b82109f729621430d47fe905e2e09d33f4"
 dependencies = [
  "bitflags",
  "futures-channel",
  "futures-core",
  "futures-executor",
  "futures-task",
- "futures-util",
  "glib-macros",
  "glib-sys",
  "gobject-sys",
  "libc",
  "once_cell",
+ "smallvec",
 ]
 
 [[package]]
 name = "glib-macros"
-version = "0.10.1"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
+checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518"
 dependencies = [
  "anyhow",
  "heck",
- "itertools",
  "proc-macro-crate",
  "proc-macro-error",
  "proc-macro2",
@@ -389,46 +338,98 @@ dependencies = [
 
 [[package]]
 name = "glib-sys"
-version = "0.10.1"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1"
+checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
 dependencies = [
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
 name = "gnome-tour"
 version = "40.0.0"
 dependencies = [
- "gdk",
  "gettext-rs",
- "gio",
- "glib",
  "gstreamer",
  "gstreamer-player",
- "gtk",
- "libhandy",
+ "gtk4",
+ "libadwaita",
  "log",
  "pretty_env_logger",
 ]
 
 [[package]]
 name = "gobject-sys"
-version = "0.10.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c"
+checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
 dependencies = [
  "glib-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
+]
+
+[[package]]
+name = "graphene-rs"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f1460a39f06e491e6112f27e71e51435c833ba370723224dd1743dfd1f201f19"
+dependencies = [
+ "glib",
+ "graphene-sys",
+ "libc",
+]
+
+[[package]]
+name = "graphene-sys"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e7d23fb7a9547e5f072a7e0cd49cd648fedeb786d122b106217511980cbb8962"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "pkg-config",
+ "system-deps 3.2.0",
+]
+
+[[package]]
+name = "gsk4"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0"
+dependencies = [
+ "bitflags",
+ "cairo-rs",
+ "gdk4",
+ "glib",
+ "graphene-rs",
+ "gsk4-sys",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gsk4-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk4-sys",
+ "glib-sys",
+ "gobject-sys",
+ "graphene-sys",
+ "libc",
+ "pango-sys",
+ "system-deps 4.0.0",
 ]
 
 [[package]]
 name = "gstreamer"
-version = "0.16.7"
+version = "0.17.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9ff5d0f7ff308ae37e6eb47b6ded17785bdea06e438a708cd09e0288c1862f33"
+checksum = "810e68483c27518ec8491d71ee163f9fc03dcc4ebacee98caa348e8a064898ef"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -436,11 +437,10 @@ dependencies = [
  "futures-core",
  "futures-util",
  "glib",
- "glib-sys",
- "gobject-sys",
  "gstreamer-sys",
  "libc",
  "muldiv",
+ "num-integer",
  "num-rational",
  "once_cell",
  "paste",
@@ -450,92 +450,84 @@ dependencies = [
 
 [[package]]
 name = "gstreamer-base"
-version = "0.16.5"
+version = "0.17.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bafd01c56f59cb10f4b5a10f97bb4bdf8c2b2784ae5b04da7e2d400cf6e6afcf"
+checksum = "2c0c1d8c62eb5d08fb80173609f2eea71d385393363146e4e78107facbd67715"
 dependencies = [
  "bitflags",
+ "cfg-if",
  "glib",
- "glib-sys",
- "gobject-sys",
  "gstreamer",
  "gstreamer-base-sys",
- "gstreamer-sys",
  "libc",
 ]
 
 [[package]]
 name = "gstreamer-base-sys"
-version = "0.9.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a4b7b6dc2d6e160a1ae28612f602bd500b3fa474ce90bf6bb2f08072682beef5"
+checksum = "28169a7b58edb93ad8ac766f0fa12dcd36a2af4257a97ee10194c7103baf3e27"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "gstreamer-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
 name = "gstreamer-player"
-version = "0.16.5"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "34edf65e48e0d29c18101d77a2e004488a61f81a852a75e19d9c73e03d35cb77"
+checksum = "c503dba6f79b5cd8a4be5329119892c196db013ce66fce16079a7df8ce819a3a"
 dependencies = [
  "bitflags",
  "glib",
- "glib-sys",
- "gobject-sys",
  "gstreamer",
  "gstreamer-player-sys",
- "gstreamer-sys",
  "gstreamer-video",
  "libc",
+ "once_cell",
 ]
 
 [[package]]
 name = "gstreamer-player-sys"
-version = "0.9.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "53aaf79503e691a32266670bc631edb6c52bdb854984da76a0ce2756f49584a2"
+checksum = "3e50bed2a120574750ea1370163df21b50762d0b4967f569fdc58232f4c930d5"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "gstreamer-sys",
  "gstreamer-video-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
 name = "gstreamer-sys"
-version = "0.9.1"
+version = "0.17.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "fc1f154082d01af5718c5f8a8eb4f565a4ea5586ad8833a8fc2c2aa6844b601d"
+checksum = "a81704feeb3e8599913bdd1e738455c2991a01ff4a1780cb62200993e454cc3e"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
 name = "gstreamer-video"
-version = "0.16.7"
+version = "0.17.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f7bbb1485d87469849ec45c08e03c2f280d3ea20ff3c439d03185be54e3ce98e"
+checksum = "e3447ee95c8e79daec0b163260cf6a3de9bc19ff47a01b533787f900074a3476"
 dependencies = [
  "bitflags",
+ "cfg-if",
  "futures-channel",
- "futures-util",
  "glib",
- "glib-sys",
- "gobject-sys",
  "gstreamer",
  "gstreamer-base",
- "gstreamer-base-sys",
- "gstreamer-sys",
  "gstreamer-video-sys",
  "libc",
  "once_cell",
@@ -543,62 +535,74 @@ dependencies = [
 
 [[package]]
 name = "gstreamer-video-sys"
-version = "0.9.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "92347e46438007d6a2386302125f62cb9df6769cdacb931af5c0f12c1ee21de4"
+checksum = "b81608f4182bdddd5bd33aaaa341d5544eda12b067a3dab75b1b7d2de01a3ba7"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "gstreamer-base-sys",
  "gstreamer-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
-name = "gtk"
-version = "0.9.2"
+name = "gtk4"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2f022f2054072b3af07666341984562c8e626a79daa8be27b955d12d06a5ad6a"
+checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776"
 dependencies = [
- "atk",
  "bitflags",
  "cairo-rs",
- "cairo-sys-rs",
- "cc",
- "gdk",
+ "field-offset",
+ "futures-channel",
  "gdk-pixbuf",
- "gdk-pixbuf-sys",
- "gdk-sys",
+ "gdk4",
  "gio",
- "gio-sys",
  "glib",
- "glib-sys",
- "gobject-sys",
- "gtk-sys",
+ "graphene-rs",
+ "gsk4",
+ "gtk4-macros",
+ "gtk4-sys",
  "libc",
  "once_cell",
  "pango",
- "pango-sys",
- "pkg-config",
 ]
 
 [[package]]
-name = "gtk-sys"
-version = "0.10.0"
+name = "gtk4-macros"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "89acda6f084863307d948ba64a4b1ef674e8527dddab147ee4cdcc194c880457"
+checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e"
+dependencies = [
+ "anyhow",
+ "heck",
+ "itertools",
+ "proc-macro-crate",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "gtk4-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c"
 dependencies = [
- "atk-sys",
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
- "gdk-sys",
+ "gdk4-sys",
  "gio-sys",
  "glib-sys",
  "gobject-sys",
+ "graphene-sys",
+ "gsk4-sys",
  "libc",
  "pango-sys",
- "system-deps",
+ "system-deps 4.0.0",
 ]
 
 [[package]]
@@ -630,9 +634,9 @@ dependencies = [
 
 [[package]]
 name = "itertools"
-version = "0.9.0"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
+checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
 dependencies = [
  "either",
 ]
@@ -644,55 +648,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
-name = "libc"
-version = "0.2.86"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
-
-[[package]]
-name = "libhandy"
-version = "0.7.1"
+name = "libadwaita"
+version = "0.1.0-alpha-6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d776bf5b92993b8006688652cda2683261317dcc82bb4d91d3996bda2f7019e0"
+checksum = "d8d01ba5036df1c3e09be88b4b8e0906af977bb7ec28d5faec81a1de94bc775c"
 dependencies = [
- "bitflags",
- "gdk",
  "gdk-pixbuf",
- "gdk-pixbuf-sys",
- "gdk-sys",
+ "gdk4",
  "gio",
- "gio-sys",
  "glib",
- "glib-sys",
- "gobject-sys",
- "gtk",
- "gtk-sys",
- "lazy_static",
+ "gtk4",
+ "libadwaita-sys",
  "libc",
- "libhandy-sys",
+ "once_cell",
  "pango",
 ]
 
 [[package]]
-name = "libhandy-sys"
-version = "0.7.0"
+name = "libadwaita-sys"
+version = "0.1.0-alpha-6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0017044b92ade6704a301212feea9e754be62f58d39d01aae8fcf2c1a982e3d9"
+checksum = "3127d83c55f64c466925b9d1e27a964187f193e94c7c8820ad6b29d6e5f487d8"
 dependencies = [
- "gdk",
  "gdk-pixbuf-sys",
- "gdk-sys",
- "gio",
+ "gdk4-sys",
  "gio-sys",
  "glib-sys",
  "gobject-sys",
- "gtk-sys",
+ "gtk4-sys",
  "libc",
  "pango-sys",
- "pkg-config",
- "system-deps",
+ "system-deps 4.0.0",
 ]
 
+[[package]]
+name = "libc"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
+
 [[package]]
 name = "locale_config"
 version = "0.3.0"
@@ -730,11 +724,20 @@ version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
+[[package]]
+name = "memoffset"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "muldiv"
-version = "0.2.1"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
+checksum = "b5136edda114182728ccdedb9f5eda882781f35fa6e80cc360af12a8932507f3"
 
 [[package]]
 name = "num-integer"
@@ -748,9 +751,9 @@ dependencies = [
 
 [[package]]
 name = "num-rational"
-version = "0.3.2"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
+checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
 dependencies = [
  "autocfg",
  "num-integer",
@@ -803,14 +806,12 @@ checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
 
 [[package]]
 name = "pango"
-version = "0.9.1"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9937068580bebd8ced19975938573803273ccbcbd598c58d4906efd4ac87c438"
+checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96"
 dependencies = [
  "bitflags",
  "glib",
- "glib-sys",
- "gobject-sys",
  "libc",
  "once_cell",
  "pango-sys",
@@ -818,14 +819,14 @@ dependencies = [
 
 [[package]]
 name = "pango-sys"
-version = "0.10.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "24d2650c8b62d116c020abd0cea26a4ed96526afda89b1c4ea567131fdefc890"
+checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
 dependencies = [
  "glib-sys",
  "gobject-sys",
  "libc",
- "system-deps",
+ "system-deps 3.2.0",
 ]
 
 [[package]]
@@ -834,6 +835,15 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "c5d65c4d95931acda4498f675e332fcbdc9a06705cd07086c510e9b6009cd1c1"
 
+[[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
 [[package]]
 name = "pin-project-lite"
 version = "0.2.4"
@@ -876,10 +886,11 @@ dependencies = [
 
 [[package]]
 name = "proc-macro-crate"
-version = "0.1.5"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
+checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92"
 dependencies = [
+ "thiserror",
  "toml",
 ]
 
@@ -907,18 +918,6 @@ dependencies = [
  "version_check",
 ]
 
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.19"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
-
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
-
 [[package]]
 name = "proc-macro2"
 version = "1.0.24"
@@ -1019,6 +1018,33 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "rustc_version"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "semver"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
 [[package]]
 name = "serde"
 version = "1.0.123"
@@ -1031,17 +1057,23 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
+[[package]]
+name = "smallvec"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
+
 [[package]]
 name = "strum"
-version = "0.18.0"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
+checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
 
 [[package]]
 name = "strum_macros"
-version = "0.18.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
+checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -1062,11 +1094,14 @@ dependencies = [
 
 [[package]]
 name = "system-deps"
-version = "1.3.2"
+version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
+checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
 dependencies = [
+ "anyhow",
+ "cfg-expr 0.8.1",
  "heck",
+ "itertools",
  "pkg-config",
  "strum",
  "strum_macros",
@@ -1075,6 +1110,19 @@ dependencies = [
  "version-compare",
 ]
 
+[[package]]
+name = "system-deps"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04"
+dependencies = [
+ "cfg-expr 0.9.0",
+ "heck",
+ "pkg-config",
+ "toml",
+ "version-compare",
+]
+
 [[package]]
 name = "tempfile"
 version = "3.2.0"
@@ -1100,18 +1148,18 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.23"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
+checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.23"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
+checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1136,6 +1184,12 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
 [[package]]
 name = "unicode-segmentation"
 version = "1.7.1"
@@ -1150,9 +1204,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
 
 [[package]]
 name = "version-compare"
-version = "0.0.10"
+version = "0.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
+checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b"
 
 [[package]]
 name = "version_check"
diff --git a/Cargo.toml b/Cargo.toml
index 8b3ecb8..e054143 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,22 +8,19 @@ edition = "2018"
 video = ["gst_player", "gst"]
 
 [dependencies]
-glib = { version = "0.10", features = ["v2_64"] }
-gdk = "0.13"
-gtk = { version = "0.9", features= ["v3_16"] }
-gio = "0.9"
+gtk = { package = "gtk4", version = "0.3", features= ["v4_2"]}
 log = "0.4"
 gettext-rs = { version = "0.6", features = ["gettext-system"] }
-libhandy = "0.7"
+libadwaita = "0.1.0-alpha-6"
 pretty_env_logger = "0.4"
 
 [dependencies.gst_player]
-version = "0.16"
+version = "0.17"
 package = "gstreamer-player"
 optional = true
 
 [dependencies.gst]
-version = "0.16"
+version = "0.17"
 package = "gstreamer"
 optional = true
 
diff --git a/data/resources/style.css b/data/resources/style.css
index 87a7ad6..7fe8843 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -42,8 +42,6 @@ window .titlebar button {
     to { background-position: 60% 30%, center 30%, center; }
 }
 
-.page { color: #000; }
-
   /* .page:nth-child(2) { background: linear-gradient(to right, #3584e4, #1a5fb4); }  overview */
   .page:nth-child(3) {  }  /* customize */
   /* .page:nth-child(4) { background: linear-gradient(to right, #e66100, #c64600); }  workspaces */
diff --git a/meson.build b/meson.build
index 6fcfb70..9f668ab 100644
--- a/meson.build
+++ b/meson.build
@@ -11,8 +11,8 @@ base_id = 'org.gnome.Tour'
 dependency('glib-2.0', version: '>= 2.64')
 dependency('gio-2.0', version: '>= 2.56')
 dependency('gdk-pixbuf-2.0')
-dependency('gtk+-3.0', version: '>= 3.16')
-dependency('libhandy-1', version: '>= 1')
+dependency('gtk4', version: '>= 4.4')
+dependency('libadwaita-1', version: '>= 1')
 
 if get_option('video_path') != ''
   dependency('gstreamer-1.0', version: '>= 1.12')
diff --git a/src/application.rs b/src/application.rs
index d09df27..174b00f 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -1,11 +1,11 @@
 use crate::config;
 use crate::utils;
 use crate::widgets::Window;
-use gio::prelude::*;
-use glib::clone;
+use gtk::gdk;
+use gtk::gio::{self, prelude::*};
+use gtk::glib::{self, clone};
 use gtk::prelude::*;
 use log::info;
-use std::env;
 use std::{cell::RefCell, rc::Rc};
 
 pub struct Application {
@@ -15,8 +15,7 @@ pub struct Application {
 
 impl Application {
     pub fn new() -> Rc<Self> {
-        let app =
-            gtk::Application::new(Some(config::APP_ID), gio::ApplicationFlags::FLAGS_NONE).unwrap();
+        let app = gtk::Application::new(Some(config::APP_ID), gio::ApplicationFlags::FLAGS_NONE);
 
         let application = Rc::new(Self {
             app,
@@ -86,7 +85,7 @@ impl Application {
 
     fn setup_signals(&self, app: Rc<Self>) {
         self.app.connect_startup(clone!(@weak app => move |_| {
-            libhandy::init();
+            libadwaita::init();
             app.setup_css();
             app.setup_gactions(app.clone());
         }));
@@ -103,8 +102,8 @@ impl Application {
     fn setup_css(&self) {
         let p = gtk::CssProvider::new();
         gtk::CssProvider::load_from_resource(&p, "/org/gnome/Tour/style.css");
-        if let Some(screen) = gdk::Screen::get_default() {
-            gtk::StyleContext::add_provider_for_screen(&screen, &p, 500);
+        if let Some(display) = gdk::Display::default() {
+            gtk::StyleContext::add_provider_for_display(&display, &p, 500);
         }
     }
 
@@ -113,7 +112,6 @@ impl Application {
         info!("Version: {} ({})", config::VERSION, config::PROFILE);
         info!("Datadir: {}", config::PKGDATADIR);
 
-        let args: Vec<String> = env::args().collect();
-        self.app.run(&args);
+        self.app.run();
     }
 }
diff --git a/src/main.rs b/src/main.rs
index e236bf1..605bd7e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
 use gettextrs::*;
+use gtk::glib;
 
 mod application;
 mod config;
diff --git a/src/static_resources.rs.in b/src/static_resources.rs.in
index 6fb8d29..2a3ba06 100644
--- a/src/static_resources.rs.in
+++ b/src/static_resources.rs.in
@@ -1,7 +1,7 @@
 // Source: https://gitlab.gnome.org/World/podcasts/blob/master/podcasts-gtk/src/static_resource.rs
 
-use gio::{resources_register, Resource};
-use glib::{Bytes, Error};
+use gtk::gio::{resources_register, Resource};
+use gtk::glib::{Bytes, Error};
 
 pub(crate) fn init() -> Result<(), Error> {
     // load the gresource binary at build time and include/link it into the final
diff --git a/src/utils.rs b/src/utils.rs
index c3eb8fe..5b4fa37 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,9 +1,10 @@
 // based on https://gitlab.gnome.org/World/podcasts/-/blob/master/podcasts-gtk/src/i18n|utils.rs
 use gettextrs::gettext;
+use gtk::{gio, glib};
 
 pub fn action<T, F>(thing: &T, name: &str, action: F)
 where
-    T: gio::ActionMapExt,
+    T: gio::traits::ActionMapExt,
     for<'r, 's> F: Fn(&'r gio::SimpleAction, Option<&glib::Variant>) + 'static,
 {
     // Create a stateless, parameterless action
diff --git a/src/widgets/pages/image.rs b/src/widgets/pages/image.rs
index d53ee5c..81ec185 100644
--- a/src/widgets/pages/image.rs
+++ b/src/widgets/pages/image.rs
@@ -15,8 +15,9 @@ impl ImagePageWidget {
     }
 
     fn init(&self, resource_uri: &str, head: String, body: String) {
-        self.widget.set_property_expand(true);
-        self.widget.get_style_context().add_class("page");
+        self.widget.set_hexpand(true);
+        self.widget.set_vexpand(true);
+        self.widget.add_css_class("page");
         self.widget.set_halign(gtk::Align::Fill);
         self.widget.set_valign(gtk::Align::Fill);
 
@@ -31,11 +32,15 @@ impl ImagePageWidget {
             .margin_start(12)
             .margin_end(12)
             .build();
+        let clamp = libadwaita::Clamp::new();
+        clamp.set_child(Some(&container));
 
-        let image = gtk::Image::from_resource(&resource_uri);
-        image.set_valign(gtk::Align::Start);
-        image.show();
-        container.add(&image);
+        let picture = gtk::PictureBuilder::new()
+            .can_shrink(false)
+            .keep_aspect_ratio(true)
+            .build();
+        picture.set_resource(Some(resource_uri));
+        container.append(&picture);
 
         let head_label = gtk::LabelBuilder::new()
             .label(&head)
@@ -43,9 +48,8 @@ impl ImagePageWidget {
             .valign(gtk::Align::Center)
             .margin_top(36)
             .build();
-        head_label.get_style_context().add_class("page-title");
-        head_label.show();
-        container.add(&head_label);
+        head_label.add_css_class("page-title");
+        container.append(&head_label);
 
         let body_label = gtk::LabelBuilder::new()
             .label(&body)
@@ -55,12 +59,9 @@ impl ImagePageWidget {
             .valign(gtk::Align::Center)
             .margin_top(12)
             .build();
-        body_label.get_style_context().add_class("page-body");
-        body_label.show();
-        container.add(&body_label);
+        body_label.add_css_class("page-body");
+        container.append(&body_label);
 
-        container.show();
-        self.widget.add(&container);
-        self.widget.show();
+        self.widget.append(&clamp);
     }
 }
diff --git a/src/widgets/pages/welcome.rs b/src/widgets/pages/welcome.rs
index 682a4a6..1483ce7 100644
--- a/src/widgets/pages/welcome.rs
+++ b/src/widgets/pages/welcome.rs
@@ -4,10 +4,11 @@ use crate::utils::i18n_f;
 use gettextrs::gettext;
 #[cfg(feature = "video")]
 use gio::FileExt;
+use gtk::glib;
 #[cfg(feature = "video")]
-use glib::clone;
+use gtk::glib::clone;
 #[cfg(feature = "video")]
-use glib::{Receiver, Sender};
+use gtk::glib::{Receiver, Sender};
 use gtk::prelude::*;
 #[cfg(feature = "video")]
 use std::cell::RefCell;
@@ -67,19 +68,26 @@ impl WelcomePageWidget {
         let container = gtk::BoxBuilder::new()
             .orientation(gtk::Orientation::Vertical)
             .spacing(0)
-            .expand(true)
+            .hexpand(true)
+            .vexpand(true)
             .valign(gtk::Align::Center)
             .halign(gtk::Align::Center)
             .margin_top(24)
             .margin_bottom(24)
             .build();
-        self.widget.get_style_context().add_class("page");
-        self.widget.get_style_context().add_class("welcome-page");
+        self.widget.add_css_class("page");
+        self.widget.add_css_class("welcome-page");
+
+        let clamp = libadwaita::Clamp::new();
+        clamp.set_child(Some(&container));
 
         #[cfg(not(feature = "video"))]
         let header = {
-            let logo = gtk::Image::from_resource("/org/gnome/Tour/welcome.svg");
-            logo.show();
+            let logo = gtk::PictureBuilder::new()
+                .can_shrink(false)
+                .keep_aspect_ratio(true)
+                .build();
+            logo.set_resource(Some("/org/gnome/Tour/welcome.svg"));
 
             logo.upcast::<gtk::Widget>()
         };
@@ -103,11 +111,11 @@ impl WelcomePageWidget {
             video_widget.set_size_request(-1, 360);
             video_widget.set_property("ignore-alpha", &false).unwrap();
             video_widget.show();
-            video_widget.get_style_context().add_class("video");
+            video_widget.add_css_class("video");
             video_widget
         };
 
-        container.add(&header);
+        container.append(&header);
 
         #[cfg(feature = "video")]
         {
@@ -117,7 +125,7 @@ impl WelcomePageWidget {
                 clone!(@strong self.player as player => move |action| {
                     match action {
                         Action::VideoReady => player.play(),
-                        Action::VideoUp => header.get_style_context().add_class("playing"),
+                        Action::VideoUp => header.add_css_class("playing"),
                     };
                     glib::Continue(true)
                 }),
@@ -150,24 +158,20 @@ impl WelcomePageWidget {
 
         let title = gtk::Label::new(Some(&gettext("Start the Tour")));
         title.set_margin_top(36);
-        title.get_style_context().add_class("page-title");
-        title.show();
-        container.add(&title);
+        title.add_css_class("page-title");
+        container.append(&title);
 
-        let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into());
-        let version = glib::get_os_info("VERSION").unwrap_or_else(|| "".into());
+        let name = glib::os_info("NAME").unwrap_or_else(|| "GNOME".into());
+        let version = glib::os_info("VERSION").unwrap_or_else(|| "".into());
         // Translators: The following string is formated as "Learn about new and essential features in GNOME 
3.36" for example
         let text = gtk::Label::new(Some(&i18n_f(
             "Learn about the key features in {} {}.",
             &[&name, &version],
         )));
-        text.get_style_context().add_class("body");
+        text.add_css_class("body");
         text.set_margin_top(12);
-        text.show();
-        container.add(&text);
+        container.append(&text);
 
-        container.show();
-        self.widget.add(&container);
-        self.widget.show();
+        self.widget.append(&clamp);
     }
 }
diff --git a/src/widgets/paginator.rs b/src/widgets/paginator.rs
index d489c82..f3bdbc7 100644
--- a/src/widgets/paginator.rs
+++ b/src/widgets/paginator.rs
@@ -1,18 +1,17 @@
 use gettextrs::gettext;
-use glib::clone;
+use gtk::glib::{self, clone};
 use gtk::prelude::*;
 use std::cell::RefCell;
 use std::rc::Rc;
 
-use libhandy::prelude::{CarouselExt, CarouselIndicatorDotsExt, HeaderBarExt};
-
 pub struct PaginatorWidget {
     pub widget: gtk::Box,
-    carousel: libhandy::Carousel,
-    carousel_dots: libhandy::CarouselIndicatorDots,
-    headerbar: libhandy::HeaderBar,
+    carousel: libadwaita::Carousel,
+    carousel_dots: libadwaita::CarouselIndicatorDots,
+    headerbar: gtk::HeaderBar,
     pages: RefCell<Vec<gtk::Widget>>,
     current_page: RefCell<u32>,
+    next_overlay: gtk::Overlay,
     next_btn: gtk::Button,
     start_btn: gtk::Button,
     finish_btn: gtk::Button,
@@ -26,10 +25,13 @@ impl PaginatorWidget {
 
         let paginator = Rc::new(Self {
             widget,
-            carousel: libhandy::Carousel::new(),
-            carousel_dots: libhandy::CarouselIndicatorDots::new(),
-            headerbar: libhandy::HeaderBar::new(),
+            carousel: libadwaita::Carousel::new(),
+            carousel_dots: libadwaita::CarouselIndicatorDots::new(),
+            headerbar: gtk::HeaderBarBuilder::new()
+                .show_title_buttons(false)
+                .build(),
             start_btn: gtk::Button::with_label(&gettext("_Start")),
+            next_overlay: gtk::Overlay::new(),
             next_btn: gtk::Button::with_label(&gettext("_Next")),
             finish_btn: gtk::Button::with_label(&gettext("_Close")),
             close_btn: gtk::Button::with_label(&gettext("_Close")),
@@ -43,7 +45,7 @@ impl PaginatorWidget {
 
     pub fn try_next(&self) -> Option<()> {
         let p = *self.current_page.borrow() + 1;
-        if p == self.carousel.get_n_pages() {
+        if p == self.carousel.n_pages() {
             return None;
         }
         self.set_page(p);
@@ -68,20 +70,24 @@ impl PaginatorWidget {
     }
 
     fn update_position(&self) {
-        let position = self.carousel.get_position();
+        let position = self.carousel.position();
         let page_nr = position.round() as u32;
 
-        let n_pages = self.carousel.get_n_pages() as f64;
+        let n_pages = self.carousel.n_pages() as f64;
         let forelast_page = n_pages - 2.0;
         let last_page = n_pages - 1.0;
 
-        let (opacity_finish, opacity_previous, opacity_start, opacity_next) =
+        let (opacity_finish, opacity_previous, opacity_start, opacity_next, opacity_close) =
             if (0.0..1.0).contains(&position) {
-                (0.0, position, 1.0, position)
+                if position == 0.0 {
+                    (0.0, position, 1.0, position, 1.0)
+                } else {
+                    (0.0, position, 1.0, position, 1f64 - position)
+                }
             } else if (0.0 <= position) && (position <= forelast_page) {
-                (0.0, 1.0, 1f64 - position, 1.0)
+                (0.0, 1.0, 1f64 - position, 1.0, 0.0)
             } else if (forelast_page < position) && (position <= last_page) {
-                (position - forelast_page, 1.0, 0.0, 1.0)
+                (position - forelast_page, 1.0, 0.0, 1.0, 0.0)
             } else {
                 panic!("Position of the carousel is outside the allowed range");
             };
@@ -91,6 +97,7 @@ impl PaginatorWidget {
 
         self.next_btn.set_opacity(opacity_next);
         self.next_btn.set_visible(opacity_next > 0_f64);
+        self.next_overlay.set_can_target(opacity_next > 0_f64);
 
         self.finish_btn.set_opacity(opacity_finish);
         self.finish_btn.set_visible(opacity_finish > 0_f64);
@@ -98,82 +105,69 @@ impl PaginatorWidget {
         self.previous_btn.set_opacity(opacity_previous);
         self.previous_btn.set_visible(opacity_previous > 0_f64);
 
+        self.close_btn.set_opacity(opacity_close);
+        self.start_btn.set_visible(opacity_close > 0_f64);
+
         self.current_page.replace(page_nr);
     }
 
     fn init(&self, p: Rc<Self>) {
-        self.carousel_dots.show();
         self.carousel_dots.set_carousel(Some(&self.carousel));
-        self.carousel.set_property_expand(true);
+        self.carousel.set_hexpand(true);
+        self.carousel.set_vexpand(true);
         self.carousel.set_animation_duration(300);
-        self.carousel.show();
 
         self.carousel
-            .connect_property_position_notify(clone!(@weak p => move |_| {
+            .connect_position_notify(clone!(@weak p => move |_| {
                 p.update_position();
             }));
-        self.start_btn
-            .get_style_context()
-            .add_class("suggested-action");
+        self.start_btn.add_css_class("suggested-action");
         self.start_btn.set_use_underline(true);
         self.start_btn.set_action_name(Some("app.start-tour"));
-        self.start_btn.show();
 
-        self.next_btn
-            .get_style_context()
-            .add_class("suggested-action");
+        self.next_btn.add_css_class("suggested-action");
         self.next_btn.set_use_underline(true);
         self.next_btn.set_action_name(Some("app.next-page"));
 
         self.close_btn.set_use_underline(true);
         self.close_btn.set_action_name(Some("app.quit"));
-        self.close_btn.show();
 
-        self.finish_btn
-            .get_style_context()
-            .add_class("suggested-action");
+        self.finish_btn.add_css_class("suggested-action");
         self.finish_btn.set_use_underline(true);
         self.finish_btn.set_action_name(Some("app.quit"));
 
         self.previous_btn.set_use_underline(true);
         self.previous_btn.set_action_name(Some("app.previous-page"));
 
+        self.next_overlay.set_child(Some(&self.next_btn));
+        self.next_overlay.add_overlay(&self.finish_btn);
+        self.next_overlay.set_can_target(false);
+
         let previous_overlay = gtk::Overlay::new();
-        previous_overlay.add(&self.close_btn);
+        previous_overlay.set_child(Some(&self.close_btn));
         previous_overlay.add_overlay(&self.previous_btn);
-        previous_overlay.show();
-
-        let next_overlay = gtk::Overlay::new();
-        next_overlay.add(&self.next_btn);
-        next_overlay.add_overlay(&self.finish_btn);
-        next_overlay.show();
 
         let start_overlay = gtk::Overlay::new();
-        start_overlay.add(&self.start_btn);
-        start_overlay.add_overlay(&next_overlay);
-        start_overlay.set_overlay_pass_through(&next_overlay, true);
-        start_overlay.show();
+        start_overlay.set_child(Some(&self.start_btn));
+        start_overlay.add_overlay(&self.next_overlay);
 
         let btn_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Horizontal);
         btn_size_group.add_widget(&self.previous_btn);
         btn_size_group.add_widget(&self.close_btn);
-        btn_size_group.add_widget(&next_overlay);
+        btn_size_group.add_widget(&self.next_overlay);
         btn_size_group.add_widget(&start_overlay);
         btn_size_group.add_widget(&self.finish_btn);
 
-        self.headerbar.set_custom_title(Some(&self.carousel_dots));
+        self.headerbar.set_title_widget(Some(&self.carousel_dots));
         self.headerbar.pack_start(&previous_overlay);
         self.headerbar.pack_end(&start_overlay);
-        self.headerbar.set_show_close_button(false);
-        self.headerbar.show();
 
-        self.widget.add(&self.headerbar);
-        self.widget.add(&self.carousel);
-        self.widget.show();
+        self.widget.append(&self.headerbar);
+        self.widget.append(&self.carousel);
     }
 
     pub fn set_page(&self, page_nr: u32) {
-        if page_nr < self.carousel.get_n_pages() {
+        if page_nr < self.carousel.n_pages() {
             let pages = &self.pages.borrow();
             let page = pages.get(page_nr as usize).unwrap();
             self.carousel.scroll_to(page);
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
index d15e510..b393873 100644
--- a/src/widgets/window.rs
+++ b/src/widgets/window.rs
@@ -1,5 +1,6 @@
 use crate::utils::i18n_f;
 use gettextrs::gettext;
+use gtk::glib;
 use gtk::prelude::*;
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -9,14 +10,13 @@ use super::paginator::PaginatorWidget;
 use crate::config::{APP_ID, PROFILE};
 
 pub struct Window {
-    pub widget: libhandy::ApplicationWindow,
+    pub widget: libadwaita::ApplicationWindow,
     pub paginator: RefCell<Rc<PaginatorWidget>>,
 }
 
 impl Window {
     pub fn new(app: &gtk::Application) -> Self {
-        let widget = libhandy::ApplicationWindow::new();
-        widget.set_application(Some(app));
+        let widget = libadwaita::ApplicationWindow::new(app);
 
         let paginator = RefCell::new(PaginatorWidget::new());
 
@@ -40,7 +40,7 @@ impl Window {
 
         // Devel Profile
         if PROFILE == "Devel" {
-            self.widget.get_style_context().add_class("devel");
+            self.widget.add_css_class("devel");
         }
         self.paginator
             .borrow_mut()
@@ -95,18 +95,20 @@ impl Window {
             .upcast::<gtk::Widget>(),
         );
 
-        let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into());
-        let version = glib::get_os_info("VERSION").unwrap_or_else(|| "".into());
+        let name = glib::os_info("NAME").unwrap_or_else(|| "GNOME".into());
+        let version = glib::os_info("VERSION").unwrap_or_else(|| "".into());
         let last_page = ImagePageWidget::new(
             "/org/gnome/Tour/ready-to-go.svg",
             gettext("That's it. Have a nice day!"),
             gettext("To get more advice and tips, see the Help app."),
         );
-        last_page.widget.get_style_context().add_class("last-page");
+        last_page.widget.add_css_class("last-page");
         self.paginator
             .borrow_mut()
             .add_page(last_page.widget.upcast::<gtk::Widget>());
 
-        self.widget.add(&self.paginator.borrow().widget);
+        self.widget
+            .set_property("content", &self.paginator.borrow().widget)
+            .unwrap();
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]