Migrate to latest gtk-rs release

This commit is contained in:
Bilal Elmoussaoui 2022-12-24 17:02:18 +01:00
parent bb862c11ff
commit e4fb7e899c
30 changed files with 1090 additions and 859 deletions

1310
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4,18 +4,18 @@ name = "authenticator"
version = "4.1.6"
[dependencies]
adw = {package = "libadwaita", version = "0.1.0"}
adw = {package = "libadwaita", version = "0.2"}
anyhow = "1.0"
ashpd = {version = "0.3", features = ["feature_pipewire", "feature_gtk4"]}
ashpd = {version = "0.4.0-alpha.1", features = ["pipewire", "gtk4"]}
binascii = "0.1"
diesel = {version = "1.4", features = ["sqlite", "r2d2"]}
diesel_migrations = {version = "1.4", features = ["sqlite"]}
gettext-rs = {version = "0.7", features = ["gettext-system"]}
gst = {package = "gstreamer", version = "0.18"}
gst4gtk = { package = "gst-plugin-gtk4", version = "0.1"}
gtk = {package = "gtk4", version = "0.4"}
gst = {package = "gstreamer", version = "0.19"}
gst4gtk = { package = "gst-plugin-gtk4", version = "0.9"}
gtk = {package = "gtk4", version = "0.5"}
gtk-macros = "0.3"
search-provider = "0.3"
search-provider = "0.4"
hex = { version = "0.4.3", features = [ "serde" ] }
tracing = "0.1"
tracing-subscriber = "0.3"

View file

