diff --git a/Cargo.toml b/Cargo.toml index cc3cc262e..95178af9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ tracing = "0.1.36" tracing-subscriber = "0.3.15" once_cell = "1.9.0" gettext-rs = { version = "0.7.0", features = ["gettext-system"] } -gtk = { package = "gtk4", version = "0.6.6" } +gtk = { package = "gtk4", version = "0.6.6", features = ["gnome_44"] } gdk-wayland = { package = "gdk4-wayland", version = "0.6.3" } gdk-x11 = { package = "gdk4-x11", version = "0.6.3" } adw = { package = "libadwaita", version = "0.4.0", features = ["v1_2"] } diff --git a/meson.build b/meson.build index 7159cae9a..bc4fb1fae 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,7 @@ base_id = 'io.github.seadve.Kooha' dependency('glib-2.0', version: '>= 2.66') dependency('gio-2.0', version: '>= 2.66') -dependency('gtk4', version: '>= 4.6') +dependency('gtk4', version: '>= 4.10') dependency('libadwaita-1', version: '>= 1.2') dependency('gstreamer-1.0', version: '>= 1.20') dependency('gstreamer-pbutils-1.0', version: '>= 1.20') diff --git a/src/application.rs b/src/application.rs index 78b209bfd..106bded95 100644 --- a/src/application.rs +++ b/src/application.rs @@ -2,7 +2,7 @@ use adw::subclass::prelude::*; use anyhow::{Context, Result}; use gettextrs::gettext; use gtk::{ - gdk, gio, + gio, glib::{self, clone, WeakRef}, prelude::*, }; @@ -135,8 +135,9 @@ impl Application { } async fn try_show_uri(&self, uri: &str) { - if let Err(err) = - gtk::show_uri_full_future(self.main_window().as_ref(), uri, gdk::CURRENT_TIME).await + if let Err(err) = gtk::FileLauncher::new(Some(&gio::File::for_uri(uri))) + .launch_future(self.main_window().as_ref()) + .await { if !err.matches(gio::IOErrorEnum::Cancelled) { tracing::error!("Failed to launch default for uri `{}`: {:?}", uri, err); diff --git a/src/area_selector/mod.rs b/src/area_selector/mod.rs index 122129f59..8aa135d1d 100644 --- a/src/area_selector/mod.rs +++ b/src/area_selector/mod.rs @@ -160,7 +160,7 @@ impl AreaSelector { let monitor_geometry = RootExt::display(transient_for) .monitor_at_surface(&transient_for.surface()) - .expect("No monitor found") + .context("No monitor found")? .geometry(); this.set_default_width( (monitor_geometry.width() as f64 * 0.4 - ASSUMED_HEADER_BAR_HEIGHT * 2.0) as i32, diff --git a/src/preferences_window.rs b/src/preferences_window.rs index 7de670fd4..7136830e4 100644 --- a/src/preferences_window.rs +++ b/src/preferences_window.rs @@ -40,7 +40,7 @@ mod imp { klass.bind_template(); klass.install_action("preferences.select-saving-location", None, |obj, _, _| { - utils::app_settings().select_saving_location(Some(obj)); + utils::app_settings().select_saving_location(obj); }); } @@ -217,6 +217,7 @@ fn profile_row_factory( ) -> gtk::SignalListItemFactory { let factory = gtk::SignalListItemFactory::new(); factory.connect_setup(clone!(@weak profile_row => move |_, list_item| { + let list_item = list_item.downcast_ref::().unwrap(); let item_expression = list_item.property_expression("item"); let hbox = gtk::Box::builder().spacing(12).build(); diff --git a/src/settings.rs b/src/settings.rs index 1bed7d78c..954670cf1 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -6,16 +6,11 @@ use gtk::{ glib::{self, clone}, }; -use std::{ - fs, - path::{Path, PathBuf}, - time::Duration, -}; +use std::{fs, path::PathBuf, time::Duration}; use crate::{ config::APP_ID, profile::{self, Profile}, - utils, }; #[gen_settings(file = "./data/io.github.seadve.Kooha.gschema.xml.in")] @@ -33,57 +28,39 @@ impl Default for Settings { impl Settings { pub const NONE_PROFILE_ID: &'static str = "none"; - /// Opens a `FileChooserDialog` to select a folder and updates + /// Opens a `FileDialog` to select a folder and updates /// the settings with the selected folder. - pub fn select_saving_location(&self, transient_for: Option<&impl IsA>) { - let chooser = gtk::FileChooserDialog::builder() + pub fn select_saving_location(&self, transient_for: &impl IsA) { + let dialog = gtk::FileDialog::builder() .modal(true) - .action(gtk::FileChooserAction::SelectFolder) .title(&gettext("Select Recordings Folder")) + .initial_folder(&gio::File::for_path(self.saving_location())) .build(); - chooser.set_transient_for(transient_for); - - if let Err(err) = - chooser.set_current_folder(Some(&gio::File::for_path(self.saving_location()))) - { - tracing::warn!("Failed to set current folder: {:?}", err); - } - - chooser.add_button(&gettext("_Cancel"), gtk::ResponseType::Cancel); - chooser.add_button(&gettext("_Select"), gtk::ResponseType::Accept); - chooser.set_default_response(gtk::ResponseType::Accept); - - chooser.present(); + let transient_for = transient_for.upcast_ref::(); let inner = &self.0; - chooser.connect_response(clone!(@weak inner => move |chooser, response| { - if response != gtk::ResponseType::Accept { - chooser.close(); - return; - } - - let Some(directory) = chooser.file().and_then(|file| file.path()) else { - present_message( - &gettext("No folder selected"), - &gettext("Please choose a folder and try again."), - Some(chooser), - ); - return; - }; - - if !is_accessible(&directory) { - present_message( - // Translators: {} will be replaced with a path to the folder. - &gettext!("Cannot access “{}”", directory.display()), - &gettext("Please choose an accessible location and try again."), - Some(chooser), - ); - return; - } - - inner.set("saving-location", &directory).unwrap(); - chooser.close(); - })); + dialog.select_folder( + Some(transient_for), + gio::Cancellable::NONE, + clone!(@weak inner, @weak transient_for => move |response| { + match response { + Ok(folder) => { + inner.set("saving-location", folder.path().unwrap()).unwrap(); + } + Err(err) => { + if err.matches(gtk::DialogError::Dismissed) || err.matches(gtk::DialogError::Cancelled) { + return; + } + + present_message( + &gettext("Failed to select folder"), + &err.to_string(), + Some(&transient_for), + ); + } + } + }), + ); } pub fn saving_location(&self) -> PathBuf { @@ -191,16 +168,6 @@ fn present_message(heading: &str, body: &str, transient_for: Option<&impl IsA bool { - if !utils::is_flatpak() { - return true; - } - - let home_folder = glib::home_dir(); - - path != home_folder && path.starts_with(&home_folder) -} - #[cfg(test)] mod tests { use super::*;