Fix/signal disconnect (#445)

Co-authored-by: elkowar <5300871+elkowar@users.noreply.github.com>
This commit is contained in:
Yury Ankudinov 2022-05-26 10:45:47 +02:00 committed by GitHub
parent 92e389130f
commit 52e14d8263
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,11 +11,10 @@ use anyhow::{anyhow, Context, Result};
use codespan_reporting::diagnostic::Severity; use codespan_reporting::diagnostic::Severity;
use eww_shared_util::Spanned; use eww_shared_util::Spanned;
use gdk::{ModifierType, NotifyType}; use gdk::{ModifierType, NotifyType};
use glib::signal::SignalHandlerId; use glib::translate::FromGlib;
use gtk::{self, glib, prelude::*, DestDefaults, TargetEntry, TargetList}; use gtk::{self, glib, prelude::*, DestDefaults, TargetEntry, TargetList};
use itertools::Itertools; use itertools::Itertools;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::hash::Hasher;
use std::{ use std::{
cell::RefCell, cell::RefCell,
@ -38,24 +37,16 @@ use yuck::{
/// thus not connecting a new handler unless the condition is met. /// thus not connecting a new handler unless the condition is met.
macro_rules! connect_signal_handler { macro_rules! connect_signal_handler {
($widget:ident, if $cond:expr, $connect_expr:expr) => {{ ($widget:ident, if $cond:expr, $connect_expr:expr) => {{
// static hashmap of widget hashes to signal handler ids. unsafe {
// For each use of connect_signal_handler (which represents a specific widget-type and a specific attribute), let key = ::std::concat!("signal-handler:", ::std::line!());
// we need to remember the handlers of all actual widget instances that use this field. let old = $widget.data::<gtk::glib::SignalHandlerId>(key);
// 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<std::sync::Mutex<HashMap<u64, SignalHandlerId>>> = Lazy::new(|| std::sync::Mutex::new(HashMap::new())); if let Some(old) = old {
let widget_hash = { let a = old.as_ref().as_raw();
let mut hasher = std::collections::hash_map::DefaultHasher::new(); $widget.disconnect(gtk::glib::SignalHandlerId::from_glib(a));
std::hash::Hash::hash(&$widget, &mut hasher); }
hasher.finish()
}; $widget.set_data::<gtk::glib::SignalHandlerId>(key, $connect_expr);
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);
} }
}}; }};
($widget:ident, $connect_expr:expr) => {{ ($widget:ident, $connect_expr:expr) => {{