gio/subclass/
action_group.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{mem, ptr, sync::OnceLock};
4
5use glib::{prelude::*, subclass::prelude::*, translate::*, GString, Quark, Variant, VariantType};
6
7use crate::{ffi, ActionGroup};
8
9pub trait ActionGroupImpl: ObjectImpl + ObjectSubclass<Type: IsA<ActionGroup>> {
10    fn action_added(&self, action_name: &str) {
11        self.parent_action_added(action_name);
12    }
13
14    fn action_enabled_changed(&self, action_name: &str, enabled: bool) {
15        self.parent_action_enabled_changed(action_name, enabled);
16    }
17
18    fn action_removed(&self, action_name: &str) {
19        self.parent_action_removed(action_name);
20    }
21
22    fn action_state_changed(&self, action_name: &str, state: &Variant) {
23        self.parent_action_state_changed(action_name, state);
24    }
25
26    fn activate_action(&self, action_name: &str, parameter: Option<&Variant>) {
27        self.parent_activate_action(action_name, parameter);
28    }
29
30    fn change_action_state(&self, action_name: &str, value: &Variant) {
31        self.parent_change_action_state(action_name, value)
32    }
33
34    #[doc(alias = "get_action_enabled")]
35    fn action_is_enabled(&self, action_name: &str) -> bool {
36        self.parent_action_is_enabled(action_name)
37    }
38
39    #[doc(alias = "get_action_parameter_type")]
40    fn action_parameter_type(&self, action_name: &str) -> Option<VariantType> {
41        self.parent_action_parameter_type(action_name)
42    }
43
44    #[doc(alias = "get_action_state")]
45    fn action_state(&self, action_name: &str) -> Option<Variant> {
46        self.parent_action_state(action_name)
47    }
48
49    #[doc(alias = "get_action_state_hint")]
50    fn action_state_hint(&self, action_name: &str) -> Option<Variant> {
51        self.parent_action_state_hint(action_name)
52    }
53
54    #[doc(alias = "get_action_state_type")]
55    fn action_state_type(&self, action_name: &str) -> Option<VariantType> {
56        self.parent_action_state_type(action_name)
57    }
58
59    fn has_action(&self, action_name: &str) -> bool {
60        self.parent_has_action(action_name)
61    }
62
63    fn list_actions(&self) -> Vec<String>;
64    fn query_action(
65        &self,
66        action_name: &str,
67    ) -> Option<(
68        bool,
69        Option<VariantType>,
70        Option<VariantType>,
71        Option<Variant>,
72        Option<Variant>,
73    )>;
74}
75
76pub trait ActionGroupImplExt: ActionGroupImpl {
77    fn parent_action_added(&self, action_name: &str) {
78        unsafe {
79            let type_data = Self::type_data();
80            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
81                as *const ffi::GActionGroupInterface;
82
83            if let Some(func) = (*parent_iface).action_added {
84                func(
85                    self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
86                    action_name.to_glib_none().0,
87                );
88            }
89        }
90    }
91
92    fn parent_action_enabled_changed(&self, action_name: &str, enabled: bool) {
93        unsafe {
94            let type_data = Self::type_data();
95            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
96                as *const ffi::GActionGroupInterface;
97
98            if let Some(func) = (*parent_iface).action_enabled_changed {
99                func(
100                    self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
101                    action_name.to_glib_none().0,
102                    enabled.into_glib(),
103                );
104            }
105        }
106    }
107
108    fn parent_action_removed(&self, action_name: &str) {
109        unsafe {
110            let type_data = Self::type_data();
111            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
112                as *const ffi::GActionGroupInterface;
113
114            if let Some(func) = (*parent_iface).action_removed {
115                func(
116                    self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
117                    action_name.to_glib_none().0,
118                );
119            }
120        }
121    }
122
123    fn parent_action_state_changed(&self, action_name: &str, state: &Variant) {
124        unsafe {
125            let type_data = Self::type_data();
126            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
127                as *const ffi::GActionGroupInterface;
128
129            if let Some(func) = (*parent_iface).action_state_changed {
130                func(
131                    self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
132                    action_name.to_glib_none().0,
133                    state.to_glib_none().0,
134                );
135            }
136        }
137    }
138
139    fn parent_activate_action(&self, action_name: &str, parameter: Option<&Variant>) {
140        unsafe {
141            let type_data = Self::type_data();
142            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
143                as *const ffi::GActionGroupInterface;
144
145            let func = (*parent_iface)
146                .activate_action
147                .expect("no parent \"activate_action\" implementation");
148            func(
149                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
150                action_name.to_glib_none().0,
151                parameter.to_glib_none().0,
152            );
153        }
154    }
155
156    fn parent_change_action_state(&self, action_name: &str, value: &Variant) {
157        unsafe {
158            let type_data = Self::type_data();
159            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
160                as *const ffi::GActionGroupInterface;
161
162            let func = (*parent_iface)
163                .change_action_state
164                .expect("no parent \"change_action_state\" implementation");
165            func(
166                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
167                action_name.to_glib_none().0,
168                value.to_glib_none().0,
169            );
170        }
171    }
172
173    fn parent_action_is_enabled(&self, action_name: &str) -> bool {
174        unsafe {
175            let type_data = Self::type_data();
176            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
177                as *const ffi::GActionGroupInterface;
178
179            let func = (*parent_iface)
180                .get_action_enabled
181                .expect("no parent \"action_is_enabled\" implementation");
182            let ret = func(
183                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
184                action_name.to_glib_none().0,
185            );
186            from_glib(ret)
187        }
188    }
189
190    fn parent_action_parameter_type(&self, action_name: &str) -> Option<VariantType> {
191        unsafe {
192            let type_data = Self::type_data();
193            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
194                as *const ffi::GActionGroupInterface;
195
196            let func = (*parent_iface)
197                .get_action_parameter_type
198                .expect("no parent \"get_action_parameter_type\" implementation");
199            let ret = func(
200                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
201                action_name.to_glib_none().0,
202            );
203            from_glib_none(ret)
204        }
205    }
206
207    fn parent_action_state(&self, action_name: &str) -> Option<Variant> {
208        unsafe {
209            let type_data = Self::type_data();
210            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
211                as *const ffi::GActionGroupInterface;
212
213            let func = (*parent_iface)
214                .get_action_state
215                .expect("no parent \"get_action_state\" implementation");
216            let ret = func(
217                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
218                action_name.to_glib_none().0,
219            );
220            from_glib_none(ret)
221        }
222    }
223
224    fn parent_action_state_hint(&self, action_name: &str) -> Option<Variant> {
225        unsafe {
226            let type_data = Self::type_data();
227            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
228                as *const ffi::GActionGroupInterface;
229
230            let func = (*parent_iface)
231                .get_action_state_hint
232                .expect("no parent \"get_action_state_hint\" implementation");
233            let ret = func(
234                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
235                action_name.to_glib_none().0,
236            );
237            from_glib_none(ret)
238        }
239    }
240
241    fn parent_action_state_type(&self, action_name: &str) -> Option<VariantType> {
242        unsafe {
243            let type_data = Self::type_data();
244            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
245                as *const ffi::GActionGroupInterface;
246
247            let func = (*parent_iface)
248                .get_action_state_type
249                .expect("no parent \"get_action_state_type\" implementation");
250            let ret = func(
251                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
252                action_name.to_glib_none().0,
253            );
254            from_glib_none(ret)
255        }
256    }
257
258    fn parent_has_action(&self, action_name: &str) -> bool {
259        unsafe {
260            let type_data = Self::type_data();
261            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
262                as *const ffi::GActionGroupInterface;
263
264            let func = (*parent_iface)
265                .has_action
266                .expect("no parent \"has_action\" implementation");
267            let ret = func(
268                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
269                action_name.to_glib_none().0,
270            );
271            from_glib(ret)
272        }
273    }
274
275    fn parent_list_actions(&self) -> Vec<String> {
276        unsafe {
277            let type_data = Self::type_data();
278            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
279                as *const ffi::GActionGroupInterface;
280
281            let func = (*parent_iface)
282                .list_actions
283                .expect("no parent \"list_actions\" implementation");
284            let ret = func(self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0);
285            FromGlibPtrContainer::from_glib_none(ret)
286        }
287    }
288
289    fn parent_query_action(
290        &self,
291        action_name: &str,
292    ) -> Option<(
293        bool,
294        Option<VariantType>,
295        Option<VariantType>,
296        Option<Variant>,
297        Option<Variant>,
298    )> {
299        unsafe {
300            let type_data = Self::type_data();
301            let parent_iface = type_data.as_ref().parent_interface::<ActionGroup>()
302                as *const ffi::GActionGroupInterface;
303
304            let func = (*parent_iface)
305                .query_action
306                .expect("no parent \"query_action\" implementation");
307
308            let mut enabled = mem::MaybeUninit::uninit();
309            let mut parameter_type = ptr::null();
310            let mut state_type = ptr::null();
311            let mut state_hint = ptr::null_mut();
312            let mut state = ptr::null_mut();
313
314            let ret: bool = from_glib(func(
315                self.obj().unsafe_cast_ref::<ActionGroup>().to_glib_none().0,
316                action_name.to_glib_none().0,
317                enabled.as_mut_ptr(),
318                &mut parameter_type,
319                &mut state_type,
320                &mut state_hint,
321                &mut state,
322            ));
323
324            if !ret {
325                None
326            } else {
327                Some((
328                    from_glib(enabled.assume_init()),
329                    from_glib_none(parameter_type),
330                    from_glib_none(state_type),
331                    from_glib_none(state_hint),
332                    from_glib_none(state),
333                ))
334            }
335        }
336    }
337}
338
339impl<T: ActionGroupImpl> ActionGroupImplExt for T {}
340
341unsafe impl<T: ActionGroupImpl> IsImplementable<T> for ActionGroup {
342    fn interface_init(iface: &mut glib::Interface<Self>) {
343        let iface = iface.as_mut();
344
345        iface.action_added = Some(action_group_action_added::<T>);
346        iface.action_enabled_changed = Some(action_group_action_enabled_changed::<T>);
347        iface.action_removed = Some(action_group_action_removed::<T>);
348        iface.action_state_changed = Some(action_group_action_state_changed::<T>);
349        iface.activate_action = Some(action_group_activate_action::<T>);
350        iface.change_action_state = Some(action_group_change_action_state::<T>);
351        iface.get_action_enabled = Some(action_group_get_action_enabled::<T>);
352        iface.get_action_parameter_type = Some(action_group_get_action_parameter_type::<T>);
353        iface.get_action_state = Some(action_group_get_action_state::<T>);
354        iface.get_action_state_hint = Some(action_group_get_action_state_hint::<T>);
355        iface.get_action_state_type = Some(action_group_get_action_state_type::<T>);
356        iface.has_action = Some(action_group_has_action::<T>);
357        iface.list_actions = Some(action_group_list_actions::<T>);
358        iface.query_action = Some(action_group_query_action::<T>);
359    }
360}
361
362unsafe extern "C" fn action_group_has_action<T: ActionGroupImpl>(
363    action_group: *mut ffi::GActionGroup,
364    action_nameptr: *const libc::c_char,
365) -> glib::ffi::gboolean {
366    let instance = &*(action_group as *mut T::Instance);
367    let action_name = GString::from_glib_borrow(action_nameptr);
368    let imp = instance.imp();
369
370    imp.has_action(&action_name).into_glib()
371}
372
373unsafe extern "C" fn action_group_get_action_enabled<T: ActionGroupImpl>(
374    action_group: *mut ffi::GActionGroup,
375    action_nameptr: *const libc::c_char,
376) -> glib::ffi::gboolean {
377    let instance = &*(action_group as *mut T::Instance);
378    let imp = instance.imp();
379    let action_name = GString::from_glib_borrow(action_nameptr);
380
381    imp.action_is_enabled(&action_name).into_glib()
382}
383
384// rustdoc-stripper-ignore-next
385/// Struct to hold a pointer and free it on `Drop::drop`
386struct PtrHolder<T, F: Fn(*mut T) + 'static>(*mut T, F);
387
388impl<T, F: Fn(*mut T) + 'static> Drop for PtrHolder<T, F> {
389    fn drop(&mut self) {
390        (self.1)(self.0)
391    }
392}
393
394unsafe extern "C" fn action_group_get_action_parameter_type<T: ActionGroupImpl>(
395    action_group: *mut ffi::GActionGroup,
396    action_nameptr: *const libc::c_char,
397) -> *const glib::ffi::GVariantType {
398    let instance = &*(action_group as *mut T::Instance);
399    let imp = instance.imp();
400    let action_name = GString::from_glib_borrow(action_nameptr);
401    let wrap = from_glib_borrow::<_, ActionGroup>(action_group);
402
403    let ret = imp.action_parameter_type(&action_name);
404
405    if let Some(param_type) = ret {
406        let parameter_type_quark = {
407            static QUARK: OnceLock<Quark> = OnceLock::new();
408            *QUARK.get_or_init(|| {
409                Quark::from_str("gtk-rs-subclass-action-group-get-action-parameter")
410            })
411        };
412        let param_type = param_type.into_glib_ptr();
413        wrap.set_qdata(
414            parameter_type_quark,
415            PtrHolder(param_type, |ptr| glib::ffi::g_free(ptr as *mut _)),
416        );
417        param_type
418    } else {
419        ptr::null()
420    }
421}
422
423unsafe extern "C" fn action_group_get_action_state_type<T: ActionGroupImpl>(
424    action_group: *mut ffi::GActionGroup,
425    action_nameptr: *const libc::c_char,
426) -> *const glib::ffi::GVariantType {
427    let instance = &*(action_group as *mut T::Instance);
428    let imp = instance.imp();
429    let action_name = GString::from_glib_borrow(action_nameptr);
430
431    let ret = imp.action_state_type(&action_name);
432
433    if let Some(state_type) = ret {
434        let instance = imp.obj();
435        let state_type_quark = {
436            static QUARK: OnceLock<Quark> = OnceLock::new();
437            *QUARK.get_or_init(|| {
438                Quark::from_str("gtk-rs-subclass-action-group-get-action-state-type")
439            })
440        };
441        let state_type = state_type.into_glib_ptr();
442        instance.set_qdata(
443            state_type_quark,
444            PtrHolder(state_type, |ptr| glib::ffi::g_free(ptr as *mut _)),
445        );
446        state_type
447    } else {
448        ptr::null()
449    }
450}
451
452unsafe extern "C" fn action_group_get_action_state_hint<T: ActionGroupImpl>(
453    action_group: *mut ffi::GActionGroup,
454    action_nameptr: *const libc::c_char,
455) -> *mut glib::ffi::GVariant {
456    let instance = &*(action_group as *mut T::Instance);
457    let imp = instance.imp();
458    let action_name = GString::from_glib_borrow(action_nameptr);
459
460    let ret = imp.action_state_hint(&action_name);
461    if let Some(state_hint) = ret {
462        let instance = imp.obj();
463        let state_hint_quark = {
464            static QUARK: OnceLock<Quark> = OnceLock::new();
465            *QUARK.get_or_init(|| {
466                Quark::from_str("gtk-rs-subclass-action-group-get-action-state-hint")
467            })
468        };
469        let state_hint_ptr = state_hint.into_glib_ptr();
470        instance.set_qdata(
471            state_hint_quark,
472            PtrHolder(state_hint_ptr, |ptr| glib::ffi::g_variant_unref(ptr)),
473        );
474        state_hint_ptr
475    } else {
476        ptr::null_mut()
477    }
478}
479
480unsafe extern "C" fn action_group_get_action_state<T: ActionGroupImpl>(
481    action_group: *mut ffi::GActionGroup,
482    action_nameptr: *const libc::c_char,
483) -> *mut glib::ffi::GVariant {
484    let instance = &*(action_group as *mut T::Instance);
485    let imp = instance.imp();
486    let action_name = GString::from_glib_borrow(action_nameptr);
487
488    let ret = imp.action_state(&action_name);
489    if let Some(state) = ret {
490        let instance = imp.obj();
491        let state_quark = {
492            static QUARK: OnceLock<Quark> = OnceLock::new();
493            *QUARK.get_or_init(|| Quark::from_str("gtk-rs-subclass-action-group-get-action-state"))
494        };
495        let state_ptr = state.into_glib_ptr();
496        instance.set_qdata(
497            state_quark,
498            PtrHolder(state_ptr, |ptr| glib::ffi::g_variant_unref(ptr)),
499        );
500        state_ptr
501    } else {
502        ptr::null_mut()
503    }
504}
505
506unsafe extern "C" fn action_group_change_action_state<T: ActionGroupImpl>(
507    action_group: *mut ffi::GActionGroup,
508    action_nameptr: *const libc::c_char,
509    stateptr: *mut glib::ffi::GVariant,
510) {
511    let instance = &*(action_group as *mut T::Instance);
512    let imp = instance.imp();
513    let action_name = GString::from_glib_borrow(action_nameptr);
514    let state = Variant::from_glib_borrow(stateptr);
515
516    imp.change_action_state(&action_name, &state)
517}
518
519unsafe extern "C" fn action_group_activate_action<T: ActionGroupImpl>(
520    action_group: *mut ffi::GActionGroup,
521    action_nameptr: *const libc::c_char,
522    parameterptr: *mut glib::ffi::GVariant,
523) {
524    let instance = &*(action_group as *mut T::Instance);
525    let imp = instance.imp();
526    let action_name = GString::from_glib_borrow(action_nameptr);
527    let param: Borrowed<Option<Variant>> = from_glib_borrow(parameterptr);
528
529    imp.activate_action(&action_name, param.as_ref().as_ref())
530}
531
532unsafe extern "C" fn action_group_action_added<T: ActionGroupImpl>(
533    action_group: *mut ffi::GActionGroup,
534    action_nameptr: *const libc::c_char,
535) {
536    let instance = &*(action_group as *mut T::Instance);
537    let imp = instance.imp();
538    let action_name = GString::from_glib_borrow(action_nameptr);
539
540    imp.action_added(&action_name)
541}
542
543unsafe extern "C" fn action_group_action_removed<T: ActionGroupImpl>(
544    action_group: *mut ffi::GActionGroup,
545    action_nameptr: *const libc::c_char,
546) {
547    let instance = &*(action_group as *mut T::Instance);
548    let imp = instance.imp();
549    let action_name = GString::from_glib_borrow(action_nameptr);
550
551    imp.action_removed(&action_name)
552}
553
554unsafe extern "C" fn action_group_action_enabled_changed<T: ActionGroupImpl>(
555    action_group: *mut ffi::GActionGroup,
556    action_nameptr: *const libc::c_char,
557    enabled: glib::ffi::gboolean,
558) {
559    let instance = &*(action_group as *mut T::Instance);
560    let imp = instance.imp();
561    let action_name = GString::from_glib_borrow(action_nameptr);
562
563    imp.action_enabled_changed(&action_name, from_glib(enabled))
564}
565
566unsafe extern "C" fn action_group_action_state_changed<T: ActionGroupImpl>(
567    action_group: *mut ffi::GActionGroup,
568    action_nameptr: *const libc::c_char,
569    stateptr: *mut glib::ffi::GVariant,
570) {
571    let instance = &*(action_group as *mut T::Instance);
572    let imp = instance.imp();
573    let action_name = GString::from_glib_borrow(action_nameptr);
574    let state = Variant::from_glib_borrow(stateptr);
575
576    imp.action_state_changed(&action_name, &state)
577}
578
579unsafe extern "C" fn action_group_list_actions<T: ActionGroupImpl>(
580    action_group: *mut ffi::GActionGroup,
581) -> *mut *mut libc::c_char {
582    let instance = &*(action_group as *mut T::Instance);
583    let imp = instance.imp();
584
585    let actions = imp.list_actions();
586
587    {
588        let instance = imp.obj();
589        let actions_quark = {
590            static QUARK: OnceLock<Quark> = OnceLock::new();
591            *QUARK.get_or_init(|| Quark::from_str("gtk-rs-subclass-action-group-list-actions"))
592        };
593        let actionsptr = actions.to_glib_full();
594        instance.set_qdata(actions_quark, actionsptr);
595        actionsptr
596    }
597}
598
599unsafe extern "C" fn action_group_query_action<T: ActionGroupImpl>(
600    action_group: *mut ffi::GActionGroup,
601    action_nameptr: *const libc::c_char,
602    enabled: *mut glib::ffi::gboolean,
603    parameter_type: *mut *const glib::ffi::GVariantType,
604    state_type: *mut *const glib::ffi::GVariantType,
605    state_hint: *mut *mut glib::ffi::GVariant,
606    state: *mut *mut glib::ffi::GVariant,
607) -> glib::ffi::gboolean {
608    let instance = &*(action_group as *mut T::Instance);
609    let imp = instance.imp();
610    let action_name = GString::from_glib_borrow(action_nameptr);
611
612    let ret = imp.query_action(&action_name);
613    if let Some((rs_enabled, rs_parameter_type, rs_state_type, rs_state_hint, rs_state)) = ret {
614        let instance = imp.obj();
615
616        if !enabled.is_null() {
617            *enabled = rs_enabled.into_glib();
618        }
619        if !parameter_type.is_null() {
620            if let Some(rs_parameter_type) = rs_parameter_type {
621                let param_type_quark = {
622                    static QUARK: OnceLock<Quark> = OnceLock::new();
623                    *QUARK.get_or_init(|| {
624                        Quark::from_str("gtk-rs-subclass-action-group-query-action-parameter-type")
625                    })
626                };
627                let ret = rs_parameter_type.into_glib_ptr();
628                instance.set_qdata(
629                    param_type_quark,
630                    PtrHolder(ret, |ptr| glib::ffi::g_free(ptr as *mut _)),
631                );
632                *parameter_type = ret;
633            } else {
634                *parameter_type = ptr::null_mut();
635            }
636        }
637        if !state_type.is_null() {
638            if let Some(rs_state_type) = rs_state_type {
639                let state_type_quark = {
640                    static QUARK: OnceLock<Quark> = OnceLock::new();
641                    *QUARK.get_or_init(|| {
642                        Quark::from_str("gtk-rs-subclass-action-group-query-action-state-type")
643                    })
644                };
645                let ret = rs_state_type.into_glib_ptr();
646                instance.set_qdata(
647                    state_type_quark,
648                    PtrHolder(ret, |ptr| glib::ffi::g_free(ptr as *mut _)),
649                );
650                *state_type = ret;
651            } else {
652                *state_type = ptr::null_mut();
653            }
654        }
655        if !state_hint.is_null() {
656            if let Some(rs_state_hint) = rs_state_hint {
657                let state_hint_quark = {
658                    static QUARK: OnceLock<Quark> = OnceLock::new();
659                    *QUARK.get_or_init(|| {
660                        Quark::from_str("gtk-rs-subclass-action-group-query-action-state-hint")
661                    })
662                };
663                let ret = rs_state_hint.into_glib_ptr();
664                instance.set_qdata(
665                    state_hint_quark,
666                    PtrHolder(ret, |ptr| glib::ffi::g_variant_unref(ptr)),
667                );
668                *state_hint = ret;
669            } else {
670                *state_hint = ptr::null_mut();
671            }
672        }
673        if !state.is_null() {
674            if let Some(rs_state) = rs_state {
675                let state_quark = {
676                    static QUARK: OnceLock<Quark> = OnceLock::new();
677                    *QUARK.get_or_init(|| {
678                        Quark::from_str("gtk-rs-subclass-action-group-query-action-state")
679                    })
680                };
681                let ret = rs_state.into_glib_ptr();
682                instance.set_qdata(
683                    state_quark,
684                    PtrHolder(ret, |ptr| glib::ffi::g_variant_unref(ptr)),
685                );
686                *state = ret;
687            } else {
688                *state = ptr::null_mut();
689            }
690        }
691        true
692    } else {
693        false
694    }
695    .into_glib()
696}