@@ -6,7 +6,7 @@ use crate::{
6
6
ffi, ActionGroup , DBusConnection , DBusInterfaceInfo , DBusMessage , DBusMethodInvocation ,
7
7
DBusSignalFlags , MenuModel ,
8
8
} ;
9
- use glib:: { prelude:: * , translate:: * } ;
9
+ use glib:: { prelude:: * , translate:: * , WeakRef } ;
10
10
11
11
pub trait DBusMethodCall : Sized {
12
12
fn parse_call (
@@ -117,9 +117,74 @@ pub struct ActionGroupExportId(NonZeroU32);
117
117
pub struct MenuModelExportId ( NonZeroU32 ) ;
118
118
#[ derive( Debug , Eq , PartialEq ) ]
119
119
pub struct FilterId ( NonZeroU32 ) ;
120
+
120
121
#[ derive( Debug , Eq , PartialEq ) ]
121
122
pub struct SignalSubscriptionId ( NonZeroU32 ) ;
122
123
124
+ // rustdoc-stripper-ignore-next
125
+ /// A strong subscription to a D-Bus signal.
126
+ ///
127
+ /// Keep a reference to a D-Bus connection to maintain a subscription on a
128
+ /// D-Bus signal even if the connection has no other strong reference.
129
+ ///
130
+ /// When dropped, unsubscribes from signal on the connection, and then drop the
131
+ /// reference on the connection. If no other strong reference on the connection
132
+ /// exists the connection is closed and destroyed.
133
+ #[ derive( Debug ) ]
134
+ pub struct SignalSubscription ( DBusConnection , Option < SignalSubscriptionId > ) ;
135
+
136
+ impl SignalSubscription {
137
+ // rustdoc-stripper-ignore-next
138
+ /// Downgrade this signal subscription to a weak one.
139
+ pub fn downgrade ( mut self ) -> WeakSignalSubscription {
140
+ WeakSignalSubscription ( self . 0 . downgrade ( ) , self . 1 . take ( ) )
141
+ }
142
+ }
143
+
144
+ impl Drop for SignalSubscription {
145
+ fn drop ( & mut self ) {
146
+ if let Some ( id) = self . 1 . take ( ) {
147
+ #[ allow( deprecated) ]
148
+ self . 0 . signal_unsubscribe ( id) ;
149
+ }
150
+ }
151
+ }
152
+
153
+ // rustdoc-stripper-ignore-next
154
+ /// A weak subscription to a D-Bus signal.
155
+ ///
156
+ /// Like [`SignalSubscription`] but hold only a weak reference to the D-Bus
157
+ /// connection the siganl is subscribed on, i.e. maintain the subscription on
158
+ /// the D-Bus signal only as long as some strong reference exists on the
159
+ /// corresponding D-Bus connection.
160
+ ///
161
+ /// When dropped, unsubscribes from signal on the connection if it still exists,
162
+ /// and then drop the reference on the connection. If no other strong reference
163
+ /// on the connection exists the connection is closed and destroyed.
164
+ #[ derive( Debug ) ]
165
+ pub struct WeakSignalSubscription ( WeakRef < DBusConnection > , Option < SignalSubscriptionId > ) ;
166
+
167
+ impl WeakSignalSubscription {
168
+ // rustdoc-stripper-ignore-next
169
+ /// Upgrade this signal subscription to a strong one.
170
+ pub fn upgrade ( mut self ) -> Option < SignalSubscription > {
171
+ self . 0
172
+ . upgrade ( )
173
+ . map ( |c| SignalSubscription ( c, self . 1 . take ( ) ) )
174
+ }
175
+ }
176
+
177
+ impl Drop for WeakSignalSubscription {
178
+ fn drop ( & mut self ) {
179
+ if let Some ( id) = self . 1 . take ( ) {
180
+ if let Some ( connection) = self . 0 . upgrade ( ) {
181
+ #[ allow( deprecated) ]
182
+ connection. signal_unsubscribe ( id) ;
183
+ }
184
+ }
185
+ }
186
+ }
187
+
123
188
// rustdoc-stripper-ignore-next
124
189
/// Build a registered DBus object, by handling different parts of DBus.
125
190
#[ must_use = "The builder must be built to be used" ]
@@ -437,8 +502,45 @@ impl DBusConnection {
437
502
}
438
503
}
439
504
505
+ // rustdoc-stripper-ignore-next
506
+ /// Subscribe to a D-Bus signal.
507
+ ///
508
+ /// See [`Self::signal_subscribe`] for arguments.
509
+ ///
510
+ /// Return a signal subscription which keeps a reference to this D-Bus
511
+ /// connection and unsubscribes from the signal when dropped.
512
+ ///
513
+ /// To avoid reference cycles you may wish to downgrade the returned
514
+ /// subscription to a weak one with [`SignalSubscription::downgrade`].
515
+ #[ must_use]
516
+ pub fn subscribe_to_signal <
517
+ P : Fn ( & DBusConnection , & str , & str , & str , & str , & glib:: Variant ) + ' static ,
518
+ > (
519
+ & self ,
520
+ sender : Option < & str > ,
521
+ interface_name : Option < & str > ,
522
+ member : Option < & str > ,
523
+ object_path : Option < & str > ,
524
+ arg0 : Option < & str > ,
525
+ flags : DBusSignalFlags ,
526
+ callback : P ,
527
+ ) -> SignalSubscription {
528
+ #[ allow( deprecated) ]
529
+ let id = self . signal_subscribe (
530
+ sender,
531
+ interface_name,
532
+ member,
533
+ object_path,
534
+ arg0,
535
+ flags,
536
+ callback,
537
+ ) ;
538
+ SignalSubscription ( self . clone ( ) , Some ( id) )
539
+ }
540
+
440
541
#[ doc( alias = "g_dbus_connection_signal_subscribe" ) ]
441
542
#[ allow( clippy:: too_many_arguments) ]
543
+ #[ deprecated( note = "Prefer subscribe_to_signal" ) ]
442
544
pub fn signal_subscribe <
443
545
P : Fn ( & DBusConnection , & str , & str , & str , & str , & glib:: Variant ) + ' static ,
444
546
> (
@@ -507,6 +609,7 @@ impl DBusConnection {
507
609
}
508
610
509
611
#[ doc( alias = "g_dbus_connection_signal_unsubscribe" ) ]
612
+ #[ deprecated( note = "Prefer subscribe_to_signal" ) ]
510
613
pub fn signal_unsubscribe ( & self , subscription_id : SignalSubscriptionId ) {
511
614
unsafe {
512
615
ffi:: g_dbus_connection_signal_unsubscribe (
0 commit comments