@ -20,7 +20,7 @@ mod imp {
use std::cell::{Cell, RefCell};
use adw::subclass::prelude::*;
use glib::{ParamFlags, ParamSpec, ParamSpecBoolean, Value, WeakRef};
use glib::{ParamSpec, ParamSpecBoolean, Value, WeakRef};
use once_cell::sync::{Lazy, OnceCell};
use super::*;
@ -51,26 +51,16 @@ mod imp {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![
ParamSpecBoolean::new(
"is-locked",
"",
"",
false,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
),
ParamSpecBoolean::new(
"can-be-locked",
"",
"",
false,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
),
ParamSpecBoolean::builder("is-locked").construct().build(),
ParamSpecBoolean::builder("can-be-locked")
.construct()
.build(),
]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"is-locked" => {
let locked = value.get().unwrap();
@ -84,7 +74,7 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"is-locked" => self.locked.get().to_value(),
"can-be-locked" => self.can_be_locked.get().to_value(),
@ -95,9 +85,9 @@ mod imp {
// Overrides GApplication vfuncs
impl ApplicationImpl for Application {
fn startup(&self, app: &Self::Type) {
self.parent_startup(app);
fn startup(&self) {
self.parent_startup();
let app = self.obj();
action!(app, "quit", clone!(@weak app => move |_, _| app.quit()));
action!(
@ -213,7 +203,8 @@ mod imp {
}));
}
fn activate(&self, app: &Self::Type) {
fn activate(&self) {
let app = self.obj();
if let Some(ref win) = *self.window.borrow() {
let window = win.upgrade().unwrap();
window.present();
@ -236,15 +227,15 @@ mod imp {
app.restart_lock_timeout();
}
fn open(&self, application: &Self::Type, files: &[gio::File], _hint: &str) {
self.activate(application);
fn open(&self, files: &[gio::File], _hint: &str) {
self.activate();
let uris = files
.iter()
.filter_map(|f| OTPUri::from_str(&f.uri()).ok())
.collect::<Vec<OTPUri>>();
// We only handle a single URI (see the desktop file)
if let Some(uri) = uris.get(0) {
let window = application.active_window();
let window = self.obj().active_window();
window.open_add_account(Some(uri))
}
}
@ -321,8 +312,7 @@ impl Application {
("resource-base-path", &"/com/belmoussaoui/Authenticator"),
("is-locked", &has_set_password),
("can-be-locked", &has_set_password),
])
.unwrap();
]);
// Only load the model if the app is not locked
if !has_set_password {
app.imp().model.load();

View file

@ -14,7 +14,7 @@
use aes_gcm::{aead::Aead, NewAead};
use anyhow::{Context, Result};
use gettextrs::gettext;
use gtk::{glib::Cast, prelude::*};
use gtk::prelude::*;
use rand::RngCore;
use serde::{Deserialize, Serialize};

View file

@ -1,6 +1,6 @@
use anyhow::Result;
use gettextrs::gettext;
use gtk::{glib::Cast, prelude::*};
use gtk::prelude::*;
use serde::{Deserialize, Serialize};
use super::{Backupable, Restorable, RestorableItem};

View file

@ -3,8 +3,11 @@ use std::cell::{Cell, RefCell};
use anyhow::{Context, Result};
use diesel::{BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl};
use glib::{clone, Cast, StaticType, ToValue};
use gtk::{glib, prelude::*, subclass::prelude::*};
use gtk::{
glib::{self, clone},
prelude::*,
subclass::prelude::*,
};
use once_cell::sync::OnceCell;
use unicase::UniCase;
@ -96,22 +99,16 @@ mod imp {
otp::HOTP_DEFAULT_COUNTER,
ParamFlags::READWRITE,
),
ParamSpecString::new("name", "", "", None, ParamFlags::READWRITE),
ParamSpecString::new("token-id", "", "", None, ParamFlags::READWRITE),
ParamSpecString::new("otp", "", "", None, ParamFlags::READWRITE),
ParamSpecObject::new(
"provider",
"",
"",
Provider::static_type(),
ParamFlags::READWRITE,
),
ParamSpecString::builder("name").build(),
ParamSpecString::builder("token-id").build(),
ParamSpecString::builder("otp").build(),
ParamSpecObject::builder::<Provider>("provider").build(),
]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"id" => {
let id = value.get().unwrap();
@ -141,7 +138,7 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"id" => self.id.get().to_value(),
"name" => self.name.borrow().to_value(),
@ -254,8 +251,7 @@ impl Account {
("token-id", &token_id),
("provider", &provider),
("counter", &counter),
])
.context("Failed to create account")?;
]);
let token = if let Some(t) = token {
t.to_string()

View file

@ -18,16 +18,11 @@ mod imp {
impl ObjectImpl for AccountSorter {}
impl SorterImpl for AccountSorter {
fn order(&self, _sorter: &Self::Type) -> gtk::SorterOrder {
fn order(&self) -> gtk::SorterOrder {
gtk::SorterOrder::Total
}
fn compare(
&self,
_sorter: &Self::Type,
item1: &glib::Object,
item2: &glib::Object,
) -> gtk::Ordering {
fn compare(&self, item1: &glib::Object, item2: &glib::Object) -> gtk::Ordering {
Account::compare(item1, item2).into()
}
}
@ -40,6 +35,6 @@ glib::wrapper! {
impl Default for AccountSorter {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create AccountSorter")
glib::Object::new(&[])
}
}

View file

@ -20,13 +20,13 @@ mod imp {
impl ObjectImpl for AccountsModel {}
impl ListModelImpl for AccountsModel {
fn item_type(&self, _list_model: &Self::Type) -> glib::Type {
fn item_type(&self) -> glib::Type {
Account::static_type()
}
fn n_items(&self, _list_model: &Self::Type) -> u32 {
fn n_items(&self) -> u32 {
self.0.borrow().len() as u32
}
fn item(&self, _list_model: &Self::Type, position: u32) -> Option<glib::Object> {
fn item(&self, position: u32) -> Option<glib::Object> {
self.0
.borrow()
.get(position as usize)
@ -91,6 +91,6 @@ impl AccountsModel {
impl Default for AccountsModel {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create AccountsModel")
glib::Object::new(&[])
}
}

View file

@ -8,8 +8,12 @@ use std::{
use anyhow::Result;
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
use glib::{clone, Cast, StaticType, ToValue};
use gtk::{gdk_pixbuf, gio, glib, prelude::*, subclass::prelude::*};
use gtk::{
gdk_pixbuf, gio,
glib::{self, clone},
prelude::*,
subclass::prelude::*,
};
use unicase::UniCase;
use url::Url;
@ -126,14 +130,8 @@ mod imp {
0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
),
ParamSpecString::new("name", "", "", None, ParamFlags::READWRITE),
ParamSpecObject::new(
"accounts",
"",
"",
AccountsModel::static_type(),
ParamFlags::READWRITE,
),
ParamSpecString::builder("name").build(),
ParamSpecObject::builder::<AccountsModel>("accounts").build(),
ParamSpecUInt::new(
"period",
"",
@ -175,8 +173,8 @@ mod imp {
Some(&OTPMethod::default().to_string()),
ParamFlags::READWRITE,
),
ParamSpecString::new("website", "", "", None, ParamFlags::READWRITE),
ParamSpecString::new("help-url", "", "", None, ParamFlags::READWRITE),
ParamSpecString::builder("website").build(),
ParamSpecString::builder("help-url").build(),
ParamSpecString::new(
"image-uri",
"",
@ -198,7 +196,7 @@ mod imp {
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"id" => {
let id = value.get().unwrap();
@ -248,7 +246,7 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"id" => self.id.get().to_value(),
"name" => self.name.borrow().to_value(),
@ -266,7 +264,7 @@ mod imp {
}
}
fn dispose(&self, _obj: &Self::Type) {
fn dispose(&self) {
// Stop ticking
if let Some(source_id) = self.tick_callback.borrow_mut().take() {
source_id.remove();
@ -365,7 +363,6 @@ impl Provider {
("digits", &digits),
("default-counter", &default_counter),
])
.expect("Failed to create provider")
}
pub async fn favicon(

View file

@ -19,16 +19,11 @@ mod imp {
impl ObjectImpl for ProviderSorter {}
impl SorterImpl for ProviderSorter {
fn order(&self, _sorter: &Self::Type) -> gtk::SorterOrder {
fn order(&self) -> gtk::SorterOrder {
gtk::SorterOrder::Total
}
fn compare(
&self,
_sorter: &Self::Type,
item1: &glib::Object,
item2: &glib::Object,
) -> gtk::Ordering {
fn compare(&self, item1: &glib::Object, item2: &glib::Object) -> gtk::Ordering {
Provider::compare(item1, item2).into()
}
}
@ -41,6 +36,6 @@ glib::wrapper! {
impl Default for ProviderSorter {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create ProviderSorter")
glib::Object::new(&[])
}
}

View file

@ -20,13 +20,13 @@ mod imp {
}
impl ObjectImpl for ProvidersModel {}
impl ListModelImpl for ProvidersModel {
fn item_type(&self, _list_model: &Self::Type) -> glib::Type {
fn item_type(&self) -> glib::Type {
Provider::static_type()
}
fn n_items(&self, _list_model: &Self::Type) -> u32 {
fn n_items(&self) -> u32 {
self.0.borrow().len() as u32
}
fn item(&self, _list_model: &Self::Type, position: u32) -> Option<glib::Object> {
fn item(&self, position: u32) -> Option<glib::Object> {
self.0
.borrow()
.get(position as usize)
@ -229,6 +229,6 @@ impl ProvidersModel {
impl Default for ProvidersModel {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create Model")
glib::Object::new(&[])
}
}

View file

@ -104,17 +104,14 @@ mod imp {
impl ObjectImpl for AccountAddDialog {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![Signal::builder("added", &[], <()>::static_type().into())
.action()
.build()]
});
static SIGNALS: Lazy<Vec<Signal>> =
Lazy::new(|| vec![Signal::builder("added").action().build()]);
SIGNALS.as_ref()
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.action_set_enabled("add.save", false);
fn constructed(&self) {
self.parent_constructed();
self.obj().action_set_enabled("add.save", false);
}
}
impl WidgetImpl for AccountAddDialog {}
@ -129,7 +126,7 @@ glib::wrapper! {
#[gtk::template_callbacks]
impl AccountAddDialog {
pub fn new(model: ProvidersModel) -> Self {
let dialog = glib::Object::new::<Self>(&[]).expect("Failed to create AccountAddDialog");
let dialog = glib::Object::new::<Self>(&[]);
dialog.imp().model.set(model).unwrap();
dialog.setup_widget();

View file

@ -121,31 +121,26 @@ mod imp {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder(
"removed",
&[Account::static_type().into()],
<()>::static_type().into(),
)
.action()
.build(),
Signal::builder("provider-changed", &[], <()>::static_type().into())
Signal::builder("removed")
.param_types([Account::static_type()])
.action()
.build(),
Signal::builder("provider-changed").action().build(),
]
});
SIGNALS.as_ref()
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
self.qrcode_picture
.set_paintable(Some(&self.qrcode_paintable));
self.counter_label.set_adjustment(1, u32::MAX);
}
}
impl WidgetImpl for AccountDetailsPage {
fn unmap(&self, widget: &Self::Type) {
self.parent_unmap(widget);
fn unmap(&self) {
self.parent_unmap();
self.edit_stack.set_visible_child_name("edit");
self.account_label.stop_editing(false);
self.counter_label.stop_editing(false);

View file

@ -82,17 +82,9 @@ mod imp {
impl ObjectImpl for QRCodePaintable {}
impl PaintableImpl for QRCodePaintable {
fn snapshot(
&self,
_paintable: &Self::Type,
snapshot: &gdk::Snapshot,
width: f64,
height: f64,
) {
let snapshot = snapshot.downcast_ref::<gtk::Snapshot>().unwrap();
fn snapshot(&self, snapshot: &gdk::Snapshot, width: f64, height: f64) {
if let Some(ref qrcode) = *self.qrcode.borrow() {
snapshot_qrcode(snapshot, qrcode, width, height);
snapshot_qrcode(snapshot.as_ref(), qrcode, width, height);
}
}
}
@ -112,6 +104,6 @@ impl QRCodePaintable {
impl Default for QRCodePaintable {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create a QRCodePaintable")
glib::Object::new(&[])
}
}

View file

@ -1,13 +1,13 @@
use std::cell::RefCell;
use gtk::{gdk, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
use gtk::{gdk, glib, prelude::*, CompositeTemplate};
use crate::models::{Account, OTPMethod};
mod imp {
use adw::subclass::prelude::*;
use gettextrs::gettext;
use glib::{subclass, ParamFlags, ParamSpec, ParamSpecObject, Value};
use glib::{subclass, ParamSpec, ParamSpecObject, Value};
use once_cell::sync::Lazy;
use super::*;
@ -62,17 +62,13 @@ mod imp {
impl ObjectImpl for AccountRow {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecObject::new(
"account",
"",
"",
Account::static_type(),
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
)]
vec![ParamSpecObject::builder::<Account>("account")
.construct_only()
.build()]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"account" => {
let account = value.get().unwrap();
@ -82,23 +78,24 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"account" => self.account.borrow().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
let account = obj.account();
account
.bind_property("name", obj, "title")
.bind_property("name", &*obj, "title")
.flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE)
.build();
account
.bind_property("name", obj, "tooltip-text")
.bind_property("name", &*obj, "tooltip-text")
.flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE)
.build();
@ -125,7 +122,7 @@ glib::wrapper! {
impl AccountRow {
pub fn new(account: Account) -> Self {
glib::Object::new(&[("account", &account)]).expect("Failed to create AccountRow")
glib::Object::new(&[("account", &account)])
}
fn account(&self) -> Account {

View file

@ -5,7 +5,7 @@ use std::{
use adw::subclass::prelude::*;
use anyhow::Result;
use ashpd::{desktop::screenshot::ScreenshotProxy, zbus};
use ashpd::desktop::screenshot::ScreenshotRequest;
use gst::prelude::*;
use gtk::{
gio,
@ -15,7 +15,6 @@ use gtk::{
Receiver,
},
prelude::*,
subclass::prelude::*,
CompositeTemplate,
};
use gtk_macros::spawn;
@ -49,35 +48,31 @@ mod screenshot {
}
pub async fn capture(window: Option<gtk::Window>) -> Result<gio::File> {
let connection = zbus::Connection::session().await?;
let proxy = ScreenshotProxy::new(&connection).await?;
let uri = proxy
.screenshot(
&{
if let Some(ref window) = window {
ashpd::WindowIdentifier::from_native(window).await
} else {
ashpd::WindowIdentifier::default()
}
},
true,
true,
)
let identifier = if let Some(ref window) = window {
ashpd::WindowIdentifier::from_native(window).await
} else {
ashpd::WindowIdentifier::default()
};
let uri = ScreenshotRequest::default()
.identifier(identifier)
.modal(true)
.interactive(true)
.build()
.await?;
Ok(gio::File::for_uri(&uri))
Ok(gio::File::for_uri(uri.as_str()))
}
pub async fn stream() -> Result<Option<(RawFd, Option<u32>)>> {
let connection = zbus::Connection::session().await?;
let proxy = ashpd::desktop::camera::CameraProxy::new(&connection).await?;
if !proxy.is_camera_present().await? {
pub async fn stream() -> Result<Option<(RawFd, Vec<ashpd::desktop::camera::Stream>)>> {
let proxy = ashpd::desktop::camera::Camera::new().await?;
if !proxy.is_present().await? {
return Ok(None);
}
proxy.access_camera().await?;
proxy.request_access().await?;
let stream_fd = proxy.open_pipe_wire_remote().await?;
let node_id = ashpd::desktop::camera::pipewire_node_id(stream_fd).await?;
Ok(Some((stream_fd, node_id)))
let nodes_id = ashpd::desktop::camera::pipewire_streams(stream_fd).await?;
Ok(Some((stream_fd, nodes_id)))
}
}
@ -150,29 +145,25 @@ mod imp {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder("close", &[], <()>::static_type().into())
.action()
Signal::builder("close").action().build(),
Signal::builder("code-detected")
.param_types([String::static_type()])
.run_first()
.build(),
Signal::builder(
"code-detected",
&[String::static_type().into()],
<()>::static_type().into(),
)
.run_first()
.build(),
]
});
SIGNALS.as_ref()
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.setup_receiver();
obj.set_state(CameraState::NotFound);
self.picture.set_paintable(Some(&self.paintable));
}
fn dispose(&self, _obj: &Self::Type) {
fn dispose(&self) {
self.paintable.close_pipeline();
}
}
@ -238,7 +229,8 @@ impl Camera {
if !self.imp().started.get() {
spawn!(clone!(@weak self as camera => async move {
match screenshot::stream().await {
Ok(Some((stream_fd, node_id))) => {
Ok(Some((stream_fd, nodes_id))) => {
let node_id = nodes_id.get(0).map(|s| s.node_id());
match camera.imp().paintable.set_pipewire_node_id(stream_fd, node_id) {
Ok(_) => camera.start(),
Err(err) => tracing::error!("Failed to start the camera stream {err}"),
@ -319,6 +311,6 @@ impl Camera {
impl Default for Camera {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create a Camera")
glib::Object::new(&[])
}
}

View file

@ -42,13 +42,13 @@ mod imp {
}
impl ObjectImpl for CameraPaintable {
fn dispose(&self, paintable: &Self::Type) {
paintable.close_pipeline();
fn dispose(&self) {
self.obj().close_pipeline();
}
}
impl PaintableImpl for CameraPaintable {
fn intrinsic_height(&self, _paintable: &Self::Type) -> i32 {
fn intrinsic_height(&self) -> i32 {
if let Some(ref paintable) = *self.sink_paintable.borrow() {
paintable.intrinsic_height()
} else {
@ -56,7 +56,7 @@ mod imp {
}
}
fn intrinsic_width(&self, _paintable: &Self::Type) -> i32 {
fn intrinsic_width(&self) -> i32 {
if let Some(ref paintable) = *self.sink_paintable.borrow() {
paintable.intrinsic_width()
} else {
@ -64,14 +64,7 @@ mod imp {
}
}
fn snapshot(
&self,
_paintable: &Self::Type,
snapshot: &gdk::Snapshot,
width: f64,
height: f64,
) {
let snapshot = snapshot.downcast_ref::<gtk::Snapshot>().unwrap();
fn snapshot(&self, snapshot: &gdk::Snapshot, width: f64, height: f64) {
if let Some(ref image) = *self.sink_paintable.borrow() {
// Transformation to avoid stretching the camera. We translate and scale the
// image.
@ -79,7 +72,7 @@ mod imp {
let image_aspect = image.intrinsic_aspect_ratio();
if image_aspect == 0.0 {
image.snapshot(snapshot.upcast_ref(), width, height);
image.snapshot(snapshot, width, height);
return;
};
@ -94,7 +87,7 @@ mod imp {
);
snapshot.translate(&p);
image.snapshot(snapshot.upcast_ref(), new_width, new_height);
image.snapshot(snapshot, new_width, new_height);
} else {
snapshot.append_color(
&gdk::RGBA::BLACK,
@ -112,7 +105,7 @@ glib::wrapper! {
impl CameraPaintable {
pub fn new(sender: Sender<CameraEvent>) -> Self {
let paintable = glib::Object::new::<Self>(&[]).expect("Failed to create a CameraPaintable");
let paintable = glib::Object::new::<Self>(&[]);
paintable.imp().sender.replace(Some(sender));
paintable
}
@ -123,7 +116,7 @@ impl CameraPaintable {
node_id: Option<u32>,
) -> anyhow::Result<()> {
let raw_fd = fd.as_raw_fd();
let pipewire_element = gst::ElementFactory::make("pipewiresrc", None)?;
let pipewire_element = gst::ElementFactory::make_with_name("pipewiresrc", None)?;
pipewire_element.set_property("fd", &raw_fd);
if let Some(node_id) = node_id {
pipewire_element.set_property("path", &node_id.to_string());
@ -140,7 +133,7 @@ impl CameraPaintable {
let imp = self.imp();
let pipeline = gst::Pipeline::new(None);
let sink = gst::ElementFactory::make("gtk4paintablesink", None)?;
let sink = gst::ElementFactory::make_with_name("gtk4paintablesink", None)?;
let paintable = sink.property::<gdk::Paintable>("paintable");
paintable.connect_invalidate_contents(clone!(@weak self as pt => move |_| {
@ -151,13 +144,13 @@ impl CameraPaintable {
pt.invalidate_size ();
}));
imp.sink_paintable.replace(Some(paintable));
let tee = gst::ElementFactory::make("tee", None)?;
let videoconvert1 = gst::ElementFactory::make("videoconvert", None)?;
let videoconvert2 = gst::ElementFactory::make("videoconvert", None)?;
let queue1 = gst::ElementFactory::make("queue", None)?;
let queue2 = gst::ElementFactory::make("queue", None)?;
let zbar = gst::ElementFactory::make("zbar", None)?;
let fakesink = gst::ElementFactory::make("fakesink", None)?;
let tee = gst::ElementFactory::make_with_name("tee", None)?;
let videoconvert1 = gst::ElementFactory::make_with_name("videoconvert", None)?;
let videoconvert2 = gst::ElementFactory::make_with_name("videoconvert", None)?;
let queue1 = gst::ElementFactory::make_with_name("queue", None)?;
let queue2 = gst::ElementFactory::make_with_name("queue", None)?;
let zbar = gst::ElementFactory::make_with_name("zbar", None)?;
let fakesink = gst::ElementFactory::make_with_name("fakesink", None)?;
pipeline.add_many(&[
&pipewire_src,

View file

@ -32,14 +32,14 @@ mod imp {
}
impl ObjectImpl for EditableLabel {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
self.stack.set_visible_child_name("label");
}
}
impl WidgetImpl for EditableLabel {
fn grab_focus(&self, widget: &Self::Type) -> bool {
self.parent_grab_focus(widget);
fn grab_focus(&self) -> bool {
self.parent_grab_focus();
if self.stack.visible_child_name().as_deref() == Some("entry") {
self.entry.grab_focus();
true
@ -77,14 +77,14 @@ mod imp {
}
impl ObjectImpl for EditableSpin {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
self.stack.set_visible_child_name("label");
}
}
impl WidgetImpl for EditableSpin {
fn grab_focus(&self, widget: &Self::Type) -> bool {
self.parent_grab_focus(widget);
fn grab_focus(&self) -> bool {
self.parent_grab_focus();
if self.stack.visible_child_name().as_deref() == Some("spin") {
self.spin.grab_focus();
true

View file

@ -32,7 +32,7 @@ mod imp {
}
impl ObjectImpl for ErrorRevealer {
fn dispose(&self, _obj: &Self::Type) {
fn dispose(&self) {
self.revealer.unparent();
self.label.unparent();
}

View file

@ -6,7 +6,6 @@ use gtk::{
gio,
glib::{self, clone, subclass::InitializingObject},
prelude::*,
subclass::prelude::*,
CompositeTemplate,
};
use gtk_macros::get_action;
@ -58,7 +57,7 @@ glib::wrapper! {
impl CameraPage {
pub fn new(actions: gio::SimpleActionGroup) -> Self {
let page = glib::Object::new::<Self>(&[]).expect("Failed to create CameraPage");
let page = glib::Object::new::<Self>(&[]);
page.imp().actions.set(actions).unwrap();
page.setup_widget();
page

View file

@ -14,8 +14,6 @@ use once_cell::sync::{Lazy, OnceCell};
use crate::{config, models::keyring, utils::spawn_tokio, widgets::ErrorRevealer};
mod imp {
use glib::ParamFlags;
use super::*;
#[derive(Debug, Default, CompositeTemplate)]
@ -57,18 +55,14 @@ mod imp {
impl ObjectImpl for PasswordPage {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecBoolean::new(
"has-set-password",
"",
"",
false,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
)]
vec![ParamSpecBoolean::builder("has-set-password")
.construct()
.build()]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"has-set-password" => {
let has_set_password = value.get().unwrap();
@ -78,15 +72,16 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"has-set-password" => self.has_set_password.get().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, page: &Self::Type) {
self.parent_constructed(page);
fn constructed(&self) {
self.parent_constructed();
let page = self.obj();
self.status_page.set_icon_name(Some(config::APP_ID));
page.reset_validation();
// Reset the validation whenever the password state changes
@ -97,9 +92,9 @@ mod imp {
}
impl WidgetImpl for PasswordPage {
fn unmap(&self, widget: &Self::Type) {
self.parent_unmap(widget);
widget.reset();
fn unmap(&self) {
self.parent_unmap();
self.obj().reset();
}
}
@ -114,7 +109,7 @@ glib::wrapper! {
#[gtk::template_callbacks]
impl PasswordPage {
pub fn new(actions: gio::SimpleActionGroup) -> Self {
let page = glib::Object::new::<Self>(&[]).expect("Failed to create PasswordPage");
let page = glib::Object::new::<Self>(&[]);
page.imp().actions.set(actions).unwrap();
page.setup_actions();
page

View file

@ -24,7 +24,7 @@ mod imp {
use adw::subclass::{preferences_window::PreferencesWindowImpl, window::AdwWindowImpl};
use glib::{
subclass::{self, Signal},
ParamFlags, ParamSpec, ParamSpecBoolean, Value,
ParamSpec, ParamSpecBoolean, Value,
};
use once_cell::sync::Lazy;
@ -99,29 +99,20 @@ mod imp {
impl ObjectImpl for PreferencesWindow {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecBoolean::new(
"has-set-password",
"",
"",
false,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
)]
vec![ParamSpecBoolean::builder("has-set-password")
.construct()
.build()]
});
PROPERTIES.as_ref()
}
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder("restore-completed", &[], <()>::static_type().into())
.action()
.build(),
]
});
static SIGNALS: Lazy<Vec<Signal>> =
Lazy::new(|| vec![Signal::builder("restore-completed").action().build()]);
SIGNALS.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"has-set-password" => {
let has_set_password = value.get().unwrap();
@ -131,16 +122,16 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"has-set-password" => self.has_set_password.get().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.setup_actions();
fn constructed(&self) {
self.parent_constructed();
self.obj().setup_actions();
}
}
impl WidgetImpl for PreferencesWindow {}
@ -156,7 +147,7 @@ glib::wrapper! {
impl PreferencesWindow {
pub fn new(model: ProvidersModel) -> Self {
let window = glib::Object::new::<Self>(&[]).expect("Failed to create PreferencesWindow");
let window = glib::Object::new::<Self>(&[]);
window.imp().model.set(model).unwrap();
window.setup_widget();
window

View file

@ -37,28 +37,29 @@ pub(crate) mod imp {
PROPERTIES.as_ref()
}
fn property(&self, obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"progress" => obj.progress().to_value(),
"progress" => self.obj().progress().to_value(),
_ => unreachable!(),
}
}
fn set_property(&self, obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"progress" => obj.set_progress(value.get().unwrap()),
"progress" => self.obj().set_progress(value.get().unwrap()),
_ => unreachable!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.set_valign(gtk::Align::Center);
fn constructed(&self) {
self.parent_constructed();
self.obj().set_valign(gtk::Align::Center);
}
}
impl WidgetImpl for ProgressIcon {
fn snapshot(&self, widget: &Self::Type, snapshot: &gtk::Snapshot) {
fn snapshot(&self, snapshot: &gtk::Snapshot) {
let widget = self.obj();
let size = widget.size() as f32;
let radius = size / 2.0;
let progress = 1.0 - widget.progress();
@ -82,13 +83,9 @@ pub(crate) mod imp {
snapshot.pop();
}
fn measure(
&self,
widget: &Self::Type,
_orientation: gtk::Orientation,
_for_size: i32,
) -> (i32, i32, i32, i32) {
(widget.size(), widget.size(), -1, -1)
fn measure(&self, _orientation: gtk::Orientation, _for_size: i32) -> (i32, i32, i32, i32) {
let size = self.obj().size();
(size, size, -1, -1)
}
}
}

View file

@ -1,7 +1,7 @@
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use glib::clone;
use gtk::{glib, pango, subclass::prelude::*, CompositeTemplate};
use gtk::{glib, pango, CompositeTemplate};
use row::ProviderActionRow;
use super::ProviderPage;
@ -78,13 +78,12 @@ mod imp {
impl ObjectImpl for ProvidersDialog {
fn signals() -> &'static [Signal] {
use once_cell::sync::Lazy;
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![Signal::builder("changed", &[], <()>::static_type().into()).build()]
});
static SIGNALS: Lazy<Vec<Signal>> =
Lazy::new(|| vec![Signal::builder("changed").build()]);
SIGNALS.as_ref()
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
self.placeholder_page.set_icon_name(Some(config::APP_ID));
}
}
@ -100,8 +99,7 @@ glib::wrapper! {
#[gtk::template_callbacks]
impl ProvidersDialog {
pub fn new(model: ProvidersModel) -> Self {
let dialog =
glib::Object::new::<ProvidersDialog>(&[]).expect("Failed to create ProvidersDialog");
let dialog = glib::Object::new::<ProvidersDialog>(&[]);
dialog.setup_widget(model);
dialog
@ -279,7 +277,7 @@ mod row {
mod imp {
use std::cell::RefCell;
use glib::{ParamFlags, ParamSpec, ParamSpecObject, Value};
use glib::{ParamSpec, ParamSpecObject, Value};
use once_cell::sync::Lazy;
use super::*;
@ -299,25 +297,12 @@ mod row {
impl ObjectImpl for ProviderActionRow {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecObject::new(
"provider",
"",
"",
Provider::static_type(),
ParamFlags::READWRITE,
)]
});
static PROPERTIES: Lazy<Vec<ParamSpec>> =
Lazy::new(|| vec![ParamSpecObject::builder::<Provider>("provider").build()]);
PROPERTIES.as_ref()
}
fn set_property(
&self,
_obj: &Self::Type,
_id: usize,
value: &Value,
pspec: &ParamSpec,
) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"provider" => {
let provider = value.get().unwrap();
@ -327,15 +312,15 @@ mod row {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"provider" => self.provider.borrow().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
let hbox = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.margin_bottom(12)
@ -348,7 +333,7 @@ mod row {
self.title_label.set_wrap(true);
self.title_label.set_ellipsize(pango::EllipsizeMode::End);
hbox.append(&self.title_label);
obj.set_child(Some(&hbox));
self.obj().set_child(Some(&hbox));
}
}
impl WidgetImpl for ProviderActionRow {}
@ -373,7 +358,7 @@ mod row {
impl Default for ProviderActionRow {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create ProviderActionRow")
glib::Object::new(&[])
}
}
}

View file

@ -67,21 +67,15 @@ mod imp {
}
impl ObjectImpl for ProviderImage {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.setup_widget();
fn constructed(&self) {
self.parent_constructed();
self.obj().setup_widget();
}
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![
ParamSpecObject::new(
"provider",
"",
"",
Provider::static_type(),
ParamFlags::READWRITE,
),
ParamSpecObject::builder::<Provider>("provider").build(),
ParamSpecUInt::new(
"size",
"",
@ -95,7 +89,7 @@ mod imp {
});
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"provider" => {
let provider = value.get().unwrap();
@ -109,7 +103,7 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"provider" => self.provider.borrow().to_value(),
"size" => self.size.get().to_value(),

View file

@ -44,21 +44,18 @@ mod imp {
}
impl ObjectImpl for ProvidersList {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.setup_widget();
fn constructed(&self) {
self.parent_constructed();
self.obj().setup_widget();
}
fn signals() -> &'static [Signal] {
use once_cell::sync::Lazy;
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![Signal::builder(
"shared",
&[Account::static_type().into()],
<()>::static_type().into(),
)
.action()
.build()]
vec![Signal::builder("shared")
.param_types([Account::static_type()])
.action()
.build()]
});
SIGNALS.as_ref()
}

View file

@ -134,35 +134,26 @@ mod imp {
use once_cell::sync::Lazy;
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder(
"created",
&[Provider::static_type().into()],
<()>::static_type().into(),
)
.build(),
Signal::builder(
"updated",
&[Provider::static_type().into()],
<()>::static_type().into(),
)
.build(),
Signal::builder(
"deleted",
&[Provider::static_type().into()],
<()>::static_type().into(),
)
.build(),
Signal::builder("created")
.param_types([Provider::static_type()])
.build(),
Signal::builder("updated")
.param_types([Provider::static_type()])
.build(),
Signal::builder("deleted")
.param_types([Provider::static_type()])
.build(),
]
});
SIGNALS.as_ref()
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
self.algorithm_comborow
.set_model(Some(&self.algorithms_model));
self.method_comborow.set_model(Some(&self.methods_model));
obj.action_set_enabled("providers.save", false);
self.obj().action_set_enabled("providers.save", false);
}
}
impl WidgetImpl for ProviderPage {}
@ -431,6 +422,6 @@ impl ProviderPage {
impl Default for ProviderPage {
fn default() -> Self {
glib::Object::new(&[]).expect("Failed to create ProviderPage")
glib::Object::new(&[])
}
}

View file

@ -13,7 +13,7 @@ mod imp {
use glib::{
subclass::{self, Signal},
ParamFlags, ParamSpec, ParamSpecObject, Value,
ParamSpec, ParamSpecObject, Value,
};
use once_cell::sync::Lazy;
@ -51,13 +51,9 @@ mod imp {
impl ObjectImpl for ProviderRow {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecObject::new(
"provider",
"",
"",
Provider::static_type(),
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
)]
vec![ParamSpecObject::builder::<Provider>("provider")
.construct_only()
.build()]
});
PROPERTIES.as_ref()
}
@ -65,22 +61,17 @@ mod imp {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder("changed", &[], <()>::static_type().into())
Signal::builder("changed").action().build(),
Signal::builder("shared")
.param_types([Account::static_type()])
.action()
.build(),
Signal::builder(
"shared",
&[Account::static_type().into()],
<()>::static_type().into(),
)
.action()
.build(),
]
});
SIGNALS.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"provider" => {
let provider = value.get().unwrap();
@ -90,16 +81,16 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"provider" => self.provider.borrow().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
obj.setup_widget();
fn constructed(&self) {
self.parent_constructed();
self.obj().setup_widget();
}
}
impl WidgetImpl for ProviderRow {}
@ -113,7 +104,7 @@ glib::wrapper! {
impl ProviderRow {
pub fn new(provider: Provider) -> Self {
glib::Object::new(&[("provider", &provider)]).expect("Failed to create ProviderRow")
glib::Object::new(&[("provider", &provider)])
}
pub fn connect_changed<F>(&self, callback: F) -> glib::SignalHandlerId

View file

@ -1,12 +1,14 @@
use adw::prelude::*;
use glib::{clone, ToValue};
use gtk::{glib, subclass::prelude::*};
use gtk::{
glib::{self, clone},
subclass::prelude::*,
};
mod imp {
use std::cell::RefCell;
use adw::subclass::prelude::*;
use glib::{ParamFlags, ParamSpec, ParamSpecString, Value};
use glib::{ParamSpec, ParamSpecString, Value};
use once_cell::sync::Lazy;
use super::*;
@ -25,19 +27,12 @@ mod imp {
impl ObjectImpl for UrlRow {
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ParamSpecString::new(
"uri",
"",
"",
None,
ParamFlags::READWRITE,
)]
});
static PROPERTIES: Lazy<Vec<ParamSpec>> =
Lazy::new(|| vec![ParamSpecString::builder("uri").build()]);
PROPERTIES.as_ref()
}
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) {
fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() {
"uri" => {
let uri = value.get().unwrap();
@ -47,15 +42,16 @@ mod imp {
}
}
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value {
fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() {
"uri" => self.uri.borrow().to_value(),
_ => unimplemented!(),
}
}
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
let gesture = gtk::GestureClick::new();
gesture.connect_pressed(clone!(@weak obj as row => move |_,_,_,_| {
if let Some(ref uri) = *row.imp().uri.borrow() {

View file

@ -105,18 +105,18 @@ mod imp {
impl ObjectImpl for Window {}
impl WidgetImpl for Window {}
impl WindowImpl for Window {
fn enable_debugging(&self, window: &Self::Type, toggle: bool) -> bool {
fn enable_debugging(&self, toggle: bool) -> bool {
if config::PROFILE != "Devel" {
tracing::warn!("Inspector is disabled for non development builds");
false
} else {
self.parent_enable_debugging(window, toggle)
self.parent_enable_debugging(toggle)
}
}
fn close_request(&self, window: &Self::Type) -> Inhibit {
self.parent_close_request(window);
if let Err(err) = window.save_window_state() {
fn close_request(&self) -> Inhibit {
self.parent_close_request();
if let Err(err) = self.obj().save_window_state() {
tracing::warn!("Failed to save window state {:#?}", err);
}
Inhibit(false)
@ -136,7 +136,7 @@ glib::wrapper! {
#[gtk::template_callbacks]
impl Window {
pub fn new(model: ProvidersModel, app: &Application) -> Self {
let window = glib::Object::new::<Window>(&[("application", app)]).unwrap();
let window = glib::Object::new::<Window>(&[("application", app)]);
app.add_window(&window);
if config::PROFILE == "Devel" {