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