about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRicky Kresslein <rk@lakoliu.com>2023-03-23 09:34:44 +0100
committerRicky Kresslein <rk@lakoliu.com>2023-03-23 09:34:44 +0100
commitdff62a9e31ff85305eb2d70b036ee25c90e4feeb (patch)
treef23dbd9fd581772a447b87daea9440cd76941624
parent458d6b3f2934e72c5ed49b452730d2d9f4232812 (diff)
downloadFurtherance-dff62a9e31ff85305eb2d70b036ee25c90e4feeb.tar.zst
Use gtk-rs 0.6.4
-rw-r--r--Cargo.lock126
-rw-r--r--Cargo.toml6
-rw-r--r--src/application.rs24
-rw-r--r--src/main.rs4
-rw-r--r--src/ui/history_box.rs10
-rw-r--r--src/ui/preferences_window.rs15
-rw-r--r--src/ui/report.rs18
-rw-r--r--src/ui/task_details.rs28
-rw-r--r--src/ui/task_row.rs15
-rw-r--r--src/ui/tasks_group.rs7
-rw-r--r--src/ui/tasks_page.rs12
-rw-r--r--src/ui/window.rs59
12 files changed, 173 insertions, 151 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b50f79b..59416ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -83,22 +83,23 @@ checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
 
 [[package]]
 name = "cairo-rs"
-version = "0.15.12"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc"
+checksum = "a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871"
 dependencies = [
  "bitflags",
  "cairo-sys-rs",
  "glib",
  "libc",
+ "once_cell",
  "thiserror",
 ]
 
 [[package]]
 name = "cairo-sys-rs"
