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