summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Hakulinen <ville.hakulinen@gmail.com>2019-08-08 20:01:06 +0300
committerVille Hakulinen <ville.hakulinen@gmail.com>2019-08-08 20:01:06 +0300
commite69c1f9b446d1c1cd2ff36a65ef4593ed5b19d6c (patch)
tree8fcd7972e4a5d7643655bd4828f524a5f91006df
parent6e62b64699994be30522926c0c861ac541d49e08 (diff)
Avoid circular reference counting with weak refs
-rw-r--r--src/ui/cmdline.rs34
-rw-r--r--src/ui/cursor_tooltip.rs24
-rw-r--r--src/ui/mod.rs17
-rw-r--r--src/ui/popupmenu/popupmenu.rs8
-rw-r--r--src/ui/wildmenu.rs4
5 files changed, 59 insertions, 28 deletions
diff --git a/src/ui/cmdline.rs b/src/ui/cmdline.rs
index d8368a1..75c43e1 100644
--- a/src/ui/cmdline.rs
+++ b/src/ui/cmdline.rs
@@ -40,22 +40,26 @@ impl CmdlineBlock {
scrolledwindow.add(&textview);
frame.add(&scrolledwindow);
- textview.connect_size_allocate(clone!(scrolledwindow => move |tv, _| {
- let h = tv.get_preferred_height();
-
- if h.1 > 250 {
- if scrolledwindow.get_size_request().1 == -1 {
- scrolledwindow.set_size_request(-1, h.1);
- scrolledwindow.set_policy(
- gtk::PolicyType::Automatic,
- gtk::PolicyType::Automatic,
- );
+ let scrolledwindow_weak = scrolledwindow.downgrade();
+ textview.connect_size_allocate(
+ clone!(scrolledwindow_weak => move |tv, _| {
+ let scrolledwindow = upgrade_weak!(scrolledwindow_weak);
+ let h = tv.get_preferred_height();
+
+ if h.1 > 250 {
+ if scrolledwindow.get_size_request().1 == -1 {
+ scrolledwindow.set_size_request(-1, h.1);
+ scrolledwindow.set_policy(
+ gtk::PolicyType::Automatic,
+ gtk::PolicyType::Automatic,
+ );
+ }
+
+ let adj = scrolledwindow.get_vadjustment().unwrap();
+ adj.set_value(adj.get_upper());
}
-
- let adj = scrolledwindow.get_vadjustment().unwrap();
- adj.set_value(adj.get_upper());
- }
- }));
+ }),
+ );
add_css_provider!(&css_provider, textview, scrolledwindow, frame);
diff --git a/src/ui/cursor_tooltip.rs b/src/ui/cursor_tooltip.rs
index 36c4bbf..5d5adeb 100644
--- a/src/ui/cursor_tooltip.rs
+++ b/src/ui/cursor_tooltip.rs
@@ -113,13 +113,15 @@ impl CursorTooltip {
let state = Arc::new(ThreadGuard::new(State::default()));
+ let frame_weak = frame.downgrade();
+ let fixed_weak = fixed.downgrade();
webview.connect_load_changed(
- clone!(frame, fixed, state => move |webview, e| match e {
+ clone!(frame_weak, fixed_weak, state => move |webview, e| match e {
webkit::LoadEvent::Finished => {
webview_load_finished(
webview,
- frame.clone(),
- fixed.clone(),
+ frame_weak.clone(),
+ fixed_weak.clone(),
state.clone(),
);
}
@@ -417,12 +419,11 @@ fn set_position(
/// the size of the webview's container.
fn webview_load_finished(
webview: &webkit::WebView,
- frame: gtk::Frame,
- fixed: gtk::Fixed,
+ frame: glib::WeakRef<gtk::Frame>,
+ fixed: glib::WeakRef<gtk::Fixed>,
state: Arc<ThreadGuard<State>>,
) {
- let widgets =
- ThreadGuard::new((frame.clone(), fixed.clone(), state.clone()));
+ let widgets = ThreadGuard::new((frame, fixed, state.clone()));
let cb =
move |width: Option<f64>,
@@ -444,9 +445,14 @@ fn webview_load_finished(
let state = state.borrow();
- widgets.0.show();
+ let frame_weak = &widgets.0;
+ let fixed_weak = &widgets.1;
+ let frame = upgrade_weak!(frame_weak);
+ let fixed = upgrade_weak!(fixed_weak);
+
+ frame.show();
- set_position(&widgets.0, &widgets.1, &state, width, height);
+ set_position(&frame, &fixed, &state, width, height);
};
let webview_ref = ThreadGuard::new(webview.clone());
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
index 641250d..8b49295 100644
--- a/src/ui/mod.rs
+++ b/src/ui/mod.rs
@@ -13,7 +13,7 @@ macro_rules! add_css_provider {
}
// Make moving clones into closures more convenient.
-// Sources from https://github.com/gtk-rs/examples/blob/e17372b1c65788b022ff152fff37d392d0f31e87/src/bin/treeview.rs#L20-L36
+// Sourced from https://github.com/gtk-rs/examples/blob/e17372b1c65788b022ff152fff37d392d0f31e87/src/bin/treeview.rs#L20-L36
#[macro_export]
macro_rules! clone {
(@param _) => ( _ );
@@ -32,6 +32,21 @@ macro_rules! clone {
);
}
+// Upgrade weak reference or return.
+// Sourced from https://github.com/gtk-rs/examples/blob/e17372b1c65788b022ff152fff37d392d0f31e87/src/bin/gtktest.rs#L36-L48
+#[macro_export]
+macro_rules! upgrade_weak {
+ ($x:ident, $r:expr) => {{
+ match $x.upgrade() {
+ Some(o) => o,
+ None => return $r,
+ }
+ }};
+ ($x:ident) => {
+ upgrade_weak!($x, ())
+ };
+}
+
mod cmdline;
pub mod color;
mod common;
diff --git a/src/ui/popupmenu/popupmenu.rs b/src/ui/popupmenu/popupmenu.rs
index 642a613..08c383c 100644
--- a/src/ui/popupmenu/popupmenu.rs
+++ b/src/ui/popupmenu/popupmenu.rs
@@ -201,7 +201,9 @@ impl Popupmenu {
state.available_size = Some(*alloc);
}));
- box_.connect_size_allocate(clone!(state, layout, scrolled_info, scrolled_list => move |box_, alloc| {
+ let layout_weak = layout.downgrade();
+ box_.connect_size_allocate(clone!(state, layout_weak, scrolled_info, scrolled_list => move |box_, alloc| {
+ let layout = upgrade_weak!(layout_weak);
let state = state.borrow();
if let Some(area) = state.available_size {
@@ -434,8 +436,10 @@ impl Popupmenu {
// this signal handler here to ensure the row is in view.
// NOTE(ville): According to some IRC discussions, this
// hack wont work on GTK4. Prepare yourself!
+ let list_weak = list.downgrade();
let sig_id = item.row.connect_size_allocate(
- clone!(id, list => move |row, _| {
+ clone!(id, list_weak => move |row, _| {
+ let list = upgrade_weak!(list_weak);
ensure_row_visible(&list, &row);
let id = id.borrow_mut().take().unwrap();
diff --git a/src/ui/wildmenu.rs b/src/ui/wildmenu.rs
index 15bbfe8..03928eb 100644
--- a/src/ui/wildmenu.rs
+++ b/src/ui/wildmenu.rs
@@ -45,8 +45,10 @@ impl Wildmenu {
frame.add(&scrolledwindow);
+ let frame_weak = frame.downgrade();
// Make sure our container grows to certain height.
- list.connect_size_allocate(clone!(frame => move |list, _| {
+ list.connect_size_allocate(clone!(frame_weak => move |list, _| {
+ let frame = upgrade_weak!(frame_weak);
// Calculate height based on shown rows.
let count = list.get_children().len() as i32;
let row_height = if let Some(item) = list.get_children().get(0) {