-version = "0.15.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8"
+checksum = "f55382a01d30e5e53f185eee269124f5e21ab526595b872751278dfbb463594e"
 dependencies = [
  "glib-sys",
  "libc",
@@ -326,6 +327,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
 
 [[package]]
+name = "futures-macro"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "futures-task"
 version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -338,6 +350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
 dependencies = [
  "futures-core",
+ "futures-macro",
  "futures-task",
  "pin-project-lite",
  "pin-utils",
@@ -346,22 +359,23 @@ dependencies = [
 
 [[package]]
 name = "gdk-pixbuf"
-version = "0.15.11"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a"
+checksum = "b023fbe0c6b407bd3d9805d107d9800da3829dc5a676653210f1d5f16d7f59bf"
 dependencies = [
  "bitflags",
  "gdk-pixbuf-sys",
  "gio",
  "glib",
  "libc",
+ "once_cell",
 ]
 
 [[package]]
 name = "gdk-pixbuf-sys"
-version = "0.15.10"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7"
+checksum = "7b41bd2b44ed49d99277d3925652a163038bd5ed943ec9809338ffb2f4391e3b"
 dependencies = [
  "gio-sys",
  "glib-sys",
@@ -372,9 +386,9 @@ dependencies = [
 
 [[package]]
 name = "gdk4"
-version = "0.4.8"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabb7cf843c26b085a5d68abb95d0c0bf27a9ae2eeff9c4adb503a1eb580876"
+checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff"
 dependencies = [
  "bitflags",
  "cairo-rs",
@@ -388,9 +402,9 @@ dependencies = [
 
 [[package]]
 name = "gdk4-sys"
-version = "0.4.8"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efe7dcb44f5c00aeabff3f69abfc5673de46559070f89bd3fbb7b66485d9cef2"
+checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64"
 dependencies = [
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
@@ -436,26 +450,29 @@ dependencies = [
 
 [[package]]
 name = "gio"
-version = "0.15.12"
+version = "0.17.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b"
+checksum = "2261a3b4e922ec676d1c27ac466218c38cf5dcb49a759129e54bb5046e442125"
 dependencies = [
  "bitflags",
  "futures-channel",
  "futures-core",
  "futures-io",
+ "futures-util",
  "gio-sys",
  "glib",
  "libc",
  "once_cell",
+ "pin-project-lite",
+ "smallvec",
  "thiserror",
 ]
 
 [[package]]
 name = "gio-sys"
-version = "0.15.10"
+version = "0.17.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d"
+checksum = "6b1d43b0d7968b48455244ecafe41192871257f5740aa6b095eb19db78e362a5"
 dependencies = [
  "glib-sys",
  "gobject-sys",
@@ -466,19 +483,22 @@ dependencies = [
 
 [[package]]
 name = "glib"
-version = "0.15.12"
+version = "0.17.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d"
+checksum = "cfb53061756195d76969292c2d2e329e01259276524a9bae6c9b73af62854773"
 dependencies = [
  "bitflags",
  "futures-channel",
  "futures-core",
  "futures-executor",
  "futures-task",
+ "futures-util",
+ "gio-sys",
  "glib-macros",
  "glib-sys",
  "gobject-sys",
  "libc",
+ "memchr",
  "once_cell",
  "smallvec",
  "thiserror",
@@ -486,9 +506,9 @@ dependencies = [
 
 [[package]]
 name = "glib-macros"
-version = "0.15.11"
+version = "0.17.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64"
+checksum = "454924cafe58d9174dc32972261fe271d6cd3c10f5e9ff505522a28dcf601a40"
 dependencies = [
  "anyhow",
  "heck",
@@ -501,9 +521,9 @@ dependencies = [
 
 [[package]]
 name = "glib-sys"
-version = "0.15.10"
+version = "0.17.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4"
+checksum = "49f00ad0a1bf548e61adfff15d83430941d9e1bb620e334f779edd1c745680a5"
 dependencies = [
  "libc",
  "system-deps",
@@ -511,9 +531,9 @@ dependencies = [
 
 [[package]]
 name = "gobject-sys"
-version = "0.15.10"
+version = "0.17.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a"
+checksum = "15e75b0000a64632b2d8ca3cf856af9308e3a970844f6e9659bd197f026793d0"
 dependencies = [
  "glib-sys",
  "libc",
@@ -522,9 +542,9 @@ dependencies = [
 
 [[package]]
 name = "graphene-rs"
-version = "0.15.1"
+version = "0.17.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570"
+checksum = "21cf11565bb0e4dfc2f99d4775b6c329f0d40a2cff9c0066214d31a0e1b46256"
 dependencies = [
  "glib",
  "graphene-sys",
@@ -533,9 +553,9 @@ dependencies = [
 
 [[package]]
 name = "graphene-sys"
-version = "0.15.10"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa691fc7337ba1df599afb55c3bcb85c04f1b3f17362570e9bb0ff0d1bc3028a"
+checksum = "cf80a4849a8d9565410a8fec6fc3678e9c617f4ac7be182ca55ab75016e07af9"
 dependencies = [
  "glib-sys",
  "libc",
@@ -545,9 +565,9 @@ dependencies = [
 
 [[package]]
 name = "gsk4"
-version = "0.4.8"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05e9020d333280b3aa38d496495bfa9b50712eebf1ad63f0ec5bcddb5eb61be4"
+checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c"
 dependencies = [
  "bitflags",
  "cairo-rs",
@@ -561,9 +581,9 @@ dependencies = [
 
 [[package]]
 name = "gsk4-sys"
-version = "0.4.8"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7add39ccf60078508c838643a2dcc91f045c46ed63b5ea6ab701b2e25bda3fea"
+checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0"
 dependencies = [
  "cairo-sys-rs",
  "gdk4-sys",
@@ -577,9 +597,9 @@ dependencies = [
 
 [[package]]
 name = "gtk4"
-version = "0.4.9"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e8ae5aef2793bc3551b5e5e3fa062a5de54bb1eccf10dfa4effe9e4384fbbbc"
+checksum = "1e30e124b5a605f6f5513db13958bfcd51d746607b20bc7bb718b33e303274ed"
 dependencies = [
  "bitflags",
  "cairo-rs",
@@ -600,24 +620,23 @@ dependencies = [
 
 [[package]]
 name = "gtk4-macros"
-version = "0.4.9"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9a4a8077b3a392dd7d637924529e1213d2e0c8e4d531177bc3355e86c257a54"
+checksum = "30e21acdeb9a02b8cba83e65afbb8aa45f977785e50f1113407024c6b6256988"
 dependencies = [
  "anyhow",
  "proc-macro-crate",
  "proc-macro-error",
  "proc-macro2",
- "quick-xml",
  "quote",
  "syn",
 ]
 
 [[package]]
 name = "gtk4-sys"
-version = "0.4.8"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bc8006eea634b7c72da3ff79e24606e45f21b3b832a3c5a1f543f5f97eb0f63"
+checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f"
 dependencies = [
  "cairo-sys-rs",
  "gdk-pixbuf-sys",
@@ -711,10 +730,12 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libadwaita"
-version = "0.1.1"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2ae453d28e3b91f03749f02b1531e8cfe315a1d0762b77a61797d2ab80bb87d"
+checksum = "b1c4efd2020a4fcedbad2c4a97de97bf6045e5dc49d61d5a5d0cfd753db60700"
 dependencies = [
+ "bitflags",
+ "futures-channel",
  "gdk-pixbuf",
  "gdk4",
  "gio",
@@ -728,9 +749,9 @@ dependencies = [
 
 [[package]]
 name = "libadwaita-sys"
-version = "0.1.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8"
+checksum = "0727b85b4fe2b1bed5ac90df6343de15cbf8118bfb96d7c3cc1512681a4b34ac"
 dependencies = [
  "gdk4-sys",
  "gio-sys",
@@ -738,6 +759,7 @@ dependencies = [
  "gobject-sys",
  "gtk4-sys",
  "libc",
+ "pango-sys",
  "system-deps",
 ]
 
@@ -879,11 +901,12 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
 
 [[package]]
 name = "pango"
-version = "0.15.10"
+version = "0.17.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f"
+checksum = "52c280b82a881e4208afb3359a8e7fde27a1b272280981f1f34610bed5770d37"
 dependencies = [
  "bitflags",
+ "gio",
  "glib",
  "libc",
  "once_cell",
@@ -892,9 +915,9 @@ dependencies = [
 
 [[package]]
 name = "pango-sys"
-version = "0.15.10"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa"
+checksum = "4293d0f0b5525eb5c24734d30b0ed02cd02aa734f216883f376b54de49625de8"
 dependencies = [
  "glib-sys",
  "gobject-sys",
@@ -981,15 +1004,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b45c49fc4f91f35bae654f85ebb3a44d60ac64f11b3166ffa609def390c732d8"
 
 [[package]]
-name = "quick-xml"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
-dependencies = [
- "memchr",
-]
-
-[[package]]
 name = "quote"
 version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 6785360..76ab30b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@ dbus = "0.9.7"
 dbus-codegen = "0.10.0"
 directories = "5.0"
 gettext-rs = { version = "0.7", features = ["gettext-system"] }
-gtk4-macros = "0.4.8"
+gtk4-macros = "0.6.3"
 itertools = "0.10.5"
 log = "0.4"
 num-derive = "0.3.3"
@@ -24,8 +24,8 @@ serde = { version = "1.0", features = ["derive"] }
 
 [dependencies.gtk]
 package = "gtk4"
-version = "0.4.9"
+version = "0.6.4"
 
 [dependencies.adw]
 package = "libadwaita"
-version = "0.1.1"
+version = "0.3.1"
diff --git a/src/application.rs b/src/application.rs
index 8d627c5..218bc9e 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -43,8 +43,9 @@ mod imp {
     }
 
     impl ObjectImpl for FurtheranceApplication {
-        fn constructed(&self, obj: &Self::Type) {
-            self.parent_constructed(obj);
+        fn constructed(&self) {
+            self.parent_constructed();
+            let obj = self.obj();
 
             obj.setup_gactions();
             obj.setup_application();
@@ -57,16 +58,17 @@ mod imp {
         // has been launched. Additionally, this callback notifies us when the user
         // tries to launch a "second instance" of the application. When they try
         // to do that, we'll just present any existing window.
-        fn activate(&self, application: &Self::Type) {
+        fn activate(&self) {
             // Initialize the database
             let _ = database::db_init();
             let _ = database::upgrade_old_db();
 
             // Get the current window or create one if necessary
+            let application = self.obj();
             let window = if let Some(window) = application.active_window() {
                 window
             } else {
-                let window = FurtheranceWindow::new(application);
+                let window = FurtheranceWindow::new(&application.clone().upcast());
                 window.set_default_size(360, 600);
                 window.set_title(Some("Furtherance"));
                 window.upcast()
@@ -100,8 +102,10 @@ glib::wrapper! {
 
 impl FurtheranceApplication {
     pub fn new(application_id: &str, flags: &gio::ApplicationFlags) -> Self {
-        glib::Object::new(&[("application-id", &application_id), ("flags", flags)])
-            .expect("Failed to create FurtheranceApplication")
+        glib::Object::builder()
+            .property("application-id", application_id)
+            .property("flags", flags)
+            .build()
     }
 
     fn setup_gactions(&self) {
@@ -158,14 +162,14 @@ impl FurtheranceApplication {
 
         let continue_pomodoro_action = gio::SimpleAction::new("continue-pomodoro-action", None);
         continue_pomodoro_action.connect_activate(clone!(@weak self as app => move |_, _| {
-            let imp = imp::FurtheranceApplication::from_instance(&app);
+            let imp = imp::FurtheranceApplication::from_obj(&app);
             imp.pomodoro_dialog.lock().unwrap().response(gtk::ResponseType::Accept);
         }));
         self.add_action(&continue_pomodoro_action);
 
         let stop_pomodoro_action = gio::SimpleAction::new("stop-pomodoro-action", None);
         stop_pomodoro_action.connect_activate(clone!(@weak self as app => move |_, _| {
-            let imp = imp::FurtheranceApplication::from_instance(&app);
+            let imp = imp::FurtheranceApplication::from_obj(&app);
             imp.pomodoro_dialog.lock().unwrap().response(gtk::ResponseType::Reject);
         }));
         self.add_action(&stop_pomodoro_action);
@@ -185,7 +189,7 @@ impl FurtheranceApplication {
             .version(config::VERSION)
             .comments(&gettext("Track your time without being tracked"))
             .copyright("© 2023 LakoLiu")
-            .authors(vec!["Ricky Kresslein <rk@lakoliu.com>".into()])
+            .authors(vec!["Ricky Kresslein <rk@lakoliu.com>"])
             .translator_credits(&gettext("translator-credits"))
             .website("https://furtherance.app")
             .license_type(gtk::License::Gpl30)
@@ -315,7 +319,7 @@ impl FurtheranceApplication {
     }
 
     pub fn system_pomodoro_notification(&self, dialog: gtk::MessageDialog) {
-        let imp = imp::FurtheranceApplication::from_instance(self);
+        let imp = imp::FurtheranceApplication::from_obj(self);
         *imp.pomodoro_dialog.lock().unwrap() = dialog;
         let icon = Some("alarm-symbolic");
         let notification = gio::Notification::new(&gettext("Time's up!"));
diff --git a/src/main.rs b/src/main.rs
index efe1522..abedf64 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -31,7 +31,7 @@ fn main() {
     // Initialize GTK
     gtk::init().expect("Failed to initialize GTK.");
     // Initialize libadwaita
-    adw::init();
+    let _ = adw::init();
 
     // Set up gettext translations
     bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain");
@@ -55,5 +55,5 @@ fn main() {
     // exits. Upon return, we have our exit code to return to the shell. (This
     // is the code you see when you do `echo $?` after running a command in a
     // terminal.
-    std::process::exit(app.run());
+    std::process::exit(app.run().into());
 }
diff --git a/src/ui/history_box.rs b/src/ui/history_box.rs
index b36808e..8590bd0 100644
--- a/src/ui/history_box.rs
+++ b/src/ui/history_box.rs
@@ -15,7 +15,6 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 use glib::subclass;
-use gtk::prelude::*;
 use gtk::subclass::prelude::*;
 use gtk::{glib, CompositeTemplate};
 
@@ -60,9 +59,10 @@ mod imp {
     }
 
     impl ObjectImpl for FurHistoryBox {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_widgets();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
     impl WidgetImpl for FurHistoryBox {}
@@ -90,7 +90,7 @@ impl FurHistoryBox {
     }
 
     fn set_view(&self, view: View) {
-        let imp = imp::FurHistoryBox::from_instance(self);
+        let imp = imp::FurHistoryBox::from_obj(self);
         let app = FurtheranceApplication::default();
         app.delete_enabled(false);
         app.export_csv_enabled(false);
@@ -115,7 +115,7 @@ impl FurHistoryBox {
     }
 
     pub fn create_tasks_page(&self) {
-        let imp = imp::FurHistoryBox::from_instance(self);
+        let imp = imp::FurHistoryBox::from_obj(self);
         let window = FurtheranceWindow::default();
         imp.tasks_page.clear_task_list();
         let is_saved_task: bool = match database::check_for_tasks() {
diff --git a/src/ui/preferences_window.rs b/src/ui/preferences_window.rs
index 6507ee3..ac0021d 100644
--- a/src/ui/preferences_window.rs
+++ b/src/ui/preferences_window.rs
@@ -19,7 +19,6 @@ use adw::subclass::prelude::*;
 use gettextrs::*;
 use glib::clone;
 use gtk::glib;
-use gtk::subclass::prelude::*;
 use gtk::CompositeTemplate;
 
 use crate::settings_manager;
@@ -95,14 +94,15 @@ mod imp {
     }
 
     impl ObjectImpl for FurPreferencesWindow {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
             let window = FurtheranceWindow::default();
+            let obj = self.obj();
             obj.set_transient_for(Some(&window));
 
             obj.setup_signals();
             obj.setup_widgets();
 
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
 
@@ -124,13 +124,13 @@ glib::wrapper! {
 
 impl FurPreferencesWindow {
     pub fn new() -> Self {
-        glib::Object::new::<FurPreferencesWindow>(&[]).unwrap()
+        glib::Object::new::<FurPreferencesWindow>()
     }
 
     fn setup_widgets(&self) {
         self.set_search_enabled(false);
 
-        let imp = imp::FurPreferencesWindow::from_instance(self);
+        let imp = imp::FurPreferencesWindow::from_obj(self);
 
         let manager = adw::StyleManager::default();
         let support_darkmode = manager.system_supports_color_schemes();
@@ -141,7 +141,7 @@ impl FurPreferencesWindow {
     }
 
     fn setup_signals(&self) {
-        let imp = imp::FurPreferencesWindow::from_instance(self);
+        let imp = imp::FurPreferencesWindow::from_obj(self);
 
         settings_manager::bind_property("dark-mode", &*imp.dark_theme_switch, "active");
 
@@ -253,7 +253,7 @@ impl FurPreferencesWindow {
                             let settings = settings_manager::get_settings();
                             let _ = settings.set_string("database-loc", &path.to_string());
 
-                            let imp2 = imp::FurPreferencesWindow::from_instance(&this2);
+                            let imp2 = imp::FurPreferencesWindow::from_obj(&this2);
                             imp2.database_loc_row.set_subtitle(&path.to_string());
 
                             let window = FurtheranceWindow::default();
@@ -271,3 +271,4 @@ impl FurPreferencesWindow {
         }));
     }
 }
+
diff --git a/src/ui/report.rs b/src/ui/report.rs
index a23bfda..a830b05 100644
--- a/src/ui/report.rs
+++ b/src/ui/report.rs
@@ -18,7 +18,6 @@ use adw::subclass::prelude::*;
 use chrono::{offset::TimeZone, Date, DateTime, Datelike, Duration, Local, NaiveDate};
 use gettextrs::*;
 use glib::clone;
-use gtk::subclass::prelude::*;
 use gtk::{glib, prelude::*, CompositeTemplate};
 use itertools::Itertools;
 
@@ -81,9 +80,10 @@ mod imp {
     }
 
     impl ObjectImpl for FurReport {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_widgets();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
 
@@ -101,7 +101,7 @@ glib::wrapper! {
 
 impl FurReport {
     pub fn new() -> Self {
-        let dialog: Self = glib::Object::new(&[]).unwrap();
+        let dialog: Self = glib::Object::new::<FurReport>();
 
         let window = FurtheranceWindow::default();
         dialog.set_transient_for(Some(&window));
@@ -113,14 +113,14 @@ impl FurReport {
     }
 
     pub fn setup_widgets(&self) {
-        let imp = imp::FurReport::from_instance(self);
+        let imp = imp::FurReport::from_obj(self);
 
         imp.range_combo.set_active_id(Some("week_item"));
         imp.filter_combo.set_active_id(Some("tasks_item"));
 
         imp.range_combo
             .connect_changed(clone!(@weak self as this => move |combo|{
-                let imp = imp::FurReport::from_instance(&this);
+                let imp = imp::FurReport::from_obj(&this);
                 if combo.active_id().unwrap() != "date_range_item" {
                     imp.date_range_box.set_visible(false);
                     this.refresh_report();
@@ -131,7 +131,7 @@ impl FurReport {
 
         imp.filter_check
             .connect_toggled(clone!(@weak self as this => move |_|{
-                let imp = imp::FurReport::from_instance(&this);
+                let imp = imp::FurReport::from_obj(&this);
                 if imp.filter_box.get_visible() {
                     imp.filter_box.set_visible(false);
                 } else {
@@ -141,7 +141,7 @@ impl FurReport {
 
         imp.filter_combo
             .connect_changed(clone!(@weak self as this => move |combo|{
-                let imp = imp::FurReport::from_instance(&this);
+                let imp = imp::FurReport::from_obj(&this);
                 if combo.active_id().unwrap() == "tasks_item" {
                     imp.filter_entry.set_placeholder_text(Some(&gettext("Task, Task 2")));
                 } else {
@@ -172,7 +172,7 @@ impl FurReport {
     }
 
     fn refresh_report(&self) {
-        let imp = imp::FurReport::from_instance(self);
+        let imp = imp::FurReport::from_obj(self);
         imp.format_error.set_visible(false);
         imp.start_end_error.set_visible(false);
 
diff --git a/src/ui/task_details.rs b/src/ui/task_details.rs
index f24a1bc..6939158 100644
--- a/src/ui/task_details.rs
+++ b/src/ui/task_details.rs
@@ -18,7 +18,6 @@ use adw::subclass::prelude::*;
 use chrono::{offset::TimeZone, DateTime, Local, NaiveDateTime, ParseError, Duration};
 use gettextrs::*;
 use glib::clone;
-use gtk::subclass::prelude::*;
 use gtk::{glib, prelude::*, CompositeTemplate};
 use itertools::Itertools;
 
@@ -80,11 +79,12 @@ mod imp {
     }
 
     impl ObjectImpl for FurTaskDetails {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_signals();
             obj.setup_delete_all();
             obj.setup_add_similar();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
 
@@ -102,7 +102,7 @@ glib::wrapper! {
 
 impl FurTaskDetails {
     pub fn new() -> Self {
-        let dialog: Self = glib::Object::new(&[]).unwrap();
+        let dialog: Self = glib::Object::new::<FurTaskDetails>();
 
         let window = FurtheranceWindow::default();
         dialog.set_transient_for(Some(&window));
@@ -114,7 +114,7 @@ impl FurTaskDetails {
     }
 
     pub fn setup_widgets(&self, mut task_group: Vec<database::Task>) {
-        let imp = imp::FurTaskDetails::from_instance(self);
+        let imp = imp::FurTaskDetails::from_obj(self);
 
         imp.task_name_label.set_text(&task_group[0].task_name);
         let this_day_str = DateTime::parse_from_rfc3339(&task_group[0].start_time).unwrap();
@@ -435,7 +435,7 @@ impl FurTaskDetails {
     }
 
     fn clear_task_list(&self) {
-        let imp = imp::FurTaskDetails::from_instance(&self);
+        let imp = imp::FurTaskDetails::from_obj(&self);
 
         for task_box in &*imp.all_boxes.borrow() {
             imp.main_box.remove(task_box);
@@ -474,12 +474,12 @@ impl FurTaskDetails {
     }
 
     fn setup_signals(&self) {
-        let imp = imp::FurTaskDetails::from_instance(self);
+        let imp = imp::FurTaskDetails::from_obj(self);
 
         // Add headerbar to dialog when scrolled far
         imp.scrolled_window.vadjustment().connect_value_notify(
             clone!(@weak self as this => move |adj|{
-                let imp = imp::FurTaskDetails::from_instance(&this);
+                let imp = imp::FurTaskDetails::from_obj(&this);
                 if adj.value() < 120.0 {
                     imp.headerbar.add_css_class("hidden");
                     imp.dialog_title.set_visible(false);
@@ -517,7 +517,7 @@ impl FurTaskDetails {
             let message_area = dialog.message_area().downcast::<gtk::Box>().unwrap();
             let new_name_entry = gtk::Entry::new();
             new_name_entry.set_placeholder_text(Some(&gettext("New Name #tags")));
-            let imp3 = imp::FurTaskDetails::from_instance(&this);
+            let imp3 = imp::FurTaskDetails::from_obj(&this);
             new_name_entry.set_text(&imp3.orig_name_with_tags.borrow().to_string());
             let cant_be_empty = gtk::Label::new(Some(&gettext("Task name cannot be empty.")));
             cant_be_empty.add_css_class("error_message");
@@ -546,7 +546,7 @@ impl FurTaskDetails {
 
                     if !new_task_name.is_empty() {
                         // Change all task names & tags
-                        let imp2 = imp::FurTaskDetails::from_instance(&this);
+                        let imp2 = imp::FurTaskDetails::from_obj(&this);
                         for id in &*imp2.all_task_ids.borrow() {
                             database::update_task_name(*id, new_task_name.trim().to_string())
                                 .expect("Could not update group of task names");
@@ -572,7 +572,7 @@ impl FurTaskDetails {
     }
 
     fn setup_delete_all(&self) {
-        let imp = imp::FurTaskDetails::from_instance(self);
+        let imp = imp::FurTaskDetails::from_obj(self);
         imp.delete_all_btn.connect_clicked(clone!(@weak self as this => move |_|{
             let dialog = gtk::MessageDialog::with_markup(
                 Some(&this),
@@ -611,9 +611,9 @@ impl FurTaskDetails {
     }
 
     fn setup_add_similar(&self) {
-        let imp = imp::FurTaskDetails::from_instance(self);
+        let imp = imp::FurTaskDetails::from_obj(self);
         imp.add_similar_btn.connect_clicked(clone!(@weak self as this => move |_|{
-            let imp2 = imp::FurTaskDetails::from_instance(&this);
+            let imp2 = imp::FurTaskDetails::from_obj(&this);
             let dialog = gtk::MessageDialog::new(
                 Some(&this),
                 gtk::DialogFlags::MODAL,
@@ -806,7 +806,7 @@ impl FurTaskDetails {
     }
 
     fn delete_all(&self) {
-        let imp = imp::FurTaskDetails::from_instance(self);
+        let imp = imp::FurTaskDetails::from_obj(self);
         let _ = database::delete_by_ids(imp.all_task_ids.borrow().to_vec());
     }
 }
diff --git a/src/ui/task_row.rs b/src/ui/task_row.rs
index 810d12e..611ebed 100644
--- a/src/ui/task_row.rs
+++ b/src/ui/task_row.rs
@@ -64,9 +64,10 @@ mod imp {
     }
 
     impl ObjectImpl for FurTaskRow {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_signals();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
 
@@ -85,7 +86,7 @@ impl FurTaskRow {
     pub fn new() -> Self {
         /* This should take a model, object, or vec filled with the description
         details and fill out the labels based on those. */
-        glib::Object::new(&[]).expect("Failed to create `FurTaskRow`.")
+        glib::Object::new::<FurTaskRow>()
     }
 
     fn setup_signals(&self) {
@@ -103,7 +104,7 @@ impl FurTaskRow {
     }
 
     pub fn set_row_labels(&self, task_list: Vec<Task>) {
-        let imp = imp::FurTaskRow::from_instance(&self);
+        let imp = imp::FurTaskRow::from_obj(&self);
         for task in task_list.clone() {
             imp.tasks.lock().unwrap().push(task);
         }
@@ -129,7 +130,7 @@ impl FurTaskRow {
             window.duplicate_task(task_list[0].clone());
         }));
 
-        self.add_controller(&gesture);
+        self.add_controller(gesture);
 
         imp.restart_task_btn
             .connect_clicked(clone!(@strong task_list => move |_| {
@@ -161,12 +162,12 @@ impl FurTaskRow {
     }
 
     pub fn get_tasks(&self) -> Vec<Task> {
-        let imp = imp::FurTaskRow::from_instance(&self);
+        let imp = imp::FurTaskRow::from_obj(&self);
         imp.tasks.lock().unwrap().to_vec()
     }
 
     pub fn get_total_time(&self) -> i64 {
-        let imp = imp::FurTaskRow::from_instance(&self);
+        let imp = imp::FurTaskRow::from_obj(&self);
         *imp.total_time.borrow()
     }
 }
diff --git a/src/ui/tasks_group.rs b/src/ui/tasks_group.rs
index f53b13f..4ba93d2 100644
--- a/src/ui/tasks_group.rs
+++ b/src/ui/tasks_group.rs
@@ -15,7 +15,6 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 use adw::subclass::prelude::*;
-use gtk::subclass::prelude::*;
 use gtk::{glib, prelude::*};
 
 use crate::database;
@@ -67,11 +66,11 @@ glib::wrapper! {
 
 impl FurTasksGroup {
     pub fn new() -> Self {
-        glib::Object::new(&[]).expect("Failed to create `FurTaskGroup`.")
+        glib::Object::new::<FurTasksGroup>()
     }
 
     pub fn add_task_model(&self, tasks: Vec<database::Task>) {
-        let imp = imp::FurTasksGroup::from_instance(&self);
+        let imp = imp::FurTasksGroup::from_obj(&self);
 
         let listbox = gtk::ListBox::new();
         listbox.add_css_class("content");
@@ -115,7 +114,7 @@ impl FurTasksGroup {
     }
 
     pub fn get_total_day_time(&self) -> i64 {
-        let imp = imp::FurTasksGroup::from_instance(&self);
+        let imp = imp::FurTasksGroup::from_obj(&self);
         *imp.day_total_time.borrow()
     }
 }
diff --git a/src/ui/tasks_page.rs b/src/ui/tasks_page.rs
index 192a309..b480b77 100644
--- a/src/ui/tasks_page.rs
+++ b/src/ui/tasks_page.rs
@@ -19,8 +19,7 @@ use adw::subclass::prelude::*;
 use chrono::{DateTime, Duration, Local};
 use chrono_locale::LocaleDate;
 use gettextrs::*;
-use gtk::subclass::prelude::*;
-use gtk::{glib, prelude::*};
+use gtk::glib;
 use std::env;
 
 use crate::database::{self, SortOrder, TaskSort};
@@ -55,9 +54,10 @@ mod imp {
     }
 
     impl ObjectImpl for FurTasksPage {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_widgets();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
 
@@ -77,7 +77,7 @@ impl FurTasksPage {
     }
 
     pub fn clear_task_list(&self) {
-        let imp = imp::FurTasksPage::from_instance(&self);
+        let imp = imp::FurTasksPage::from_obj(&self);
 
         for group in &*imp.all_groups.borrow() {
             self.remove(group);
@@ -87,7 +87,7 @@ impl FurTasksPage {
     }
 
     pub fn build_task_list(&self) {
-        let imp = imp::FurTasksPage::from_instance(&self);
+        let imp = imp::FurTasksPage::from_obj(&self);
 
         // Get user's locale for date formatting
         let locale_env = env::var("LANG");
diff --git a/src/ui/window.rs b/src/ui/window.rs
index bed1931..173d953 100644
--- a/src/ui/window.rs
+++ b/src/ui/window.rs
@@ -22,7 +22,7 @@ use directories::ProjectDirs;
 use gettextrs::*;
 use glib::{clone, timeout_add_local};
 use gtk::subclass::prelude::*;
-use gtk::{gio, glib, CompositeTemplate};
+use gtk::{Application, gio, glib, CompositeTemplate};
 use itertools::Itertools;
 use std::cell::RefCell;
 use std::convert::TryFrom;
@@ -94,11 +94,12 @@ mod imp {
     }
 
     impl ObjectImpl for FurtheranceWindow {
-        fn constructed(&self, obj: &Self::Type) {
+        fn constructed(&self) {
+            let obj = self.obj();
             obj.setup_widgets();
             obj.setup_signals();
             obj.setup_settings();
-            self.parent_constructed(obj);
+            self.parent_constructed();
         }
     }
     impl WidgetImpl for FurtheranceWindow {}
@@ -114,21 +115,23 @@ glib::wrapper! {
 }
 
 impl FurtheranceWindow {
-    pub fn new<P: glib::IsA<gtk::Application>>(application: &P) -> Self {
-        glib::Object::new(&[("application", application)])
-            .expect("Failed to create FurtheranceWindow")
+    pub fn new(app: &Application) -> Self {
+        glib::Object::builder()
+            .property("application", Some(app))
+            .build()
     }
 
+
     pub fn display_toast(&self, text: &str) {
         // Display in-app notifications
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         let toast = adw::Toast::new(text);
-        imp.toast_overlay.add_toast(&toast);
+        imp.toast_overlay.add_toast(toast);
     }
 
     fn set_watch_time(&self, text: &str) {
         // Update watch time while timer is running
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         imp.watch.set_text(text);
         if settings_manager::get_bool("notify-of-idle") {
             self.check_user_idle();
@@ -137,7 +140,7 @@ impl FurtheranceWindow {
 
     pub fn save_task(&self, start_time: DateTime<Local>, mut stop_time: DateTime<Local>) {
         // Save the most recent task to the database and clear the task_input field
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
 
         if *imp.subtract_idle.lock().unwrap() {
             let idle_start =
@@ -154,12 +157,12 @@ impl FurtheranceWindow {
     }
 
     pub fn reset_history_box(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         imp.history_box.create_tasks_page();
     }
 
     fn setup_widgets(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
 
         // Set initial minimum height and alignment
         let is_saved_task: bool = match database::check_for_tasks() {
@@ -187,14 +190,14 @@ impl FurtheranceWindow {
     }
 
     fn setup_signals(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         *imp.running.lock().unwrap() = false;
         let start_time = Rc::new(RefCell::new(Local::now()));
         let stop_time = Rc::new(RefCell::new(Local::now()));
 
         imp.task_input
             .connect_changed(clone!(@weak self as this => move |task_input| {
-                let imp2 = imp::FurtheranceWindow::from_instance(&this);
+                let imp2 = imp::FurtheranceWindow::from_obj(&this);
                 let task_input_text = task_input.text();
                 let split_tags: Vec<&str> = task_input_text.trim().split('#').collect();
                 if split_tags[0].trim().is_empty() {
@@ -205,7 +208,7 @@ impl FurtheranceWindow {
             }));
 
         imp.start_button.connect_clicked(clone!(@weak self as this => move |button| {
-            let imp2 = imp::FurtheranceWindow::from_instance(&this);
+            let imp2 = imp::FurtheranceWindow::from_obj(&this);
             if !*imp2.running.lock().unwrap() {
                 if settings_manager::get_bool("pomodoro") && !*imp2.pomodoro_continue.lock().unwrap() {
                     let pomodoro_time = settings_manager::get_int("pomodoro-time");
@@ -220,7 +223,7 @@ impl FurtheranceWindow {
                     imp2.task_input.set_sensitive(false);
                     let duration = Duration::new(1,0);
                     timeout_add_local(duration, clone!(@strong this as this_clone => move || {
-                        let imp3 = imp::FurtheranceWindow::from_instance(&this_clone);
+                        let imp3 = imp::FurtheranceWindow::from_obj(&this_clone);
                         if *imp3.running.lock().unwrap() {
                             secs -= 1;
                             if secs < 0 {
@@ -274,7 +277,7 @@ impl FurtheranceWindow {
                     let autosave_start = *start_time.borrow();
                     let duration = Duration::new(1,0);
                     timeout_add_local(duration, clone!(@strong this as this_clone => move || {
-                        let imp3 = imp::FurtheranceWindow::from_instance(&this_clone);
+                        let imp3 = imp::FurtheranceWindow::from_obj(&this_clone);
                         if *imp3.running.lock().unwrap() {
                             secs += 1;
                             if secs > 59 {
@@ -500,7 +503,7 @@ impl FurtheranceWindow {
     }
 
     fn setup_settings(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         self.reset_idle();
 
         // Enter starts timer
@@ -524,7 +527,7 @@ impl FurtheranceWindow {
     }
 
     fn check_user_idle(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         // Check for user idle
         let idle_time = match self.get_idle_time() {
             Ok(val) => val,
@@ -552,7 +555,7 @@ impl FurtheranceWindow {
     }
 
     fn resume_from_idle(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
 
         let resume_time = Local::now();
         let idle_start =
@@ -631,7 +634,7 @@ impl FurtheranceWindow {
         dialog.connect_response(clone!(
             @weak self as this,
             @strong dialog => move |_, resp| {
-            let imp = imp::FurtheranceWindow::from_instance(&this);
+            let imp = imp::FurtheranceWindow::from_obj(&this);
             if resp == gtk::ResponseType::Reject {
                 imp.start_button.set_icon_name("media-playback-start-symbolic");
                 this.refresh_timer();
@@ -647,7 +650,7 @@ impl FurtheranceWindow {
             }
         }));
 
-        let imp2 = imp::FurtheranceWindow::from_instance(self);
+        let imp2 = imp::FurtheranceWindow::from_obj(self);
         imp2.idle_dialog.lock().unwrap().close();
 
         dialog.show();
@@ -686,7 +689,7 @@ impl FurtheranceWindow {
     }
 
     fn split_tags_and_task(&self) -> (String, String) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         let task_input_text = imp.task_input.text();
         let mut split_tags: Vec<&str> = task_input_text.trim().split("#").collect();
         // Remove task name from tags list
@@ -755,7 +758,7 @@ impl FurtheranceWindow {
     }
 
     pub fn reset_idle(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         *imp.stored_idle.lock().unwrap() = 0;
         *imp.idle_notified.lock().unwrap() = false;
         *imp.idle_time_reached.lock().unwrap() = false;
@@ -763,12 +766,12 @@ impl FurtheranceWindow {
     }
 
     pub fn set_subtract_idle(&self, val: bool) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         *imp.subtract_idle.lock().unwrap() = val;
     }
 
     pub fn duplicate_task(&self, task: database::Task) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         if !*imp.running.lock().unwrap() {
             let task_text: String;
             if task.tags.trim().is_empty() {
@@ -784,7 +787,7 @@ impl FurtheranceWindow {
     }
 
     pub fn refresh_timer(&self) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         if settings_manager::get_bool("pomodoro") {
             let mut mins = settings_manager::get_int("pomodoro-time");
             let mut hrs: i32 = 0;
@@ -912,7 +915,7 @@ impl FurtheranceWindow {
     }
 
     pub fn vertical_align(&self, align: gtk::Align) {
-        let imp = imp::FurtheranceWindow::from_instance(self);
+        let imp = imp::FurtheranceWindow::from_obj(self);
         imp.win_box.set_valign(align);
     }
 }