From d1ebbde77897db4279232d7f77ad378aa158454c Mon Sep 17 00:00:00 2001 From: Julian Hofer Date: Wed, 12 Feb 2020 16:56:18 +0100 Subject: [PATCH] Switch to glib::clone macro and fix some typos --- podcasts-gtk/src/app.rs | 6 +- podcasts-gtk/src/headerbar.rs | 50 +++--- podcasts-gtk/src/main.rs | 19 -- podcasts-gtk/src/utils.rs | 9 +- podcasts-gtk/src/widgets/base_view.rs | 2 +- podcasts-gtk/src/widgets/episode.rs | 35 ++-- podcasts-gtk/src/widgets/home_view.rs | 2 +- podcasts-gtk/src/widgets/player.rs | 239 +++++++++++++------------ podcasts-gtk/src/widgets/show.rs | 19 +- podcasts-gtk/src/widgets/show_menu.rs | 21 +-- podcasts-gtk/src/widgets/shows_view.rs | 2 +- podcasts-gtk/src/window.rs | 19 +- 12 files changed, 210 insertions(+), 213 deletions(-) diff --git a/podcasts-gtk/src/app.rs b/podcasts-gtk/src/app.rs index 5d34959..14820d1 100644 --- a/podcasts-gtk/src/app.rs +++ b/podcasts-gtk/src/app.rs @@ -19,6 +19,7 @@ #![allow(clippy::new_without_default)] +use glib::clone; use glib::subclass::prelude::*; use glib::subclass::simple::{ClassStruct, InstanceStruct}; use glib::translate::*; @@ -94,7 +95,10 @@ impl gio::subclass::prelude::ApplicationImpl for PdApplicationPrivate { window.present(); self.window.replace(Some(window)); // Setup the Action channel - gtk::timeout_add(25, clone!(app => move || app.setup_action_channel())); + gtk::timeout_add( + 25, + clone!(@strong app => move || app.setup_action_channel()), + ); } fn startup(&self, app: &gio::Application) { diff --git a/podcasts-gtk/src/headerbar.rs b/podcasts-gtk/src/headerbar.rs index 63854e1..fec02ef 100644 --- a/podcasts-gtk/src/headerbar.rs +++ b/podcasts-gtk/src/headerbar.rs @@ -18,6 +18,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use gio; +use glib::clone; use gtk; use gtk::prelude::*; use libhandy; @@ -83,7 +84,7 @@ impl AddPopover { url.to_owned() }; - rayon::spawn(clone!(sender => move || { + rayon::spawn(clone!(@strong sender => move || { if let Ok(source) = Source::from_url(&url) { schedule_refresh(Some(vec![source]), sender.clone()); } else { @@ -227,41 +228,38 @@ impl Header { } pub(crate) fn init(s: &Rc, content: &Content, sender: &Sender) { - let weak = Rc::downgrade(s); - s.bottom_switcher.set_stack(Some(&content.get_stack())); s.switch.set_stack(Some(&content.get_stack())); - s.add.entry.connect_changed(clone!(weak => move |_| { - weak.upgrade().map(|h| { - h.add.on_entry_changed() - .map_err(|err| error!("Error: {}", err)) - .ok(); - }); - })); - - s.add.add.connect_clicked(clone!(weak, sender => move |_| { - weak.upgrade().map(|h| h.add.on_add_clicked(&sender)); + s.add.entry.connect_changed(clone!(@weak s => move |_| { + s.add.on_entry_changed() + .map_err(|err| error!("Error: {}", err)) + .ok(); })); s.add - .entry - .connect_activate(clone!(weak, sender => move |_| { - weak.upgrade().map(|h| { - if h.add.add.get_sensitive() { - h.add.on_add_clicked(&sender).unwrap(); - } - }); + .add + .connect_clicked(clone!(@weak s, @strong sender => move |_| { + s.add.on_add_clicked(&sender).unwrap(); })); - s.back.connect_clicked(clone!(weak, sender => move |_| { - weak.upgrade().map(|h| h.switch_to_normal()); - sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow"); - })); + s.add + .entry + .connect_activate(clone!(@weak s, @strong sender => move |_| { + if s.add.add.get_sensitive() { + s.add.on_add_clicked(&sender).unwrap(); + } + })); + + s.back + .connect_clicked(clone!(@weak s, @strong sender => move |_| { + s.switch_to_normal(); + sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow"); + })); s.switch_squeezer - .connect_property_visible_child_notify(clone!(weak => move |_| { - weak.upgrade().map(|h| h.update_bottom_switcher()); + .connect_property_visible_child_notify(clone!(@weak s => move |_| { + s.update_bottom_switcher(); })); s.update_bottom_switcher(); } diff --git a/podcasts-gtk/src/main.rs b/podcasts-gtk/src/main.rs index 00bcbf6..dd0ae37 100644 --- a/podcasts-gtk/src/main.rs +++ b/podcasts-gtk/src/main.rs @@ -60,25 +60,6 @@ use log::Level; use gtk::prelude::*; -// https://gtk-rs.org/docs-src/tutorial/closures -#[macro_export] -macro_rules! clone { - (@param _) => ( _ ); - (@param $x:ident) => ( $x ); - ($($n:ident),+ => move || $body:expr) => ( - { - $( let $n = $n.clone(); )+ - move || $body - } - ); - ($($n:ident),+ => move |$($p:tt),+| $body:expr) => ( - { - $( let $n = $n.clone(); )+ - move |$(clone!(@param $p),)+| $body - } - ); -} - mod stacks; mod widgets; diff --git a/podcasts-gtk/src/utils.rs b/podcasts-gtk/src/utils.rs index 7efa171..0449a36 100644 --- a/podcasts-gtk/src/utils.rs +++ b/podcasts-gtk/src/utils.rs @@ -20,6 +20,7 @@ #![allow(clippy::type_complexity)] use gdk_pixbuf::Pixbuf; +use glib::clone; use glib::{self, object::WeakRef}; use glib::{IsA, Object}; use gtk; @@ -183,7 +184,7 @@ pub(crate) fn ignore_show(id: i32) -> Result { .map_err(|err| format_err!("{}", err)) } -pub(crate) fn uningore_show(id: i32) -> Result { +pub(crate) fn unignore_show(id: i32) -> Result { IGNORESHOWS .lock() .map(|mut guard| guard.remove(&id)) @@ -300,7 +301,7 @@ pub(crate) fn set_image_from_path( // If it fails another download will be scheduled. if let Ok(guard) = COVER_DL_REGISTRY.read() { if guard.contains(&show_id) { - let callback = clone!(image => move || { + let callback = clone!(@weak image => @default-return glib::Continue(false), move || { let _ = set_image_from_path(&image, show_id, size); glib::Continue(false) }); @@ -417,7 +418,7 @@ pub(crate) fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender if let Some(filename) = dialog.get_filename() { debug!("File selected: {:?}", filename); - rayon::spawn(clone!(sender => move || { + rayon::spawn(clone!(@strong sender => move || { // Parse the file and import the feeds if let Ok(sources) = opml::import_from_file(filename) { // Refresh the successfully parsed feeds to index them @@ -464,7 +465,7 @@ pub(crate) fn on_export_clicked(window: >k::ApplicationWindow, sender: &Sender if let Some(filename) = dialog.get_filename() { debug!("File selected: {:?}", filename); - rayon::spawn(clone!(sender => move || { + rayon::spawn(clone!(@strong sender => move || { if opml::export_from_db(filename, i18n("GNOME Podcasts Subscriptions").as_str()).is_err() { let text = i18n("Failed to export podcasts"); sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow"); diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs index 4cf9f50..0a98b69 100644 --- a/podcasts-gtk/src/widgets/base_view.rs +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -67,7 +67,7 @@ impl BaseView { self.scrolled_window.add(widget); } - pub(crate) fn set_adjutments<'a, 'b>( + pub(crate) fn set_adjustments<'a, 'b>( &self, hadjustment: Option<&'a Adjustment>, vadjustment: Option<&'b Adjustment>, diff --git a/podcasts-gtk/src/widgets/episode.rs b/podcasts-gtk/src/widgets/episode.rs index 7afdf59..28fb788 100644 --- a/podcasts-gtk/src/widgets/episode.rs +++ b/podcasts-gtk/src/widgets/episode.rs @@ -18,6 +18,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use glib; +use glib::clone; use gtk; use gtk::prelude::*; @@ -235,16 +236,18 @@ impl EpisodeWidget { let widget = Rc::new(Self::default()); let episode = RefCell::new(Some(episode)); let weak = Rc::downgrade(&widget); - widget.container.connect_draw(clone!(sender => move |_, _| { - episode.borrow_mut().take().map(|ep| { - weak.upgrade().map(|w| w.info.init(&ep)); - Self::determine_buttons_state(&weak, &ep, &sender) - .map_err(|err| error!("Error: {}", err)) - .ok(); - }); + widget + .container + .connect_draw(clone!(@strong sender => move |_, _| { + episode.borrow_mut().take().map(|ep| { + weak.upgrade().map(|w| w.info.init(&ep)); + Self::determine_buttons_state(&weak, &ep, &sender) + .map_err(|err| error!("Error: {}", err)) + .ok(); + }); - gtk::Inhibit(false) - })); + gtk::Inhibit(false) + })); // When the widget is attached to a parent, // since it's a rust struct and not a widget the @@ -372,7 +375,7 @@ impl EpisodeWidget { // State: InProgress if let Some(prog) = active_dl()? { // set a callback that will update the state when the download finishes - let callback = clone!(weak, sender => move || { + let callback = clone!(@strong weak, @strong sender => move || { if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() { if !guard.contains_key(&id) { if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) { @@ -393,14 +396,14 @@ impl EpisodeWidget { widget .buttons .cancel - .connect_clicked(clone!(prog, weak, sender => move |_| { + .connect_clicked(clone!(@strong prog, @strong weak, @strong sender => move |_| { // Cancel the download if let Ok(mut m) = prog.lock() { m.cancel(); } // Cancel is not instant so we have to wait a bit - timeout_add(50, clone!(weak, sender => move || { + timeout_add(50, clone!(@strong weak, @strong sender => move || { if let Ok(thing) = active_dl() { if thing.is_none() { // Recalculate the widget state @@ -441,7 +444,7 @@ impl EpisodeWidget { widget .buttons .play - .connect_clicked(clone!(weak, sender => move |_| { + .connect_clicked(clone!(@strong weak, @strong sender => move |_| { if let Ok(mut ep) = dbqueries::get_episode_widget_from_rowid(id) { on_play_bttn_clicked(&weak, &mut ep, &sender) .map_err(|err| error!("Error: {}", err)) @@ -457,7 +460,7 @@ impl EpisodeWidget { widget .buttons .download - .connect_clicked(clone!(weak, sender => move |dl| { + .connect_clicked(clone!(@strong weak, @strong sender => move |dl| { // Make the button insensitive so it won't be pressed twice dl.set_sensitive(false); if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) { @@ -528,7 +531,7 @@ fn update_progressbar_callback( prog: &Arc>, episode_rowid: i32, ) { - let callback = clone!(widget, prog => move || { + let callback = clone!(@strong widget,@strong prog => move || { progress_bar_helper(&widget, &prog, episode_rowid) .unwrap_or(glib::Continue(false)) }); @@ -602,7 +605,7 @@ fn progress_bar_helper( // relying to the RSS feed. #[inline] fn update_total_size_callback(widget: &Weak, prog: &Arc>) { - let callback = clone!(prog, widget => move || { + let callback = clone!(@strong prog, @strong widget => move || { total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true)) }); timeout_add(100, callback); diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index 2575bcb..a51b10d 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -143,7 +143,7 @@ impl HomeView { }; if let Some(ref v) = vadj { - home.view.set_adjutments(None, Some(v)) + home.view.set_adjustments(None, Some(v)) }; }; diff --git a/podcasts-gtk/src/widgets/player.rs b/podcasts-gtk/src/widgets/player.rs index 4a18d68..ddbcf0a 100644 --- a/podcasts-gtk/src/widgets/player.rs +++ b/podcasts-gtk/src/widgets/player.rs @@ -26,6 +26,7 @@ use libhandy as hdy; use libhandy::prelude::*; use gio::{File, FileExt}; +use glib::clone; use glib::{SignalHandlerId, WeakRef}; use chrono::{prelude::*, NaiveTime}; @@ -241,17 +242,18 @@ impl PlayerRate { } fn connect_signals(&self, widget: &Rc) { - let weak = Rc::downgrade(widget); - - self.radio_normal.connect_toggled(clone!(weak => move |_| { - weak.upgrade().map(|w| w.on_rate_changed(1.00)); - })); - self.radio125.connect_toggled(clone!(weak => move |_| { - weak.upgrade().map(|w| w.on_rate_changed(1.25)); - })); - self.radio150.connect_toggled(clone!(weak => move |_| { - weak.upgrade().map(|w| w.on_rate_changed(1.50)); - })); + self.radio_normal + .connect_toggled(clone!(@weak widget => move |_| { + widget.on_rate_changed(1.00); + })); + self.radio125 + .connect_toggled(clone!(@weak widget => move |_| { + widget.on_rate_changed(1.25); + })); + self.radio150 + .connect_toggled(clone!(@weak widget => move |_| { + widget.on_rate_changed(1.50); + })); } } @@ -680,21 +682,18 @@ impl PlayerWrapper { } fn connect_dialog(&self) { - let weak = Rc::downgrade(self); - + let this = self.deref(); self.squeezer - .connect_property_visible_child_notify(clone!(weak => move |_| { - weak.upgrade().map(|w| { - if let Some(child) = w.squeezer.get_visible_child() { - let full = child == w.full; - w.timer.progress_bar.set_visible(!full); + .connect_property_visible_child_notify(clone!(@weak this => move |_| { + if let Some(child) = this.squeezer.get_visible_child() { + let full = child == this.full; + this.timer.progress_bar.set_visible(!full); if full { - w.action_bar.get_style_context().remove_class("player-small"); + this.action_bar.get_style_context().remove_class("player-small"); } else { - w.action_bar.get_style_context().add_class("player-small"); + this.action_bar.get_style_context().add_class("player-small"); } } - }); })); self.timer @@ -711,103 +710,110 @@ impl PlayerWrapper { .slider .set_adjustment(&self.timer.slider.get_adjustment()); - self.evbox - .connect_button_press_event(clone!(weak => move |_, event| { + self.evbox.connect_button_press_event( + clone!(@weak this => @default-return Inhibit(false), move |_, event| { if event.get_button() != 1 { return Inhibit(false); } - - if let Some(w) = weak.upgrade() { - // only open the dialog when the small toolbar is visible - if let Some(child) = w.squeezer.get_visible_child() { - if child == w.full { - return Inhibit(false); - } + // only open the dialog when the small toolbar is visible + if let Some(child) = this.squeezer.get_visible_child() { + if child == this.full { + return Inhibit(false); } - - let parent = w.container.get_toplevel().and_then(|toplevel| { - toplevel - .downcast::() - .ok() - }).unwrap(); - - info!("showing dialog"); - w.dialog.dialog.set_transient_for(Some(&parent)); - w.dialog.dialog.show(); } - Inhibit(false) - })); + let parent = this.container.get_toplevel().and_then(|toplevel| { + toplevel + .downcast::() + .ok() + }).unwrap(); - self.dialog.close.connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|w| w.dialog.dialog.hide()); - })); + info!("showing dialog"); + this.dialog.dialog.set_transient_for(Some(&parent)); + this.dialog.dialog.show(); + + Inhibit(false) + }), + ); + + self.dialog + .close + .connect_clicked(clone!(@weak this => move |_| { + this.dialog.dialog.hide(); + })); } /// Connect the `PlayerControls` buttons to the `PlayerExt` methods. fn connect_control_buttons(&self) { - let weak = Rc::downgrade(self); - + let this = self.deref(); // Connect the play button to the gst Player. - self.controls.play.connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.play()); - })); + self.controls + .play + .connect_clicked(clone!(@weak this => move |_| { + this.play(); + })); // Connect the pause button to the gst Player. self.controls .pause - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.pause()); + .connect_clicked(clone!(@weak this => move |_| { + this.pause(); })); // Connect the play button to the gst Player. self.controls .play_small - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.play()); + .connect_clicked(clone!(@weak this => move |_| { + this.play(); })); // Connect the pause button to the gst Player. self.controls .pause_small - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.pause()); + .connect_clicked(clone!(@weak this => move |_| { + this.pause(); })); // Connect the rewind button to the gst Player. self.controls .rewind - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.rewind()); + .connect_clicked(clone!(@weak this => move |_| { + this.rewind(); })); // Connect the fast-forward button to the gst Player. self.controls .forward - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.fast_forward()); + .connect_clicked(clone!(@weak this => move |_| { + this.fast_forward(); })); // Connect the play button to the gst Player. - self.dialog.play.connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.play()); - })); + self.dialog + .play + .connect_clicked(clone!(@weak this => move |_| { + this.play(); + })); // Connect the pause button to the gst Player. - self.dialog.pause.connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.pause()); - })); + self.dialog + .pause + .connect_clicked(clone!(@weak this => move |_| { + this.pause(); + })); // Connect the rewind button to the gst Player. - self.dialog.rewind.connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.rewind()); - })); + self.dialog + .rewind + .connect_clicked(clone!(@weak this => move |_| { + this.rewind(); + })); // Connect the fast-forward button to the gst Player. self.dialog .forward - .connect_clicked(clone!(weak => move |_| { - weak.upgrade().map(|p| p.fast_forward()); + .connect_clicked(clone!(@weak this => move |_| { + this.fast_forward(); })); } @@ -817,7 +823,7 @@ impl PlayerWrapper { self.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn)); // Log gst errors. - self.player.connect_error(clone!(sender => move |_, _error| { + self.player.connect_error(clone!(@strong sender => move |_, _error| { // sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); let s = i18n("The media player was unable to execute an action."); sender.send(Action::ErrorNotification(s)).expect("Action channel blew up somehow"); @@ -827,21 +833,21 @@ impl PlayerWrapper { let weak = Fragile::new(Rc::downgrade(self)); // Update the duration label and the slider - self.player.connect_duration_changed(clone!(weak => move |_, clock| { + self.player.connect_duration_changed(clone!(@strong weak => move |_, clock| { weak.get() .upgrade() .map(|p| p.timer.on_duration_changed(Duration(clock))); })); // Update the position label and the slider - self.player.connect_position_updated(clone!(weak => move |_, clock| { + self.player.connect_position_updated(clone!(@strong weak => move |_, clock| { weak.get() .upgrade() .map(|p| p.timer.on_position_updated(Position(clock))); })); // Reset the slider to 0 and show a play button - self.player.connect_end_of_stream(clone!(weak => move |_| { + self.player.connect_end_of_stream(clone!(@strong weak => move |_| { weak.get() .upgrade() .map(|p| p.stop()); @@ -859,49 +865,60 @@ impl PlayerWrapper { // FIXME: Reference cycle with mpris let mpris = self.info.mpris.clone(); - self.info.mpris.connect_play_pause(clone!(weak => move || { - let player = match weak.upgrade() { - Some(s) => s, - None => return - }; - - if let Ok(status) = mpris.get_playback_status() { - match status.as_ref() { - "Paused" => player.play(), - "Stopped" => player.play(), - _ => player.pause(), + self.info + .mpris + .connect_play_pause(clone!(@strong weak => move || { + let player = match weak.upgrade() { + Some(s) => s, + None => return }; - } - })); - self.info.mpris.connect_play(clone!(weak => move || { - let player = match weak.upgrade() { - Some(s) => s, - None => return - }; + if let Ok(status) = mpris.get_playback_status() { + match status.as_ref() { + "Paused" => player.play(), + "Stopped" => player.play(), + _ => player.pause(), + }; + } + })); + self.info + .mpris + .connect_play(clone!(@strong weak => move || { + let player = match weak.upgrade() { + Some(s) => s, + None => return + }; - player.play(); - })); + player.play(); + })); - self.info.mpris.connect_pause(clone!(weak => move || { - let player = match weak.upgrade() { - Some(s) => s, - None => return - }; + self.info + .mpris + .connect_pause(clone!(@strong weak => move || { + let player = match weak.upgrade() { + Some(s) => s, + None => return + }; - player.pause(); - })); + player.pause(); + })); - self.info.mpris.connect_next(clone!(weak => move || { - weak.upgrade().map(|p| p.fast_forward()); - })); + self.info + .mpris + .connect_next(clone!(@strong weak => move || { + weak.upgrade().map(|p| p.fast_forward()); + })); - self.info.mpris.connect_previous(clone!(weak => move || { - weak.upgrade().map(|p| p.rewind()); - })); + self.info + .mpris + .connect_previous(clone!(@strong weak => move || { + weak.upgrade().map(|p| p.rewind()); + })); - self.info.mpris.connect_raise(clone!(sender => move || { - sender.send(Action::RaiseWindow).expect("Action channel blew up somehow"); - })); + self.info + .mpris + .connect_raise(clone!(@strong sender => move || { + sender.send(Action::RaiseWindow).expect("Action channel blew up somehow"); + })); } } diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 95f1f72..24274bd 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -18,6 +18,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use glib; +use glib::clone; use gtk::{self, prelude::*, Adjustment}; use crossbeam_channel::{bounded, Sender}; @@ -108,16 +109,14 @@ impl ShowWidget { let res = populate_listbox(&pdw, pd.clone(), sender, vadj); debug_assert!(res.is_ok()); - let weak = Rc::downgrade(&pdw); pdw.description_short - .connect_size_allocate(clone!(weak => move |_, _2| { - weak.upgrade().map(|w| w.update_read_more()); + .connect_size_allocate(clone!(@weak pdw => move |_, _2| { + pdw.update_read_more(); })); pdw.description_button - .connect_clicked(clone!(weak => move |_| { - weak.upgrade() - .map(|w| w.description_stack.set_visible_child_name("full")); + .connect_clicked(clone!(@weak pdw => move |_| { + pdw.description_stack.set_visible_child_name("full"); })); pdw @@ -180,7 +179,7 @@ fn populate_listbox( let count = dbqueries::get_pd_episodes_count(&pd)?; let (sender_, receiver) = bounded(1); - rayon::spawn(clone!(pd => move || { + rayon::spawn(clone!(@strong pd => move || { if let Ok(episodes) = dbqueries::get_pd_episodeswidgets(&pd) { // The receiver can be dropped if there's an early return // like on show without episodes for example. @@ -205,13 +204,13 @@ fn populate_listbox( debug_assert!(episodes.len() as i64 == count); - let constructor = clone!(sender => move |ep| { + let constructor = clone!(@strong sender => move |ep| { EpisodeWidget::new(ep, &sender).container.clone() }); - let callback = clone!(show_weak, vadj => move || { + let callback = clone!(@strong show_weak, @strong vadj => move || { match (show_weak.upgrade(), &vadj) { - (Some(ref shows), Some(ref v)) => shows.view.set_adjutments(None, Some(v)), + (Some(ref shows), Some(ref v)) => shows.view.set_adjustments(None, Some(v)), _ => (), }; }); diff --git a/podcasts-gtk/src/widgets/show_menu.rs b/podcasts-gtk/src/widgets/show_menu.rs index 80e5753..70f290e 100644 --- a/podcasts-gtk/src/widgets/show_menu.rs +++ b/podcasts-gtk/src/widgets/show_menu.rs @@ -18,6 +18,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use glib; +use glib::clone; use gtk; use gtk::prelude::*; @@ -78,7 +79,7 @@ impl ShowMenu { fn connect_website(&self, pd: &Arc) { self.website.set_tooltip_text(Some(pd.link())); - self.website.connect_clicked(clone!(pd => move |_| { + self.website.connect_clicked(clone!(@strong pd => move |_| { let link = pd.link(); info!("Opening link: {}", link); let res = open::that(link); @@ -87,13 +88,7 @@ impl ShowMenu { } fn connect_played(&self, pd: &Arc, episodes: >k::ListBox, sender: &Sender) { - let episodes_weak = episodes.downgrade(); - self.played.connect_clicked(clone!(pd, sender => move |_| { - let episodes = match episodes_weak.upgrade() { - Some(e) => e, - None => return, - }; - + self.played.connect_clicked(clone!(@strong pd, @strong sender, @weak episodes => move |_| { let res = dim_titles(&episodes); debug_assert!(res.is_some()); @@ -103,7 +98,7 @@ impl ShowMenu { fn connect_unsub(&self, pd: &Arc, sender: &Sender) { self.unsub - .connect_clicked(clone!(pd, sender => move |unsub| { + .connect_clicked(clone!(@strong pd, @strong sender => move |unsub| { // hack to get away without properly checking for none. // if pressed twice would panic. unsub.set_sensitive(false); @@ -173,7 +168,7 @@ pub(crate) fn mark_all_notif(pd: Arc, sender: &Sender) -> InAppNot glib::Continue(false) }; - let undo_callback = clone!(sender => move || { + let undo_callback = clone!(@strong sender => move || { sender.send(Action::RefreshWidgetIfSame(id)).expect("Action channel blew up somehow") }); let text = i18n("Marked all episodes as listened"); @@ -189,11 +184,11 @@ pub(crate) fn remove_show_notif(pd: Arc, sender: Sender) -> InAppN let sender_ = sender.clone(); let pd_ = pd.clone(); let callback = move |revealer: gtk::Revealer| { - let res = utils::uningore_show(pd_.id()); + let res = utils::unignore_show(pd_.id()); debug_assert!(res.is_ok()); // Spawn a thread so it won't block the ui. - rayon::spawn(clone!(pd_, sender_ => move || { + rayon::spawn(clone!(@strong pd_, @strong sender_ => move || { delete_show(&pd_) .map_err(|err| error!("Error: {}", err)) .map_err(|_| error!("Failed to delete {}", pd_.title())) @@ -207,7 +202,7 @@ pub(crate) fn remove_show_notif(pd: Arc, sender: Sender) -> InAppN }; let undo_callback = move || { - let res = utils::uningore_show(pd.id()); + let res = utils::unignore_show(pd.id()); debug_assert!(res.is_ok()); sender .send(Action::RefreshShowsView) diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index 97c108e..868ef81 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -89,7 +89,7 @@ fn populate_flowbox(shows: &Rc, vadj: Option) -> Result<( let constructor = move |parent| ShowsChild::new(&parent).child; let callback = move || { match (show_weak.upgrade(), &vadj) { - (Some(ref shows), Some(ref v)) => shows.view.set_adjutments(None, Some(v)), + (Some(ref shows), Some(ref v)) => shows.view.set_adjustments(None, Some(v)), _ => (), }; }; diff --git a/podcasts-gtk/src/window.rs b/podcasts-gtk/src/window.rs index 98eb2a0..c1383d4 100644 --- a/podcasts-gtk/src/window.rs +++ b/podcasts-gtk/src/window.rs @@ -18,6 +18,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use glib; +use glib::clone; use glib::Variant; use gio::{self, prelude::*, ActionMapExt, SettingsExt}; @@ -172,13 +173,11 @@ impl MainWindow { #[cfg_attr(rustfmt, rustfmt_skip)] pub fn setup_gactions(&self) { let sender = &self.sender; - let weak_win = self.window.downgrade(); - // Create the `refresh` action. // // This will trigger a refresh of all the shows in the database. - action(&self.window, "refresh", clone!(sender => move |_, _| { - gtk::idle_add(clone!(sender => move || { + action(&self.window, "refresh", clone!(@strong sender => move |_, _| { + gtk::idle_add(clone!(@strong sender => move || { let s: Option> = None; utils::schedule_refresh(s, sender.clone()); glib::Continue(false) @@ -187,17 +186,17 @@ impl MainWindow { self.app.set_accels_for_action("win.refresh", &["r"]); // Create the `OPML` import action - action(&self.window, "import", clone!(sender, weak_win => move |_, _| { - weak_win.upgrade().map(|win| utils::on_import_clicked(&win, &sender)); + action(&self.window, "import", clone!(@strong sender, @weak self.window as win => move |_, _| { + utils::on_import_clicked(&win, &sender); })); - action(&self.window, "export", clone!(sender, weak_win => move |_, _| { - weak_win.upgrade().map(|win| utils::on_export_clicked(&win, &sender)); + action(&self.window, "export", clone!(@strong sender, @weak self.window as win => move |_, _| { + utils::on_export_clicked(&win, &sender); })); // Create the action that shows a `gtk::AboutDialog` - action(&self.window, "about", clone!(weak_win => move |_, _| { - weak_win.upgrade().map(|win| about_dialog(&win)); + action(&self.window, "about", clone!(@weak self.window as win => move |_, _| { + about_dialog(&win); })); // Create the quit action