From c19be372ace4e9659830db87fe019d211e74154a Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 25 Jul 2023 10:07:47 +0200 Subject: [PATCH] glib: Re-introduce an event propagation specific type As the semantics of ControlFlow don't match 1:1 with the event propagations See https://github.com/gtk-rs/gtk4-rs/issues/1435 --- glib/src/lib.rs | 2 +- glib/src/signal.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/glib/src/lib.rs b/glib/src/lib.rs index b4ac3c8029d3..0374fdbe1ee7 100644 --- a/glib/src/lib.rs +++ b/glib/src/lib.rs @@ -29,7 +29,7 @@ pub use self::{ }, signal::{ signal_handler_block, signal_handler_disconnect, signal_handler_unblock, - signal_stop_emission_by_name, SignalHandlerId, + signal_stop_emission_by_name, Propagation, SignalHandlerId, }, types::{ILong, Pointer, StaticType, StaticTypeExt, Type, ULong}, value::{BoxedValue, SendValue, ToSendValue, ToValue, Value}, diff --git a/glib/src/signal.rs b/glib/src/signal.rs index 0b2f14ae9213..75d986e09d93 100644 --- a/glib/src/signal.rs +++ b/glib/src/signal.rs @@ -146,3 +146,81 @@ pub fn signal_has_handler_pending( )) } } + +// rustdoc-stripper-ignore-next +/// Whether to invoke the other event handlers. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Propagation { + // Stop other handlers from being invoked for the event. + Stop, + // Propagate the event further. + Proceed, +} + +impl Propagation { + // rustdoc-stripper-ignore-next + /// Returns `true` if this is a `Stop` variant. + pub fn is_stop(&self) -> bool { + matches!(self, Self::Stop) + } + + // rustdoc-stripper-ignore-next + /// Returns `true` if this is a `Proceed` variant. + pub fn is_proceed(&self) -> bool { + matches!(self, Self::Proceed) + } +} + +impl From for Propagation { + fn from(value: bool) -> Self { + if value { + Self::Stop + } else { + Self::Proceed + } + } +} + +impl From for bool { + fn from(c: Propagation) -> Self { + match c { + Propagation::Stop => true, + Propagation::Proceed => false, + } + } +} + +#[doc(hidden)] +impl IntoGlib for Propagation { + type GlibType = ffi::gboolean; + + #[inline] + fn into_glib(self) -> ffi::gboolean { + bool::from(self).into_glib() + } +} + +#[doc(hidden)] +impl FromGlib for Propagation { + #[inline] + unsafe fn from_glib(value: ffi::gboolean) -> Self { + bool::from_glib(value).into() + } +} + +impl crate::ToValue for Propagation { + fn to_value(&self) -> crate::Value { + bool::from(*self).to_value() + } + + fn value_type(&self) -> crate::Type { + ::static_type() + } +} + +impl From for crate::Value { + #[inline] + fn from(v: Propagation) -> Self { + bool::from(v).into() + } +}