1use std::{boxed::Box as Box_, collections::HashMap, fmt, future::Future};
7
8use glib::{
9 clone::Downgrade,
10 property::{Property, PropertyGet},
11 subclass::SignalId,
12 translate::*,
13 GString, Variant,
14};
15
16use crate::{
17 ffi, prelude::*, subclass::prelude::*, Accessible, AccessibleRole, Buildable, BuilderRustScope,
18 BuilderScope, ConstraintTarget, DirectionType, LayoutManager, Orientation, Shortcut,
19 SizeRequestMode, Snapshot, StateFlags, SystemSetting, TextDirection, Tooltip, Widget,
20};
21
22#[derive(Debug, Default)]
23struct Internal {
24 pub(crate) actions: HashMap<String, glib::ffi::gpointer>,
25 pub(crate) scope: Option<*mut <<BuilderRustScope as glib::object::ObjectSubclassIs>::Subclass as ObjectSubclass>::Instance>,
26}
27unsafe impl Sync for Internal {}
28unsafe impl Send for Internal {}
29
30pub struct WidgetActionIter(*mut ffi::GtkWidgetClass, u32);
31
32pub struct WidgetAction(
33 glib::Type,
34 GString,
35 Option<glib::VariantType>,
36 Option<GString>,
37);
38
39impl WidgetAction {
40 pub fn owner(&self) -> glib::Type {
43 self.0
44 }
45
46 pub fn name(&self) -> &str {
49 self.1.as_ref()
50 }
51
52 pub fn parameter_type(&self) -> Option<&glib::VariantType> {
55 self.2.as_ref()
56 }
57
58 pub fn property_name(&self) -> Option<&str> {
61 self.3.as_ref().map(|s| s.as_ref())
62 }
63}
64
65impl fmt::Debug for WidgetAction {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("WidgetAction")
68 .field("owner", &self.owner())
69 .field("name", &self.name())
70 .field("parameter_type", &self.parameter_type())
71 .field("property_name", &self.property_name())
72 .finish()
73 }
74}
75
76impl Iterator for WidgetActionIter {
77 type Item = WidgetAction;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 unsafe {
81 let mut owner = std::mem::MaybeUninit::uninit();
82 let mut action_name_ptr = std::ptr::null();
83 let mut parameter_type = std::ptr::null();
84 let mut property_name_ptr = std::ptr::null();
85 let found: bool = from_glib(ffi::gtk_widget_class_query_action(
86 self.0,
87 self.1,
88 owner.as_mut_ptr(),
89 &mut action_name_ptr,
90 &mut parameter_type,
91 &mut property_name_ptr,
92 ));
93 if found {
94 self.1 += 1;
95 let property_name: Option<GString> = from_glib_none(property_name_ptr);
96 let action_name: GString = from_glib_none(action_name_ptr);
97
98 Some(WidgetAction(
99 from_glib(owner.assume_init()),
100 action_name,
101 from_glib_none(parameter_type),
102 property_name,
103 ))
104 } else {
105 None
106 }
107 }
108 }
109}
110
111impl std::iter::FusedIterator for WidgetActionIter {}
112
113pub trait WidgetImpl:
114 ObjectImpl
115 + ObjectSubclass<Type: IsA<Widget> + IsA<Accessible> + IsA<Buildable> + IsA<ConstraintTarget>>
116{
117 fn compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
118 self.parent_compute_expand(hexpand, vexpand)
119 }
120
121 fn contains(&self, x: f64, y: f64) -> bool {
122 self.parent_contains(x, y)
123 }
124
125 fn direction_changed(&self, previous_direction: TextDirection) {
126 self.parent_direction_changed(previous_direction)
127 }
128
129 fn focus(&self, direction_type: DirectionType) -> bool {
130 self.parent_focus(direction_type)
131 }
132
133 #[doc(alias = "get_request_mode")]
134 fn request_mode(&self) -> SizeRequestMode {
135 self.parent_request_mode()
136 }
137
138 fn grab_focus(&self) -> bool {
139 self.parent_grab_focus()
140 }
141
142 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
143 #[allow(deprecated)]
144 fn hide(&self) {
145 self.parent_hide()
146 }
147
148 fn keynav_failed(&self, direction_type: DirectionType) -> bool {
149 self.parent_keynav_failed(direction_type)
150 }
151
152 fn map(&self) {
153 self.parent_map()
154 }
155
156 fn measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
157 self.parent_measure(orientation, for_size)
158 }
159
160 fn mnemonic_activate(&self, group_cycling: bool) -> bool {
161 self.parent_mnemonic_activate(group_cycling)
162 }
163
164 fn move_focus(&self, direction_type: DirectionType) {
165 self.parent_move_focus(direction_type)
166 }
167
168 fn query_tooltip(&self, x: i32, y: i32, keyboard_tooltip: bool, tooltip: &Tooltip) -> bool {
169 self.parent_query_tooltip(x, y, keyboard_tooltip, tooltip)
170 }
171
172 fn realize(&self) {
173 self.parent_realize()
174 }
175
176 fn root(&self) {
177 self.parent_root()
178 }
179
180 fn set_focus_child(&self, child: Option<&Widget>) {
181 self.parent_set_focus_child(child)
182 }
183
184 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
185 #[allow(deprecated)]
186 fn show(&self) {
187 self.parent_show()
188 }
189
190 fn size_allocate(&self, width: i32, height: i32, baseline: i32) {
191 self.parent_size_allocate(width, height, baseline)
192 }
193
194 fn snapshot(&self, snapshot: &Snapshot) {
195 self.parent_snapshot(snapshot)
196 }
197
198 fn state_flags_changed(&self, state_flags: &StateFlags) {
199 self.parent_state_flags_changed(state_flags)
200 }
201
202 fn system_setting_changed(&self, settings: &SystemSetting) {
203 self.parent_system_setting_changed(settings)
204 }
205
206 fn unmap(&self) {
207 self.parent_unmap()
208 }
209
210 fn unrealize(&self) {
211 self.parent_unrealize()
212 }
213
214 fn unroot(&self) {
215 self.parent_unroot()
216 }
217}
218
219pub trait WidgetImplExt: WidgetImpl {
220 fn parent_compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
221 unsafe {
222 let data = Self::type_data();
223 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
224 if let Some(f) = (*parent_class).compute_expand {
225 let mut hexpand_glib = hexpand.into_glib();
226 let mut vexpand_glib = vexpand.into_glib();
227 f(
228 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
229 &mut hexpand_glib,
230 &mut vexpand_glib,
231 );
232 *hexpand = from_glib(hexpand_glib);
233 *vexpand = from_glib(vexpand_glib);
234 }
235 }
236 }
237
238 fn parent_contains(&self, x: f64, y: f64) -> bool {
240 unsafe {
241 let data = Self::type_data();
242 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
243 if let Some(f) = (*parent_class).contains {
244 from_glib(f(
245 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
246 x,
247 y,
248 ))
249 } else {
250 false
251 }
252 }
253 }
254
255 fn parent_direction_changed(&self, previous_direction: TextDirection) {
256 unsafe {
257 let data = Self::type_data();
258 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
259 if let Some(f) = (*parent_class).direction_changed {
260 f(
261 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
262 previous_direction.into_glib(),
263 )
264 }
265 }
266 }
267
268 fn parent_focus(&self, direction_type: DirectionType) -> bool {
270 unsafe {
271 let data = Self::type_data();
272 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
273 if let Some(f) = (*parent_class).focus {
274 from_glib(f(
275 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
276 direction_type.into_glib(),
277 ))
278 } else {
279 false
280 }
281 }
282 }
283
284 fn parent_request_mode(&self) -> SizeRequestMode {
285 unsafe {
286 let data = Self::type_data();
287 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
288 let f = (*parent_class)
289 .get_request_mode
290 .expect("No parent class impl for \"get_request_mode\"");
291 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
292 }
293 }
294
295 fn parent_grab_focus(&self) -> bool {
297 unsafe {
298 let data = Self::type_data();
299 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
300 if let Some(f) = (*parent_class).grab_focus {
301 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
302 } else {
303 false
304 }
305 }
306 }
307
308 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
309 #[allow(deprecated)]
310 fn parent_hide(&self) {
311 unsafe {
312 let data = Self::type_data();
313 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
314 if let Some(f) = (*parent_class).hide {
315 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
316 }
317 }
318 }
319
320 fn parent_keynav_failed(&self, direction_type: DirectionType) -> bool {
324 unsafe {
325 let data = Self::type_data();
326 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
327 if let Some(f) = (*parent_class).keynav_failed {
328 from_glib(f(
329 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
330 direction_type.into_glib(),
331 ))
332 } else {
333 false
334 }
335 }
336 }
337
338 fn parent_map(&self) {
339 unsafe {
340 let data = Self::type_data();
341 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
342 if let Some(f) = (*parent_class).map {
343 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
344 }
345 }
346 }
347
348 fn parent_measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
349 unsafe {
350 let data = Self::type_data();
351 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
352
353 let f = (*parent_class)
354 .measure
355 .expect("No parent class impl for \"measure\"");
356
357 let mut min = 0;
358 let mut nat = 0;
359 let mut min_base = -1;
360 let mut nat_base = -1;
361 f(
362 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
363 orientation.into_glib(),
364 for_size,
365 &mut min,
366 &mut nat,
367 &mut min_base,
368 &mut nat_base,
369 );
370 (min, nat, min_base, nat_base)
371 }
372 }
373
374 fn parent_mnemonic_activate(&self, group_cycling: bool) -> bool {
376 unsafe {
377 let data = Self::type_data();
378 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
379 if let Some(f) = (*parent_class).mnemonic_activate {
380 from_glib(f(
381 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
382 group_cycling.into_glib(),
383 ))
384 } else {
385 false
386 }
387 }
388 }
389
390 fn parent_move_focus(&self, direction_type: DirectionType) {
391 unsafe {
392 let data = Self::type_data();
393 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
394 if let Some(f) = (*parent_class).move_focus {
395 f(
396 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
397 direction_type.into_glib(),
398 )
399 }
400 }
401 }
402
403 fn parent_query_tooltip(
404 &self,
405 x: i32,
406 y: i32,
407 keyboard_tooltip: bool,
408 tooltip: &Tooltip,
409 ) -> bool {
410 unsafe {
411 let data = Self::type_data();
412 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
413 if let Some(f) = (*parent_class).query_tooltip {
414 from_glib(f(
415 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
416 x,
417 y,
418 keyboard_tooltip.into_glib(),
419 tooltip.to_glib_none().0,
420 ))
421 } else {
422 false
423 }
424 }
425 }
426
427 fn parent_realize(&self) {
428 unsafe {
429 let data = Self::type_data();
430 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
431 if let Some(f) = (*parent_class).realize {
432 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
433 }
434 }
435 }
436
437 fn parent_root(&self) {
438 unsafe {
439 let data = Self::type_data();
440 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
441 if let Some(f) = (*parent_class).root {
442 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
443 }
444 }
445 }
446
447 fn parent_set_focus_child(&self, child: Option<&Widget>) {
448 unsafe {
449 let data = Self::type_data();
450 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
451 if let Some(f) = (*parent_class).set_focus_child {
452 f(
453 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
454 child.to_glib_none().0,
455 )
456 }
457 }
458 }
459
460 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
461 #[allow(deprecated)]
462 fn parent_show(&self) {
463 unsafe {
464 let data = Self::type_data();
465 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
466 if let Some(f) = (*parent_class).show {
467 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
468 }
469 }
470 }
471
472 fn parent_size_allocate(&self, width: i32, height: i32, baseline: i32) {
473 unsafe {
474 let data = Self::type_data();
475 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
476 if let Some(f) = (*parent_class).size_allocate {
477 f(
478 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
479 width,
480 height,
481 baseline,
482 )
483 }
484 }
485 }
486
487 fn parent_snapshot(&self, snapshot: &Snapshot) {
488 unsafe {
489 let data = Self::type_data();
490 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
491 if let Some(f) = (*parent_class).snapshot {
492 f(
493 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
494 snapshot.to_glib_none().0,
495 )
496 }
497 }
498 }
499
500 fn parent_state_flags_changed(&self, state_flags: &StateFlags) {
501 unsafe {
502 let data = Self::type_data();
503 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
504 if let Some(f) = (*parent_class).state_flags_changed {
505 f(
506 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
507 state_flags.into_glib(),
508 )
509 }
510 }
511 }
512
513 fn parent_system_setting_changed(&self, settings: &SystemSetting) {
514 unsafe {
515 let data = Self::type_data();
516 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
517 if let Some(f) = (*parent_class).system_setting_changed {
518 f(
519 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
520 settings.into_glib(),
521 )
522 }
523 }
524 }
525
526 fn parent_unmap(&self) {
527 unsafe {
528 let data = Self::type_data();
529 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
530 if let Some(f) = (*parent_class).unmap {
531 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
532 }
533 }
534 }
535
536 fn parent_unrealize(&self) {
537 unsafe {
538 let data = Self::type_data();
539 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
540 if let Some(f) = (*parent_class).unrealize {
541 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
542 }
543 }
544 }
545
546 fn parent_unroot(&self) {
547 unsafe {
548 let data = Self::type_data();
549 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
550 if let Some(f) = (*parent_class).unroot {
551 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
552 }
553 }
554 }
555}
556
557impl<T: WidgetImpl> WidgetImplExt for T {}
558
559unsafe impl<T: WidgetImpl> IsSubclassable<T> for Widget {
560 fn class_init(class: &mut ::glib::Class<Self>) {
561 Self::parent_class_init::<T>(class);
562
563 assert_initialized_main_thread!();
564
565 let klass = class.as_mut();
566 unsafe {
567 let mut data = T::type_data();
568 let data = data.as_mut();
569 data.set_class_data(<T as ObjectSubclassType>::type_(), Internal::default());
571 }
572
573 klass.compute_expand = Some(widget_compute_expand::<T>);
574 klass.contains = Some(widget_contains::<T>);
575 klass.direction_changed = Some(widget_direction_changed::<T>);
576 klass.focus = Some(widget_focus::<T>);
577 klass.get_request_mode = Some(widget_get_request_mode::<T>);
578 klass.grab_focus = Some(widget_grab_focus::<T>);
579 klass.hide = Some(widget_hide::<T>);
580 klass.keynav_failed = Some(widget_keynav_failed::<T>);
581 klass.map = Some(widget_map::<T>);
582 klass.measure = Some(widget_measure::<T>);
583 klass.mnemonic_activate = Some(widget_mnemonic_activate::<T>);
584 klass.move_focus = Some(widget_move_focus::<T>);
585 klass.query_tooltip = Some(widget_query_tooltip::<T>);
586 klass.realize = Some(widget_realize::<T>);
587 klass.root = Some(widget_root::<T>);
588 klass.set_focus_child = Some(widget_set_focus_child::<T>);
589 klass.show = Some(widget_show::<T>);
590 klass.size_allocate = Some(widget_size_allocate::<T>);
591 klass.snapshot = Some(widget_snapshot::<T>);
592 klass.state_flags_changed = Some(widget_state_flags_changed::<T>);
593 klass.system_setting_changed = Some(widget_system_setting_changed::<T>);
594 klass.unmap = Some(widget_unmap::<T>);
595 klass.unrealize = Some(widget_unrealize::<T>);
596 klass.unroot = Some(widget_unroot::<T>);
597 }
598}
599
600unsafe extern "C" fn widget_compute_expand<T: WidgetImpl>(
601 ptr: *mut ffi::GtkWidget,
602 hexpand_ptr: *mut glib::ffi::gboolean,
603 vexpand_ptr: *mut glib::ffi::gboolean,
604) {
605 let instance = &*(ptr as *mut T::Instance);
606 let imp = instance.imp();
607
608 let widget = imp.obj();
609 let widget = widget.unsafe_cast_ref::<Widget>();
610 let mut hexpand: bool = if widget.is_hexpand_set() {
611 widget.hexpands()
612 } else {
613 from_glib(*hexpand_ptr)
614 };
615 let mut vexpand: bool = if widget.is_vexpand_set() {
616 widget.vexpands()
617 } else {
618 from_glib(*vexpand_ptr)
619 };
620
621 imp.compute_expand(&mut hexpand, &mut vexpand);
622
623 *hexpand_ptr = hexpand.into_glib();
624 *vexpand_ptr = vexpand.into_glib();
625}
626
627unsafe extern "C" fn widget_contains<T: WidgetImpl>(
628 ptr: *mut ffi::GtkWidget,
629 x: f64,
630 y: f64,
631) -> glib::ffi::gboolean {
632 let instance = &*(ptr as *mut T::Instance);
633 let imp = instance.imp();
634
635 imp.contains(x, y).into_glib()
636}
637
638unsafe extern "C" fn widget_direction_changed<T: WidgetImpl>(
639 ptr: *mut ffi::GtkWidget,
640 direction_ptr: ffi::GtkTextDirection,
641) {
642 let instance = &*(ptr as *mut T::Instance);
643 let imp = instance.imp();
644 let direction_wrap = from_glib(direction_ptr);
645
646 imp.direction_changed(direction_wrap)
647}
648
649unsafe extern "C" fn widget_focus<T: WidgetImpl>(
650 ptr: *mut ffi::GtkWidget,
651 direction_type_ptr: ffi::GtkDirectionType,
652) -> glib::ffi::gboolean {
653 let instance = &*(ptr as *mut T::Instance);
654 let imp = instance.imp();
655 let direction_type = from_glib(direction_type_ptr);
656
657 imp.focus(direction_type).into_glib()
658}
659
660unsafe extern "C" fn widget_get_request_mode<T: WidgetImpl>(
661 ptr: *mut ffi::GtkWidget,
662) -> ffi::GtkSizeRequestMode {
663 let instance = &*(ptr as *mut T::Instance);
664 let imp = instance.imp();
665
666 imp.request_mode().into_glib()
667}
668
669unsafe extern "C" fn widget_grab_focus<T: WidgetImpl>(
670 ptr: *mut ffi::GtkWidget,
671) -> glib::ffi::gboolean {
672 let instance = &*(ptr as *mut T::Instance);
673 let imp = instance.imp();
674
675 imp.grab_focus().into_glib()
676}
677
678unsafe extern "C" fn widget_hide<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
679 let instance = &*(ptr as *mut T::Instance);
680 let imp = instance.imp();
681
682 imp.hide()
683}
684
685unsafe extern "C" fn widget_keynav_failed<T: WidgetImpl>(
686 ptr: *mut ffi::GtkWidget,
687 direction_type_ptr: ffi::GtkDirectionType,
688) -> glib::ffi::gboolean {
689 let instance = &*(ptr as *mut T::Instance);
690 let imp = instance.imp();
691 let direction_type = from_glib(direction_type_ptr);
692
693 imp.keynav_failed(direction_type).into_glib()
694}
695
696unsafe extern "C" fn widget_map<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
697 let instance = &*(ptr as *mut T::Instance);
698 let imp = instance.imp();
699
700 imp.map()
701}
702
703unsafe extern "C" fn widget_measure<T: WidgetImpl>(
704 ptr: *mut ffi::GtkWidget,
705 orientation_ptr: ffi::GtkOrientation,
706 for_size: i32,
707 min_ptr: *mut libc::c_int,
708 nat_ptr: *mut libc::c_int,
709 min_base_ptr: *mut libc::c_int,
710 nat_base_ptr: *mut libc::c_int,
711) {
712 let instance = &*(ptr as *mut T::Instance);
713 let imp = instance.imp();
714 let orientation = from_glib(orientation_ptr);
715 let (min, nat, min_base, nat_base) = imp.measure(orientation, for_size);
716 if !min_ptr.is_null() {
717 *min_ptr = min;
718 }
719 if !nat_ptr.is_null() {
720 *nat_ptr = nat;
721 }
722 if !min_base_ptr.is_null() {
723 *min_base_ptr = min_base;
724 }
725 if !nat_base_ptr.is_null() {
726 *nat_base_ptr = nat_base;
727 }
728}
729
730unsafe extern "C" fn widget_mnemonic_activate<T: WidgetImpl>(
731 ptr: *mut ffi::GtkWidget,
732 group_cycling_ptr: glib::ffi::gboolean,
733) -> glib::ffi::gboolean {
734 let instance = &*(ptr as *mut T::Instance);
735 let imp = instance.imp();
736 let group_cycling: bool = from_glib(group_cycling_ptr);
737
738 imp.mnemonic_activate(group_cycling).into_glib()
739}
740
741unsafe extern "C" fn widget_move_focus<T: WidgetImpl>(
742 ptr: *mut ffi::GtkWidget,
743 direction_type_ptr: ffi::GtkDirectionType,
744) {
745 let instance = &*(ptr as *mut T::Instance);
746 let imp = instance.imp();
747 let direction_type = from_glib(direction_type_ptr);
748
749 imp.move_focus(direction_type)
750}
751
752unsafe extern "C" fn widget_query_tooltip<T: WidgetImpl>(
753 ptr: *mut ffi::GtkWidget,
754 x: i32,
755 y: i32,
756 keyboard_tooltip_ptr: glib::ffi::gboolean,
757 tooltip_ptr: *mut ffi::GtkTooltip,
758) -> glib::ffi::gboolean {
759 let instance = &*(ptr as *mut T::Instance);
760 let imp = instance.imp();
761
762 let keyboard_tooltip: bool = from_glib(keyboard_tooltip_ptr);
763 let tooltip = from_glib_borrow(tooltip_ptr);
764
765 imp.query_tooltip(x, y, keyboard_tooltip, &tooltip)
766 .into_glib()
767}
768
769unsafe extern "C" fn widget_realize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
770 let instance = &*(ptr as *mut T::Instance);
771 let imp = instance.imp();
772
773 imp.realize()
774}
775
776unsafe extern "C" fn widget_root<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
777 let instance = &*(ptr as *mut T::Instance);
778 let imp = instance.imp();
779
780 imp.root()
781}
782
783unsafe extern "C" fn widget_set_focus_child<T: WidgetImpl>(
784 ptr: *mut ffi::GtkWidget,
785 child_ptr: *mut ffi::GtkWidget,
786) {
787 let instance = &*(ptr as *mut T::Instance);
788 let imp = instance.imp();
789 let child: Borrowed<Option<Widget>> = from_glib_borrow(child_ptr);
790
791 imp.set_focus_child(child.as_ref().as_ref())
792}
793
794unsafe extern "C" fn widget_show<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
795 let instance = &*(ptr as *mut T::Instance);
796 let imp = instance.imp();
797
798 imp.show()
799}
800
801unsafe extern "C" fn widget_size_allocate<T: WidgetImpl>(
802 ptr: *mut ffi::GtkWidget,
803 width: i32,
804 height: i32,
805 baseline: i32,
806) {
807 let instance = &*(ptr as *mut T::Instance);
808 let imp = instance.imp();
809
810 imp.size_allocate(width, height, baseline)
811}
812
813unsafe extern "C" fn widget_snapshot<T: WidgetImpl>(
814 ptr: *mut ffi::GtkWidget,
815 snapshot_ptr: *mut ffi::GtkSnapshot,
816) {
817 let instance = &*(ptr as *mut T::Instance);
818 let imp = instance.imp();
819 let snapshot = from_glib_borrow(snapshot_ptr);
820
821 imp.snapshot(&snapshot)
822}
823
824unsafe extern "C" fn widget_state_flags_changed<T: WidgetImpl>(
825 ptr: *mut ffi::GtkWidget,
826 state_flags_ptr: ffi::GtkStateFlags,
827) {
828 let instance = &*(ptr as *mut T::Instance);
829 let imp = instance.imp();
830 let state_flags = from_glib(state_flags_ptr);
831
832 imp.state_flags_changed(&state_flags)
833}
834
835unsafe extern "C" fn widget_system_setting_changed<T: WidgetImpl>(
836 ptr: *mut ffi::GtkWidget,
837 settings_ptr: ffi::GtkSystemSetting,
838) {
839 let instance = &*(ptr as *mut T::Instance);
840 let imp = instance.imp();
841 let settings = from_glib(settings_ptr);
842
843 imp.system_setting_changed(&settings)
844}
845
846unsafe extern "C" fn widget_unmap<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
847 let instance = &*(ptr as *mut T::Instance);
848 let imp = instance.imp();
849
850 imp.unmap()
851}
852
853unsafe extern "C" fn widget_unrealize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
854 let instance = &*(ptr as *mut T::Instance);
855 let imp = instance.imp();
856
857 imp.unrealize()
858}
859
860unsafe extern "C" fn widget_unroot<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
861 let instance = &*(ptr as *mut T::Instance);
862 let imp = instance.imp();
863
864 imp.unroot()
865}
866
867#[allow(clippy::missing_safety_doc)]
868pub unsafe trait WidgetClassExt: ClassStruct {
869 #[doc(alias = "gtk_widget_class_set_template")]
870 fn set_template_bytes(&mut self, template: &glib::Bytes) {
871 unsafe {
872 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
873 ffi::gtk_widget_class_set_template(widget_class, template.to_glib_none().0);
874 }
875 }
876
877 fn set_template(&mut self, template: &[u8]) {
878 let template_bytes = glib::Bytes::from(template);
879 self.set_template_bytes(&template_bytes);
880 }
881
882 fn set_template_static(&mut self, template: &'static [u8]) {
883 let template_bytes = glib::Bytes::from_static(template);
884 self.set_template_bytes(&template_bytes);
885 }
886
887 #[doc(alias = "gtk_widget_class_set_template_from_resource")]
888 fn set_template_from_resource(&mut self, resource_name: &str) {
889 unsafe {
890 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
891 ffi::gtk_widget_class_set_template_from_resource(
892 widget_class,
893 resource_name.to_glib_none().0,
894 );
895 }
896 }
897
898 fn install_action_async<Fut, F>(
899 &mut self,
900 action_name: &str,
901 parameter_type: Option<&glib::VariantTy>,
902 activate: F,
903 ) where
904 F: Fn(
905 <<Self as ClassStruct>::Type as ObjectSubclass>::Type,
906 String,
907 Option<Variant>,
908 ) -> Fut
909 + 'static
910 + Clone,
911 Fut: Future<Output = ()>,
912 {
913 self.install_action(
914 action_name,
915 parameter_type,
916 move |this, action_name, parameter_type| {
917 let ctx = glib::MainContext::default();
918 let action_name = action_name.to_owned();
919 let parameter_type = parameter_type.map(ToOwned::to_owned);
920 ctx.spawn_local(glib::clone!(
921 #[strong]
922 this,
923 #[strong]
924 action_name,
925 #[strong]
926 parameter_type,
927 #[strong]
928 activate,
929 async move {
930 activate(this, action_name, parameter_type).await;
931 }
932 ));
933 },
934 );
935 }
936
937 #[doc(alias = "gtk_widget_class_install_action")]
938 fn install_action<F>(
939 &mut self,
940 action_name: &str,
941 parameter_type: Option<&glib::VariantTy>,
942 activate: F,
943 ) where
944 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
945 + 'static,
946 {
947 unsafe {
948 let mut data = <Self::Type as ObjectSubclassType>::type_data();
951 let data = data.as_mut();
952
953 let f: Box_<F> = Box_::new(activate);
954
955 let internal = data
956 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
957 .expect("Something bad happened at class_init, the internal class_data is missing");
958 let callback_ptr = Box_::into_raw(f) as glib::ffi::gpointer;
959 internal
960 .actions
961 .insert(action_name.to_string(), callback_ptr);
962
963 unsafe extern "C" fn activate_trampoline<F, S>(
964 this: *mut ffi::GtkWidget,
965 action_name: *const libc::c_char,
966 parameter: *mut glib::ffi::GVariant,
967 ) where
968 S: ClassStruct,
969 <S as ClassStruct>::Type: ObjectSubclass,
970 F: Fn(&<<S as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
971 + 'static,
972 {
973 let action_name = GString::from_glib_borrow(action_name);
974
975 let data = <S::Type as ObjectSubclassType>::type_data();
976 let internal = data
977 .as_ref()
978 .class_data::<Internal>(<S::Type as ObjectSubclassType>::type_())
979 .unwrap();
980 let activate_callback = *internal
981 .actions
982 .get(&action_name.to_string())
983 .unwrap_or_else(|| {
984 panic!("Action name '{}' was not found", action_name.as_str());
985 });
986
987 let widget = Widget::from_glib_borrow(this);
988
989 let f: &F = &*(activate_callback as *const F);
990 f(
991 widget.unsafe_cast_ref(),
992 &action_name,
993 Option::<Variant>::from_glib_borrow(parameter)
994 .as_ref()
995 .as_ref(),
996 )
997 }
998 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
999 let callback = activate_trampoline::<F, Self>;
1000 ffi::gtk_widget_class_install_action(
1001 widget_class,
1002 action_name.to_glib_none().0,
1003 parameter_type.map(|p| p.as_str()).to_glib_none().0,
1004 Some(callback),
1005 );
1006 }
1007 }
1008
1009 #[doc(alias = "gtk_widget_class_query_action")]
1010 fn query_action(&self) -> WidgetActionIter {
1011 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1012 WidgetActionIter(widget_class, 0)
1013 }
1014
1015 #[doc(alias = "gtk_widget_class_set_template_scope")]
1016 fn set_template_scope<S: IsA<BuilderScope>>(&mut self, scope: &S) {
1017 unsafe {
1018 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1019 ffi::gtk_widget_class_set_template_scope(widget_class, scope.as_ref().to_glib_none().0);
1020 }
1021 }
1022
1023 #[doc(alias = "gtk_widget_class_add_binding")]
1024 fn add_binding<
1025 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type) -> glib::Propagation + 'static,
1026 >(
1027 &mut self,
1028 keyval: gdk::Key,
1029 mods: gdk::ModifierType,
1030 callback: F,
1031 ) {
1032 let shortcut = crate::Shortcut::new(
1033 Some(crate::KeyvalTrigger::new(keyval, mods)),
1034 Some(crate::CallbackAction::new(
1035 move |widget, _| -> glib::Propagation {
1036 unsafe { callback(widget.unsafe_cast_ref()) }
1037 },
1038 )),
1039 );
1040 self.add_shortcut(&shortcut);
1041 }
1042
1043 #[doc(alias = "gtk_widget_class_add_binding_action")]
1044 fn add_binding_action(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, action_name: &str) {
1045 let shortcut = crate::Shortcut::new(
1046 Some(crate::KeyvalTrigger::new(keyval, mods)),
1047 Some(crate::NamedAction::new(action_name)),
1048 );
1049 self.add_shortcut(&shortcut);
1050 }
1051
1052 #[doc(alias = "gtk_widget_class_add_binding_signal")]
1053 fn add_binding_signal(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, signal_name: &str) {
1054 let type_ = <Self::Type as ObjectSubclassType>::type_();
1055 assert!(
1056 SignalId::lookup(signal_name, type_).is_some(),
1057 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1058 );
1059
1060 let shortcut = crate::Shortcut::new(
1061 Some(crate::KeyvalTrigger::new(keyval, mods)),
1062 Some(crate::SignalAction::new(signal_name)),
1063 );
1064 self.add_shortcut(&shortcut);
1065 }
1066
1067 #[doc(alias = "gtk_widget_class_add_shortcut")]
1068 fn add_shortcut(&mut self, shortcut: &Shortcut) {
1069 unsafe {
1070 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1071 ffi::gtk_widget_class_add_shortcut(widget_class, shortcut.to_glib_none().0);
1072 }
1073 }
1074
1075 #[doc(alias = "gtk_widget_class_install_property_action")]
1076 fn install_property_action(&mut self, action_name: &str, property_name: &str) {
1077 unsafe {
1078 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1079 ffi::gtk_widget_class_install_property_action(
1080 widget_class,
1081 action_name.to_glib_none().0,
1082 property_name.to_glib_none().0,
1083 );
1084 }
1085 }
1086
1087 #[doc(alias = "gtk_widget_class_get_activate_signal")]
1088 #[doc(alias = "get_activate_signal")]
1089 fn activate_signal(&self) -> Option<SignalId> {
1090 unsafe {
1091 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1092 let signal_id = ffi::gtk_widget_class_get_activate_signal(widget_class);
1093 if signal_id == 0 {
1094 None
1095 } else {
1096 Some(from_glib(signal_id))
1097 }
1098 }
1099 }
1100
1101 #[doc(alias = "gtk_widget_class_set_activate_signal")]
1102 fn set_activate_signal(&mut self, signal_id: SignalId) {
1103 unsafe {
1104 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1105 ffi::gtk_widget_class_set_activate_signal(widget_class, signal_id.into_glib())
1106 }
1107 }
1108
1109 #[doc(alias = "gtk_widget_class_set_activate_signal_from_name")]
1110 fn set_activate_signal_from_name(&mut self, signal_name: &str) {
1111 let type_ = <Self::Type as ObjectSubclassType>::type_();
1112 assert!(
1113 SignalId::lookup(signal_name, type_).is_some(),
1114 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1115 );
1116
1117 unsafe {
1118 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1119 ffi::gtk_widget_class_set_activate_signal_from_name(
1120 widget_class,
1121 signal_name.to_glib_none().0,
1122 );
1123 }
1124 }
1125
1126 #[doc(alias = "gtk_widget_class_set_layout_manager_type")]
1127 fn set_layout_manager_type<T: IsA<LayoutManager>>(&mut self) {
1128 unsafe {
1129 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1130 ffi::gtk_widget_class_set_layout_manager_type(
1131 widget_class,
1132 T::static_type().into_glib(),
1133 );
1134 }
1135 }
1136
1137 #[doc(alias = "gtk_widget_class_get_layout_manager_type")]
1138 #[doc(alias = "get_layout_manager_type")]
1139 fn layout_manager_type(&self) -> glib::Type {
1140 unsafe {
1141 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1142 from_glib(ffi::gtk_widget_class_get_layout_manager_type(widget_class))
1143 }
1144 }
1145
1146 #[doc(alias = "gtk_widget_class_set_css_name")]
1147 fn set_css_name(&mut self, name: &str) {
1148 unsafe {
1149 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1150 ffi::gtk_widget_class_set_css_name(widget_class, name.to_glib_none().0);
1151 }
1152 }
1153
1154 #[doc(alias = "gtk_widget_class_get_css_name")]
1155 #[doc(alias = "get_css_name")]
1156 fn css_name(&self) -> glib::GString {
1157 unsafe {
1158 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1159 from_glib_none(ffi::gtk_widget_class_get_css_name(widget_class))
1160 }
1161 }
1162
1163 #[doc(alias = "gtk_widget_class_set_accessible_role")]
1164 fn set_accessible_role(&mut self, role: AccessibleRole) {
1165 unsafe {
1166 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1167 ffi::gtk_widget_class_set_accessible_role(widget_class, role.into_glib());
1168 }
1169 }
1170
1171 #[doc(alias = "gtk_widget_class_get_accessible_role")]
1172 #[doc(alias = "get_accessible_role")]
1173 fn accessible_role(&self) -> AccessibleRole {
1174 unsafe {
1175 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1176 from_glib(ffi::gtk_widget_class_get_accessible_role(widget_class))
1177 }
1178 }
1179
1180 #[allow(clippy::missing_safety_doc)]
1181 #[doc(alias = "gtk_widget_class_bind_template_child_full")]
1182 unsafe fn bind_template_child_with_offset<T>(
1183 &mut self,
1184 name: &str,
1185 internal: bool,
1186 offset: field_offset::FieldOffset<Self::Type, TemplateChild<T>>,
1187 ) where
1188 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1189 {
1190 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1191 let private_offset = <Self::Type as ObjectSubclassType>::type_data()
1192 .as_ref()
1193 .impl_offset();
1194 ffi::gtk_widget_class_bind_template_child_full(
1195 widget_class,
1196 name.to_glib_none().0,
1197 internal.into_glib(),
1198 private_offset + (offset.get_byte_offset() as isize),
1199 )
1200 }
1201
1202 fn rust_template_scope(&mut self) -> BuilderRustScope {
1203 assert_initialized_main_thread!();
1204 unsafe {
1205 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1206 let internal = data
1207 .as_mut()
1208 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1209 .expect("Something bad happened at class_init, the internal class_data is missing");
1210 let scope = internal.scope.get_or_insert_with(|| {
1211 let scope = BuilderRustScope::new();
1212 self.set_template_scope(&scope);
1213 scope.into_glib_ptr()
1214 });
1215 from_glib_none(*scope)
1216 }
1217 }
1218}
1219
1220unsafe impl<T: ClassStruct> WidgetClassExt for T where T::Type: WidgetImpl {}
1221
1222#[derive(Debug, PartialEq, Eq)]
1223#[repr(transparent)]
1224pub struct TemplateChild<T>
1225where
1226 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1227{
1228 ptr: *mut <T as ObjectType>::GlibType,
1229}
1230
1231impl<T: Property> Property for TemplateChild<T>
1232where
1233 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1234{
1235 type Value = T::Value;
1236}
1237
1238impl<T> Default for TemplateChild<T>
1239where
1240 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1241{
1242 fn default() -> Self {
1243 T::static_type();
1244
1245 Self {
1246 ptr: std::ptr::null_mut(),
1247 }
1248 }
1249}
1250
1251impl<T> PropertyGet for TemplateChild<T>
1252where
1253 T: Property + ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1254{
1255 type Value = T;
1256
1257 fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
1258 f(&self.get())
1259 }
1260}
1261
1262impl<T> std::ops::Deref for TemplateChild<T>
1263where
1264 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1265{
1266 type Target = T;
1267
1268 #[inline]
1269 fn deref(&self) -> &Self::Target {
1270 unsafe {
1271 if !self.is_bound() {
1272 let name = Self::name();
1273 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1274 }
1275 &*(&self.ptr as *const _ as *const T)
1276 }
1277 }
1278}
1279
1280impl<T> Downgrade for TemplateChild<T>
1281where
1282 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType> + Downgrade,
1283{
1284 type Weak = T::Weak;
1285
1286 fn downgrade(&self) -> Self::Weak {
1287 T::downgrade(&self.get())
1288 }
1289}
1290
1291impl<T> TemplateChild<T>
1292where
1293 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1294{
1295 pub(crate) fn name<'a>() -> &'a str {
1296 T::static_type().name()
1297 }
1298
1299 #[track_caller]
1300 pub fn get(&self) -> T {
1301 self.try_get()
1302 .unwrap_or_else(|| {
1303 let name = Self::name();
1304 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1305 })
1306 }
1307
1308 pub fn is_bound(&self) -> bool {
1312 !self.ptr.is_null()
1313 }
1314
1315 pub fn try_get(&self) -> Option<T> {
1318 unsafe { Option::<T>::from_glib_none(self.ptr) }
1319 }
1320}
1321
1322pub trait CompositeTemplate: WidgetImpl {
1328 fn bind_template(klass: &mut Self::Class);
1329 fn check_template_children(widget: &<Self as ObjectSubclass>::Type);
1330}
1331
1332pub trait CompositeTemplateClass {
1337 fn bind_template(&mut self);
1341}
1342
1343impl<T, U> CompositeTemplateClass for T
1344where
1345 T: ClassStruct<Type = U>,
1346 U: ObjectSubclass<Class = T> + CompositeTemplate,
1347{
1348 fn bind_template(&mut self) {
1349 <U as CompositeTemplate>::bind_template(self);
1350 }
1351}
1352
1353pub type TemplateCallback = (&'static str, fn(&[glib::Value]) -> Option<glib::Value>);
1354
1355pub trait CompositeTemplateCallbacks {
1361 const CALLBACKS: &'static [TemplateCallback];
1362
1363 fn bind_template_callbacks<T: WidgetClassExt>(klass: &mut T) {
1367 Self::add_callbacks_to_scope(&klass.rust_template_scope());
1368 }
1369 fn bind_template_callbacks_prefixed<T: WidgetClassExt>(klass: &mut T, prefix: &str) {
1373 Self::add_callbacks_to_scope_prefixed(&klass.rust_template_scope(), prefix);
1374 }
1375 fn add_callbacks_to_scope(scope: &BuilderRustScope) {
1378 for (name, func) in Self::CALLBACKS {
1379 scope.add_callback(*name, func);
1380 }
1381 }
1382 fn add_callbacks_to_scope_prefixed(scope: &BuilderRustScope, prefix: &str) {
1386 for (name, func) in Self::CALLBACKS {
1387 scope.add_callback(format!("{prefix}{name}"), func);
1388 }
1389 }
1390}
1391
1392pub trait CompositeTemplateCallbacksClass {
1397 fn bind_template_callbacks(&mut self);
1401}
1402
1403impl<T, U> CompositeTemplateCallbacksClass for T
1404where
1405 T: ClassStruct<Type = U> + WidgetClassExt,
1406 U: ObjectSubclass<Class = T> + CompositeTemplateCallbacks,
1407{
1408 fn bind_template_callbacks(&mut self) {
1409 <U as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1410 }
1411}
1412
1413pub trait CompositeTemplateInstanceCallbacksClass {
1419 fn bind_template_instance_callbacks(&mut self);
1423}
1424
1425impl<T, U, V> CompositeTemplateInstanceCallbacksClass for T
1426where
1427 T: ClassStruct<Type = U> + WidgetClassExt,
1428 U: ObjectSubclass<Class = T, Type = V>,
1429 V: CompositeTemplateCallbacks,
1430{
1431 fn bind_template_instance_callbacks(&mut self) {
1432 <V as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1433 }
1434}
1435
1436pub trait CompositeTemplateInitializingExt {
1437 fn init_template(&self);
1438}
1439
1440impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateInitializingExt
1441 for glib::subclass::InitializingObject<T>
1442{
1443 fn init_template(&self) {
1444 unsafe {
1445 let widget = self
1446 .as_ref()
1447 .unsafe_cast_ref::<<T as ObjectSubclass>::Type>();
1448 ffi::gtk_widget_init_template(AsRef::<Widget>::as_ref(widget).to_glib_none().0);
1449
1450 <T as CompositeTemplate>::check_template_children(widget);
1451 }
1452 }
1453}
1454
1455pub trait CompositeTemplateDisposeExt {
1456 #[cfg(feature = "v4_8")]
1457 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1458 fn dispose_template(&self);
1459}
1460
1461impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateDisposeExt for T {
1462 #[cfg(feature = "v4_8")]
1463 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1464 fn dispose_template(&self) {
1465 unsafe {
1466 ffi::gtk_widget_dispose_template(
1467 self.obj().upcast_ref::<Widget>().to_glib_none().0,
1468 <T as ObjectSubclass>::Type::static_type().into_glib(),
1469 );
1470 }
1471 }
1472}