From f202117eda224acec3037b784c210b58be356f71 Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 6 Mar 2022 21:53:02 +0100 Subject: [PATCH] feat: switch to gnome toolchain --- .editorconfig | 21 ++ .gitignore | 15 +- Cargo.lock | 351 ++++++++++++++---- Cargo.toml | 13 +- build-aux/chat.revolt.Mutiny.Devel.json | 45 +++ build-aux/dist-vendor.sh | 10 + data/chat.revolt.Mutiny.desktop.in.in | 11 + data/chat.revolt.Mutiny.gschema.xml.in | 20 + data/chat.revolt.Mutiny.metainfo.xml.in.in | 42 +++ ...ic.svg => chat.revolt.Mutiny-symbolic.svg} | 0 ...Devel.svg => chat.revolt.Mutiny.Devel.svg} | 0 ....gtk.Mutiny.svg => chat.revolt.Mutiny.svg} | 0 data/icons/meson.build | 10 + data/meson.build | 76 ++++ data/resources/meson.build | 9 + data/resources/resources.gresource.xml | 8 + data/resources/screenshots/screenshot1.png | Bin 0 -> 19037 bytes data/resources/ui/shortcuts.ui | 29 ++ data/resources/ui/window.ui | 48 +++ meson.build | 71 ++++ meson_options.txt | 10 + po/LINGUAS | 0 po/POTFILES.in | 6 + po/meson.build | 1 + src/application.rs | 141 +++++++ src/config.rs.in | 7 + src/main.rs | 104 +----- src/meson.build | 52 +++ src/window.rs | 116 ++++++ 29 files changed, 1057 insertions(+), 159 deletions(-) create mode 100644 .editorconfig create mode 100644 build-aux/chat.revolt.Mutiny.Devel.json create mode 100644 build-aux/dist-vendor.sh create mode 100644 data/chat.revolt.Mutiny.desktop.in.in create mode 100644 data/chat.revolt.Mutiny.gschema.xml.in create mode 100644 data/chat.revolt.Mutiny.metainfo.xml.in.in rename data/icons/{chat.revolt.gtk.Mutiny-symbolic.svg => chat.revolt.Mutiny-symbolic.svg} (100%) rename data/icons/{chat.revolt.gtk.Mutiny.Devel.svg => chat.revolt.Mutiny.Devel.svg} (100%) rename data/icons/{chat.revolt.gtk.Mutiny.svg => chat.revolt.Mutiny.svg} (100%) create mode 100644 data/icons/meson.build create mode 100644 data/meson.build create mode 100644 data/resources/meson.build create mode 100644 data/resources/resources.gresource.xml create mode 100644 data/resources/screenshots/screenshot1.png create mode 100644 data/resources/ui/shortcuts.ui create mode 100644 data/resources/ui/window.ui create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 po/LINGUAS create mode 100644 po/POTFILES.in create mode 100644 po/meson.build create mode 100644 src/application.rs create mode 100644 src/config.rs.in create mode 100644 src/meson.build create mode 100644 src/window.rs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5600faa --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +root = true +[*] +indent_style = space +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +charset = utf-8 + +[*.{build,css,doap,scss,ui,xml,xml.in,xml.in.in,yaml,yml}] +indent_size = 2 + +[*.{json,py,rs}] +indent_size = 4 + +[*.{c,h,h.in}] +indent_size = 2 +max_line_length = 80 + +[NEWS] +indent_size = 2 +max_line_length = 72 diff --git a/.gitignore b/.gitignore index ea8c4bf..1a3a73a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,14 @@ -/target +target/ +build/ +_build/ +builddir/ +build-aux/app +build-aux/.flatpak-builder/ +src/config.rs +*.ui.in~ +*.ui~ +.flatpak/ +vendor +flatpak_app/ +.flatpak-builder/ +recompile/ diff --git a/Cargo.lock b/Cargo.lock index ce51cce..2b65e7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,32 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -21,10 +41,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "cairo-rs" -version = "0.15.6" +name = "block" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b14c80d8d1a02fa6d914b9d1afeeca9bc34257f8300d9696e1e331ae114223" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "cairo-rs" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "bitflags", "cairo-sys-rs", @@ -35,15 +60,20 @@ dependencies = [ [[package]] name = "cairo-sys-rs" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib-sys", "libc", "system-deps", ] +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cfg-expr" version = "0.10.2" @@ -53,6 +83,25 @@ dependencies = [ "smallvec", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "field-offset" version = "0.3.4" @@ -95,6 +144,17 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-task" version = "0.3.21" @@ -108,6 +168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", @@ -116,9 +177,8 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8750501d75f318c2ec0314701bc8403901303210def80bafd13f6b6059a3f45" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "bitflags", "gdk-pixbuf-sys", @@ -129,9 +189,8 @@ dependencies = [ [[package]] name = "gdk-pixbuf-sys" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "gio-sys", "glib-sys", @@ -142,9 +201,8 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df40006277ff44538fe758400fc671146f6f2665978b6b57d2408db3c2becf" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "bitflags", "cairo-rs", @@ -158,9 +216,8 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -174,10 +231,29 @@ dependencies = [ ] [[package]] -name = "gio" -version = "0.15.6" +name = "gettext-rs" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96efd8a1c00d890f6b45671916e165b5e43ccec61957d443aff6d7e44f62d348" +checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364" +dependencies = [ + "gettext-sys", + "locale_config", +] + +[[package]] +name = "gettext-sys" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa9e06ab9e7514cc9ae668ea3b71ea1536259d767dff0289ac23ad134f99929" +dependencies = [ + "cc", + "temp-dir", +] + +[[package]] +name = "gio" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "bitflags", "futures-channel", @@ -192,9 +268,8 @@ dependencies = [ [[package]] name = "gio-sys" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0fa5052773f5a56b8ae47dab09d040f5d9ce1311f4f99006e16e9a08269296" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib-sys", "gobject-sys", @@ -205,15 +280,15 @@ dependencies = [ [[package]] name = "glib" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa570813c504bdf7539a9400180c2dd4b789a819556fb86da7226d7d1b037b49" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", + "futures-util", "glib-macros", "glib-sys", "gobject-sys", @@ -225,9 +300,8 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41bfd8d227dead0829ac142454e97531b93f576d0805d779c42bfd799c65c572" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "anyhow", "heck", @@ -240,9 +314,8 @@ dependencies = [ [[package]] name = "glib-sys" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4366377bd56697de8aaee24e673c575d2694d72e7756324ded2b0428829a7b8" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "libc", "system-deps", @@ -250,9 +323,8 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib-sys", "libc", @@ -261,9 +333,8 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib", "graphene-sys", @@ -272,9 +343,8 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f311acb023cf7af5537f35de028e03706136eead7f25a31e8fd26f5011e0b3" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib-sys", "libc", @@ -284,9 +354,8 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf63d454e2f75abd92ee6de0ac9fc5aaf1018cd9c458aaf9de296c5cbab6bb9" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "bitflags", "cairo-rs", @@ -300,9 +369,8 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -316,9 +384,8 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e841556e3fe55d8a43ada76b7b08a5f65570bbdfe3b8f72c333053b8832c626" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "bitflags", "cairo-rs", @@ -339,9 +406,8 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573db42bb64973a4d5f718b73caa7204285a1a665308a23b11723d0ee56ec305" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "anyhow", "proc-macro-crate", @@ -353,9 +419,8 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d" +version = "0.5.0" +source = "git+https://github.com/gtk-rs/gtk4-rs.git#f8a6597a7bf3014758b8efe007f593b27d501dbf" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -377,10 +442,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] -name = "libadwaita" -version = "0.1.0" +name = "hermit-abi" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4b1d54d907dfa5d6663fdf4bdbe46c34747258b85c787adbf66187ccbaac81" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libadwaita" +version = "0.1.0-alpha-6" +source = "git+https://gitlab.gnome.org/World/Rust/libadwaita-rs.git?rev=e9ca4b59f2d3774c3ecfbb87828f9c6325fd59f9#e9ca4b59f2d3774c3ecfbb87828f9c6325fd59f9" dependencies = [ "gdk-pixbuf", "gdk4", @@ -395,9 +483,8 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8" +version = "0.1.0-alpha-6" +source = "git+https://gitlab.gnome.org/World/Rust/libadwaita-rs.git?rev=e9ca4b59f2d3774c3ecfbb87828f9c6325fd59f9#e9ca4b59f2d3774c3ecfbb87828f9c6325fd59f9" dependencies = [ "gdk4-sys", "gio-sys", @@ -414,6 +501,43 @@ version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +[[package]] +name = "locale_config" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" +dependencies = [ + "lazy_static", + "objc", + "objc-foundation", + "regex", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + [[package]] name = "memoffset" version = "0.6.5" @@ -427,7 +551,41 @@ dependencies = [ name = "mutiny" version = "0.1.0" dependencies = [ + "gettext-rs", + "gtk4", "libadwaita", + "log", + "once_cell", + "pretty_env_logger", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", ] [[package]] @@ -438,9 +596,8 @@ checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "pango" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c7420fc01a390ec200da7395b64d705f5d82fe03e5d0708aee422c46538be7" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "bitflags", "glib", @@ -451,9 +608,8 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#e06623f4ab5e4395216ce2d4040da7137572be39" dependencies = [ "glib-sys", "gobject-sys", @@ -488,6 +644,16 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + [[package]] name = "proc-macro-crate" version = "1.1.3" @@ -531,6 +697,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.15" @@ -540,6 +712,23 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "rustc_version" version = "0.3.3" @@ -609,6 +798,21 @@ dependencies = [ "version-compare", ] +[[package]] +name = "temp-dir" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af547b166dd1ea4b472165569fc456cfb6818116f854690b0ff205e636523dab" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.30" @@ -678,6 +882,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index c11f4f8..f6c1608 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,13 @@ [package] +edition = "2021" name = "mutiny" version = "0.1.0" -edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies.adw] -package = "libadwaita" -version = "0.1.0" +[dependencies] +adw = {package = "libadwaita", rev = "e9ca4b59f2d3774c3ecfbb87828f9c6325fd59f9", git = "https://gitlab.gnome.org/World/Rust/libadwaita-rs.git"} +gettext-rs = {version = "0.7", features = ["gettext-system"]} +gtk = {package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs.git"} +log = "0.4" +once_cell = "1.9" +pretty_env_logger = "0.4" diff --git a/build-aux/chat.revolt.Mutiny.Devel.json b/build-aux/chat.revolt.Mutiny.Devel.json new file mode 100644 index 0000000..376b120 --- /dev/null +++ b/build-aux/chat.revolt.Mutiny.Devel.json @@ -0,0 +1,45 @@ +{ + "app-id": "chat.revolt.Mutiny.Devel", + "runtime": "org.gnome.Platform", + "runtime-version": "master", + "sdk": "org.gnome.Sdk", + "sdk-extensions": [ + "org.freedesktop.Sdk.Extension.rust-stable" + ], + "command": "mutiny", + "finish-args": [ + "--socket=fallback-x11", + "--socket=wayland", + "--device=dri", + "--share=network", + "--env=RUST_LOG=mutiny=debug", + "--env=G_MESSAGES_DEBUG=none", + "--env=RUST_BACKTRACE=1" + ], + "build-options": { + "append-path": "/usr/lib/sdk/rust-stable/bin", + "build-args": [ + "--share=network" + ], + "test-args": [ + "--socket=x11", + "--share=network" + ] + }, + "modules": [ + { + "name": "mutiny", + "buildsystem": "meson", + "run-tests": true, + "config-opts": [ + "-Dprofile=development" + ], + "sources": [ + { + "type": "dir", + "path": "../" + } + ] + } + ] +} diff --git a/build-aux/dist-vendor.sh b/build-aux/dist-vendor.sh new file mode 100644 index 0000000..be73278 --- /dev/null +++ b/build-aux/dist-vendor.sh @@ -0,0 +1,10 @@ +#!/bin/bash +export DIST="$1" +export SOURCE_ROOT="$2" + +cd "$SOURCE_ROOT" +mkdir "$DIST"/.cargo +cargo vendor | sed 's/^directory = ".*"/directory = "vendor"/g' > $DIST/.cargo/config +# Move vendor into dist tarball directory +mv vendor "$DIST" + diff --git a/data/chat.revolt.Mutiny.desktop.in.in b/data/chat.revolt.Mutiny.desktop.in.in new file mode 100644 index 0000000..bf81e7a --- /dev/null +++ b/data/chat.revolt.Mutiny.desktop.in.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Mutiny +Comment=Revolt Client +Type=Application +Exec=mutiny +Terminal=false +Categories=Network;InstantMessaging +Keywords=Revolt;Chat +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=@icon@ +StartupNotify=true diff --git a/data/chat.revolt.Mutiny.gschema.xml.in b/data/chat.revolt.Mutiny.gschema.xml.in new file mode 100644 index 0000000..0910bc4 --- /dev/null +++ b/data/chat.revolt.Mutiny.gschema.xml.in @@ -0,0 +1,20 @@ + + + + + 600 + Default window width + Default window width + + + 400 + Default window height + Default window height + + + false + Default window maximized behaviour + + + + diff --git a/data/chat.revolt.Mutiny.metainfo.xml.in.in b/data/chat.revolt.Mutiny.metainfo.xml.in.in new file mode 100644 index 0000000..5cae7fa --- /dev/null +++ b/data/chat.revolt.Mutiny.metainfo.xml.in.in @@ -0,0 +1,42 @@ + + + + @app-id@ + CC0 + + + Mutiny + Write a GTK + Rust application + +

A boilerplate template for GTK + Rust. It uses Meson as a build system and has flatpak support by default.

+
+ + + https://gitlab.gnome.org/bilelmoussaoui/mutiny/raw/master/data/resources/screenshots/screenshot1.png + Main window + + + https://github.com/revoltchat/mutiny + https://github.com/revoltchat/mutiny/issues + + moderate + moderate + moderate + intense + + + + + + + ModernToolkit + HiDpiIcon + + Revolt + hello@revolt.chat + @gettext-package@ + @app-id@.desktop +
diff --git a/data/icons/chat.revolt.gtk.Mutiny-symbolic.svg b/data/icons/chat.revolt.Mutiny-symbolic.svg similarity index 100% rename from data/icons/chat.revolt.gtk.Mutiny-symbolic.svg rename to data/icons/chat.revolt.Mutiny-symbolic.svg diff --git a/data/icons/chat.revolt.gtk.Mutiny.Devel.svg b/data/icons/chat.revolt.Mutiny.Devel.svg similarity index 100% rename from data/icons/chat.revolt.gtk.Mutiny.Devel.svg rename to data/icons/chat.revolt.Mutiny.Devel.svg diff --git a/data/icons/chat.revolt.gtk.Mutiny.svg b/data/icons/chat.revolt.Mutiny.svg similarity index 100% rename from data/icons/chat.revolt.gtk.Mutiny.svg rename to data/icons/chat.revolt.Mutiny.svg diff --git a/data/icons/meson.build b/data/icons/meson.build new file mode 100644 index 0000000..2ab86e9 --- /dev/null +++ b/data/icons/meson.build @@ -0,0 +1,10 @@ +install_data( + '@0@.svg'.format(application_id), + install_dir: iconsdir / 'hicolor' / 'scalable' / 'apps' +) + +install_data( + '@0@-symbolic.svg'.format(base_id), + install_dir: iconsdir / 'hicolor' / 'symbolic' / 'apps', + rename: '@0@-symbolic.svg'.format(application_id) +) diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 0000000..5643b60 --- /dev/null +++ b/data/meson.build @@ -0,0 +1,76 @@ +subdir('icons') +subdir('resources') +# Desktop file +desktop_conf = configuration_data() +desktop_conf.set('icon', application_id) +desktop_file = i18n.merge_file( + type: 'desktop', + input: configure_file( + input: '@0@.desktop.in.in'.format(base_id), + output: '@BASENAME@', + configuration: desktop_conf + ), + output: '@0@.desktop'.format(application_id), + po_dir: podir, + install: true, + install_dir: datadir / 'applications' +) +# Validate Desktop file +if desktop_file_validate.found() + test( + 'validate-desktop', + desktop_file_validate, + args: [ + desktop_file.full_path() + ], + depends: desktop_file, + ) +endif + +# Appdata +appdata_conf = configuration_data() +appdata_conf.set('app-id', application_id) +appdata_conf.set('gettext-package', gettext_package) +appdata_file = i18n.merge_file( + input: configure_file( + input: '@0@.metainfo.xml.in.in'.format(base_id), + output: '@BASENAME@', + configuration: appdata_conf + ), + output: '@0@.metainfo.xml'.format(application_id), + po_dir: podir, + install: true, + install_dir: datadir / 'metainfo' +) +# Validate Appdata +if appstream_util.found() + test( + 'validate-appdata', appstream_util, + args: [ + 'validate', '--nonet', appdata_file.full_path() + ], + depends: appdata_file, + ) +endif + +# GSchema +gschema_conf = configuration_data() +gschema_conf.set('app-id', application_id) +gschema_conf.set('gettext-package', gettext_package) +configure_file( + input: '@0@.gschema.xml.in'.format(base_id), + output: '@0@.gschema.xml'.format(application_id), + configuration: gschema_conf, + install: true, + install_dir: datadir / 'glib-2.0' / 'schemas' +) + +# Validata GSchema +if glib_compile_schemas.found() + test( + 'validate-gschema', glib_compile_schemas, + args: [ + '--strict', '--dry-run', meson.current_build_dir() + ], + ) +endif diff --git a/data/resources/meson.build b/data/resources/meson.build new file mode 100644 index 0000000..604e1b2 --- /dev/null +++ b/data/resources/meson.build @@ -0,0 +1,9 @@ +# Resources +resources = gnome.compile_resources( + 'resources', + 'resources.gresource.xml', + gresource_bundle: true, + source_dir: meson.current_build_dir(), + install: true, + install_dir: pkgdatadir, +) diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml new file mode 100644 index 0000000..09be358 --- /dev/null +++ b/data/resources/resources.gresource.xml @@ -0,0 +1,8 @@ + + + + + ui/shortcuts.ui + ui/window.ui + + diff --git a/data/resources/screenshots/screenshot1.png b/data/resources/screenshots/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..173b6beebdbdd81021d0048036f9ba38476cd887 GIT binary patch literal 19037 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 z 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 literal 0 HcmV?d00001 diff --git a/data/resources/ui/shortcuts.ui b/data/resources/ui/shortcuts.ui new file mode 100644 index 0000000..ef12f02 --- /dev/null +++ b/data/resources/ui/shortcuts.ui @@ -0,0 +1,29 @@ + + + + True + + + shortcuts + 10 + + + General + + + Show Shortcuts + win.show-help-overlay + + + + + Quit + app.quit + + + + + + + + diff --git a/data/resources/ui/window.ui b/data/resources/ui/window.ui new file mode 100644 index 0000000..239a221 --- /dev/null +++ b/data/resources/ui/window.ui @@ -0,0 +1,48 @@ + + + +
+ + _Preferences + app.preferences + + + _Keyboard Shortcuts + win.show-help-overlay + + + _About Mutiny + app.about + +
+
+ +
diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..1974ef4 --- /dev/null +++ b/meson.build @@ -0,0 +1,71 @@ +project( + 'mutiny', + 'rust', + version: '0.0.1', + meson_version: '>= 0.59', + # license: MIT, +) + +i18n = import('i18n') +gnome = import('gnome') + +base_id = 'chat.revolt.Mutiny' + +dependency('glib-2.0', version: '>= 2.66') +dependency('gio-2.0', version: '>= 2.66') +dependency('gtk4', version: '>= 4.0.0') + +glib_compile_resources = find_program('glib-compile-resources', required: true) +glib_compile_schemas = find_program('glib-compile-schemas', required: true) +desktop_file_validate = find_program('desktop-file-validate', required: false) +appstream_util = find_program('appstream-util', required: false) +cargo = find_program('cargo', required: true) + +version = meson.project_version() + +prefix = get_option('prefix') +bindir = prefix / get_option('bindir') +localedir = prefix / get_option('localedir') + +datadir = prefix / get_option('datadir') +pkgdatadir = datadir / meson.project_name() +iconsdir = datadir / 'icons' +podir = meson.project_source_root() / 'po' +gettext_package = meson.project_name() + +if get_option('profile') == 'development' + profile = 'Devel' + vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip() + if vcs_tag == '' + version_suffix = '-devel' + else + version_suffix = '-@0@'.format(vcs_tag) + endif + application_id = '@0@.@1@'.format(base_id, profile) +else + profile = '' + version_suffix = '' + application_id = base_id +endif + +meson.add_dist_script( + 'build-aux/dist-vendor.sh', + meson.project_build_root() / 'meson-dist' / meson.project_name() + '-' + version, + meson.project_source_root() +) + +if get_option('profile') == 'development' + # Setup pre-commit hook for ensuring coding style is always consistent + message('Setting up git pre-commit hook..') + run_command('cp', '-f', 'hooks/pre-commit.hook', '.git/hooks/pre-commit') +endif + +subdir('data') +subdir('po') +subdir('src') + +gnome.post_install( + gtk_update_icon_cache: true, + glib_compile_schemas: true, + update_desktop_database: true, +) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..2e02821 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,10 @@ +option( + 'profile', + type: 'combo', + choices: [ + 'default', + 'development' + ], + value: 'default', + description: 'The build profile for Mutiny. One of "default" or "development".' +) diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..e69de29 diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..9b44e61 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,6 @@ +data/chat.revolt.Mutiny.desktop.in.in +data/chat.revolt.Mutiny.gschema.xml.in +data/chat.revolt.Mutiny.metainfo.xml.in.in +data/resources/ui/shortcuts.ui +data/resources/ui/window.ui +src/application.rs diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..57d1266 --- /dev/null +++ b/po/meson.build @@ -0,0 +1 @@ +i18n.gettext(gettext_package, preset: 'glib') diff --git a/src/application.rs b/src/application.rs new file mode 100644 index 0000000..60ae9a7 --- /dev/null +++ b/src/application.rs @@ -0,0 +1,141 @@ +use gettextrs::gettext; +use log::{debug, info}; + +use adw::subclass::prelude::*; +use glib::clone; +use gtk::prelude::*; +use gtk::subclass::prelude::*; +use gtk::{gio, glib}; + +use crate::config::{APP_ID, PKGDATADIR, PROFILE, VERSION}; +use crate::window::MutinyAppWindow; + +mod imp { + use super::*; + use glib::WeakRef; + use once_cell::sync::OnceCell; + + #[derive(Debug, Default)] + pub struct MutinyApp { + pub window: OnceCell>, + } + + #[glib::object_subclass] + impl ObjectSubclass for MutinyApp { + const NAME: &'static str = "MutinyApp"; + type Type = super::MutinyApp; + type ParentType = adw::Application; + } + + impl ObjectImpl for MutinyApp {} + + impl ApplicationImpl for MutinyApp { + fn activate(&self, app: &Self::Type) { + debug!("GtkApplication::activate"); + self.parent_activate(app); + + if let Some(window) = self.window.get() { + let window = window.upgrade().unwrap(); + window.present(); + return; + } + + let window = MutinyAppWindow::new(app); + self.window + .set(window.downgrade()) + .expect("Window already set."); + + app.main_window().present(); + } + + fn startup(&self, app: &Self::Type) { + debug!("GtkApplication::startup"); + self.parent_startup(app); + + // Set icons for shell + gtk::Window::set_default_icon_name(APP_ID); + + app.setup_gactions(); + app.setup_accels(); + } + } + + impl GtkApplicationImpl for MutinyApp {} + impl AdwApplicationImpl for MutinyApp {} +} + +glib::wrapper! { + pub struct MutinyApp(ObjectSubclass) + @extends gio::Application, gtk::Application, adw::Application, + @implements gio::ActionMap, gio::ActionGroup; +} + +impl MutinyApp { + pub fn new() -> Self { + glib::Object::new(&[ + ("application-id", &Some(APP_ID)), + ("flags", &gio::ApplicationFlags::empty()), + ("resource-base-path", &Some("/chat/revolt/Mutiny/")), + ]) + .expect("Application initialization failed...") + } + + fn main_window(&self) -> MutinyAppWindow { + self.imp().window.get().unwrap().upgrade().unwrap() + } + + fn setup_gactions(&self) { + // Quit + let action_quit = gio::SimpleAction::new("quit", None); + action_quit.connect_activate(clone!(@weak self as app => move |_, _| { + // This is needed to trigger the delete event and saving the window state + app.main_window().close(); + app.quit(); + })); + self.add_action(&action_quit); + + // About + let action_about = gio::SimpleAction::new("about", None); + action_about.connect_activate(clone!(@weak self as app => move |_, _| { + app.show_about_dialog(); + })); + self.add_action(&action_about); + } + + // Sets up keyboard shortcuts + fn setup_accels(&self) { + self.set_accels_for_action("app.quit", &["q"]); + } + + fn show_about_dialog(&self) { + let dialog = gtk::AboutDialog::builder() + .logo_icon_name(APP_ID) + // Insert your license of choice here + // .license_type(gtk::License::MitX11) + // Insert your website here + // .website("https://gitlab.gnome.org/bilelmoussaoui/mutiny/") + .version(VERSION) + .transient_for(&self.main_window()) + .translator_credits(&gettext("translator-credits")) + .modal(true) + .authors(vec!["Revolt".into()]) + .artists(vec!["Revolt".into()]) + .build(); + + dialog.present(); + } + + pub fn run(&self) { + info!("Mutiny ({})", APP_ID); + info!("Version: {} ({})", VERSION, PROFILE); + info!("Datadir: {}", PKGDATADIR); + + ApplicationExtManual::run(self); + } +} + +impl Default for MutinyApp { + fn default() -> Self { + Self::new() + } +} diff --git a/src/config.rs.in b/src/config.rs.in new file mode 100644 index 0000000..699897f --- /dev/null +++ b/src/config.rs.in @@ -0,0 +1,7 @@ +pub const APP_ID: &str = @APP_ID@; +pub const GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; +pub const LOCALEDIR: &str = @LOCALEDIR@; +pub const PKGDATADIR: &str = @PKGDATADIR@; +pub const PROFILE: &str = @PROFILE@; +pub const RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/resources.gresource"); +pub const VERSION: &str = @VERSION@; diff --git a/src/main.rs b/src/main.rs index cb5678f..ba84b35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,92 +1,28 @@ -use adw::{prelude::*, Avatar}; +mod application; +#[rustfmt::skip] +mod config; +mod window; -use adw::{ActionRow, ApplicationWindow, HeaderBar}; -use adw::gtk::{Application, Box, ListBox, Orientation}; +use gettextrs::{gettext, LocaleCategory}; +use gtk::{gio, glib}; + +use self::application::MutinyApp; +use self::config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; fn main() { - // Configure a new GTK4 application. - let application = Application::builder() - .application_id("chat.revolt.Mutiny") - .build(); + // Initialize logger + pretty_env_logger::init(); - // Configure Adwaita on start. - application.connect_startup(|_| { - adw::init(); - }); + // Prepare i18n + gettextrs::setlocale(LocaleCategory::LcAll, ""); + gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); + gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); - // Once the application is ready, build the UI. - application.connect_activate(|app| { - // This is our main Window frame. - let frame = Box::new(Orientation::Vertical, 0); + glib::set_application_name(&gettext("Mutiny")); - // Add the header bar, not included by default. - frame.append( - &HeaderBar::builder() - .title_widget(&adw::WindowTitle::new("Mutiny", "")) - .build(), - ); + let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file"); + gio::resources_register(&res); - // Add the main content. - frame.append(&{ - let panels = Box::builder() - .orientation(Orientation::Horizontal) - .margin_top(16) - .margin_start(16) - .build(); - - // Some stuff on the left. - panels.append(&{ - let servers_or_something = Box::new(Orientation::Vertical, 24); - - servers_or_something.append(&Avatar::new(64, Some("deez nuts"), true)); - servers_or_something.append(&Avatar::new(64, Some("hm yes aaa"), true)); - servers_or_something.append(&Avatar::new(64, Some("abc def"), true)); - servers_or_something.append(&Avatar::new(64, Some("aaaa"), true)); - - servers_or_something - }); - - // This is the default content from the Adwaita demo code. - panels.append(&{ - let list = ListBox::builder() - .margin_top(32) - .margin_end(32) - .margin_bottom(32) - .margin_start(32) - .css_classes(vec![String::from("content")]) - .build(); - - list.append(&{ - let row = ActionRow::builder() - .activatable(true) - .selectable(false) - .title("Click me") - .build(); - - row.connect_activated(|_| { - eprintln!("Clicked!"); - }); - - row - }); - - list - }); - - panels - }); - - // Construct the Window. - let window = ApplicationWindow::builder() - .application(app) - .default_width(350) - .content(&frame) - .build(); - - // Display the Window. - window.show(); - }); - - // Run the GTK application. - application.run(); + let app = MutinyApp::new(); + app.run(); } diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..d99036d --- /dev/null +++ b/src/meson.build @@ -0,0 +1,52 @@ +global_conf = configuration_data() +global_conf.set_quoted('APP_ID', application_id) +global_conf.set_quoted('PKGDATADIR', pkgdatadir) +global_conf.set_quoted('PROFILE', profile) +global_conf.set_quoted('VERSION', version + version_suffix) +global_conf.set_quoted('GETTEXT_PACKAGE', gettext_package) +global_conf.set_quoted('LOCALEDIR', localedir) +config = configure_file( + input: 'config.rs.in', + output: 'config.rs', + configuration: global_conf +) +# Copy the config.rs output to the source directory. +run_command( + 'cp', + meson.project_build_root() / 'src' / 'config.rs', + meson.project_source_root() / 'src' / 'config.rs', + check: true +) + +cargo_options = [ '--manifest-path', meson.project_source_root() / 'Cargo.toml' ] +cargo_options += [ '--target-dir', meson.project_build_root() / 'src' ] + +if get_option('profile') == 'default' + cargo_options += [ '--release' ] + rust_target = 'release' + message('Building in release mode') +else + rust_target = 'debug' + message('Building in debug mode') +endif + +cargo_env = [ 'CARGO_HOME=' + meson.project_build_root() / 'cargo-home' ] + +cargo_build = custom_target( + 'cargo-build', + build_by_default: true, + build_always_stale: true, + output: meson.project_name(), + console: true, + install: true, + install_dir: bindir, + depends: resources, + command: [ + 'env', + cargo_env, + cargo, 'build', + cargo_options, + '&&', + 'cp', 'src' / rust_target / meson.project_name(), '@OUTPUT@', + ] +) diff --git a/src/window.rs b/src/window.rs new file mode 100644 index 0000000..1117457 --- /dev/null +++ b/src/window.rs @@ -0,0 +1,116 @@ +use adw::subclass::prelude::*; +use gtk::prelude::*; +use gtk::subclass::prelude::*; +use gtk::{gio, glib}; + +use crate::application::MutinyApp; +use crate::config::{APP_ID, PROFILE}; + +mod imp { + use super::*; + + use gtk::CompositeTemplate; + + #[derive(Debug, CompositeTemplate)] + #[template(resource = "/chat/revolt/Mutiny/ui/window.ui")] + pub struct MutinyAppWindow { + #[template_child] + pub headerbar: TemplateChild, + pub settings: gio::Settings, + } + + impl Default for MutinyAppWindow { + fn default() -> Self { + Self { + headerbar: TemplateChild::default(), + settings: gio::Settings::new(APP_ID), + } + } + } + + #[glib::object_subclass] + impl ObjectSubclass for MutinyAppWindow { + const NAME: &'static str = "MutinyAppWindow"; + type Type = super::MutinyAppWindow; + type ParentType = adw::ApplicationWindow; + + fn class_init(klass: &mut Self::Class) { + Self::bind_template(klass); + } + + // You must call `Widget`'s `init_template()` within `instance_init()`. + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for MutinyAppWindow { + fn constructed(&self, obj: &Self::Type) { + self.parent_constructed(obj); + + // Devel Profile + if PROFILE == "Devel" { + obj.add_css_class("devel"); + } + + // Load latest window state + obj.load_window_size(); + } + } + + impl WidgetImpl for MutinyAppWindow {} + impl WindowImpl for MutinyAppWindow { + // Save window state on delete event + fn close_request(&self, window: &Self::Type) -> gtk::Inhibit { + if let Err(err) = window.save_window_size() { + log::warn!("Failed to save window state, {}", &err); + } + + // Pass close request on to the parent + self.parent_close_request(window) + } + } + + impl ApplicationWindowImpl for MutinyAppWindow {} + impl AdwApplicationWindowImpl for MutinyAppWindow {} +} + +glib::wrapper! { + pub struct MutinyAppWindow(ObjectSubclass) + @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, + @implements gio::ActionMap, gio::ActionGroup, gtk::Root; +} + +impl MutinyAppWindow { + pub fn new(app: &MutinyApp) -> Self { + glib::Object::new(&[("application", app)]).expect("Failed to create MutinyAppWindow") + } + + fn save_window_size(&self) -> Result<(), glib::BoolError> { + let imp = self.imp(); + + let (width, height) = self.default_size(); + + imp.settings.set_int("window-width", width)?; + imp.settings.set_int("window-height", height)?; + + imp.settings + .set_boolean("is-maximized", self.is_maximized())?; + + Ok(()) + } + + fn load_window_size(&self) { + let imp = self.imp(); + + let width = imp.settings.int("window-width"); + let height = imp.settings.int("window-height"); + let is_maximized = imp.settings.boolean("is-maximized"); + + self.set_default_size(width, height); + + if is_maximized { + self.maximize(); + } + } +}