From 52e14d8263c914a490a727fd23f856b22ff7b2e3 Mon Sep 17 00:00:00 2001 From: Yury Ankudinov Date: Thu, 26 May 2022 10:45:47 +0200 Subject: [PATCH] Fix/signal disconnect (#445) Co-authored-by: elkowar <5300871+elkowar@users.noreply.github.com> --- crates/eww/src/widgets/widget_definitions.rs | 31 +++++++------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index f3e89e9..42ab0b6 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -11,11 +11,10 @@ use anyhow::{anyhow, Context, Result}; use codespan_reporting::diagnostic::Severity; use eww_shared_util::Spanned; use gdk::{ModifierType, NotifyType}; -use glib::signal::SignalHandlerId; +use glib::translate::FromGlib; use gtk::{self, glib, prelude::*, DestDefaults, TargetEntry, TargetList}; use itertools::Itertools; use once_cell::sync::Lazy; -use std::hash::Hasher; use std::{ cell::RefCell, @@ -38,24 +37,16 @@ use yuck::{ /// thus not connecting a new handler unless the condition is met. macro_rules! connect_signal_handler { ($widget:ident, if $cond:expr, $connect_expr:expr) => {{ - // static hashmap of widget hashes to signal handler ids. - // For each use of connect_signal_handler (which represents a specific widget-type and a specific attribute), - // we need to remember the handlers of all actual widget instances that use this field. - // We can't go by instance by just using a static, and we can't really go by field/attribute without static -- so we do both. - static ID: Lazy>> = Lazy::new(|| std::sync::Mutex::new(HashMap::new())); - let widget_hash = { - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - std::hash::Hash::hash(&$widget, &mut hasher); - hasher.finish() - }; - let old = if $cond { - let new_id = $connect_expr; - ID.lock().unwrap().insert(widget_hash, new_id) - } else { - ID.lock().unwrap().remove(&widget_hash) - }; - if let Some(old) = old { - $widget.disconnect(old); + unsafe { + let key = ::std::concat!("signal-handler:", ::std::line!()); + let old = $widget.data::(key); + + if let Some(old) = old { + let a = old.as_ref().as_raw(); + $widget.disconnect(gtk::glib::SignalHandlerId::from_glib(a)); + } + + $widget.set_data::(key, $connect_expr); } }}; ($widget:ident, $connect_expr:expr) => {{