Skip to main content

gtk/subclass/
widget.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use libc::c_int;
4use std::mem;
5
6use glib::prelude::*;
7use glib::subclass::prelude::*;
8use glib::translate::*;
9use glib::Propagation;
10
11use crate::prelude::*;
12use crate::Allocation;
13use crate::DragResult;
14use crate::Orientation;
15use crate::SelectionData;
16use crate::SizeRequestMode;
17use crate::TextDirection;
18use crate::Widget;
19
20pub trait WidgetImpl: WidgetImplExt + ObjectImpl {
21    fn adjust_baseline_allocation(&self, baseline: &mut i32) {
22        self.parent_adjust_baseline_allocation(baseline)
23    }
24
25    fn adjust_baseline_request(&self, minimum_baseline: &mut i32, natural_baseline: &mut i32) {
26        self.parent_adjust_baseline_request(minimum_baseline, natural_baseline)
27    }
28
29    fn adjust_size_allocation(
30        &self,
31
32        orientation: Orientation,
33        minimum_size: &mut i32,
34        natural_size: &mut i32,
35        allocated_pos: &mut i32,
36        allocated_size: &mut i32,
37    ) {
38        self.parent_adjust_size_allocation(
39            orientation,
40            minimum_size,
41            natural_size,
42            allocated_pos,
43            allocated_size,
44        )
45    }
46
47    fn adjust_size_request(
48        &self,
49
50        orientation: Orientation,
51        minimum_size: &mut i32,
52        natural_size: &mut i32,
53    ) {
54        self.parent_adjust_size_request(orientation, minimum_size, natural_size)
55    }
56
57    fn button_press_event(&self, event: &gdk::EventButton) -> Propagation {
58        self.parent_button_press_event(event)
59    }
60
61    fn button_release_event(&self, event: &gdk::EventButton) -> Propagation {
62        self.parent_button_release_event(event)
63    }
64
65    /// Emits a [`child-notify`][struct@crate::Widget#child-notify] signal for the
66    /// [child property][child-properties] `child_property`
67    /// on `self`.
68    ///
69    /// This is the analogue of [`ObjectExt::notify()`][crate::glib::prelude::ObjectExt::notify()] for child properties.
70    ///
71    /// Also see [`ContainerExt::child_notify()`][crate::prelude::ContainerExt::child_notify()].
72    /// ## `child_property`
73    /// the name of a child property installed on the
74    ///  class of `self`’s parent
75    fn child_notify(&self, child_property: &glib::ParamSpec) {
76        self.parent_child_notify(child_property)
77    }
78
79    fn composited_changed(&self) {
80        self.parent_composited_changed()
81    }
82
83    fn compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
84        self.parent_compute_expand(hexpand, vexpand)
85    }
86
87    fn configure_event(&self, event: &gdk::EventConfigure) -> Propagation {
88        self.parent_configure_event(event)
89    }
90
91    fn window_state_event(&self, event: &gdk::EventWindowState) -> Propagation {
92        self.parent_window_state_event(event)
93    }
94
95    fn damage_event(&self, event: &gdk::EventExpose) -> Propagation {
96        self.parent_damage_event(event)
97    }
98
99    fn delete_event(&self, event: &gdk::Event) -> Propagation {
100        self.parent_delete_event(event)
101    }
102
103    fn destroy(&self) {
104        self.parent_destroy()
105    }
106
107    fn destroy_event(&self, event: &gdk::Event) -> Propagation {
108        self.parent_destroy_event(event)
109    }
110
111    fn direction_changed(&self, previous_direction: TextDirection) {
112        self.parent_direction_changed(previous_direction)
113    }
114
115    fn dispatch_child_properties_changed(&self, pspecs: &[glib::ParamSpec]) {
116        self.parent_dispatch_child_properties_changed(pspecs)
117    }
118
119    fn drag_begin(&self, context: &gdk::DragContext) {
120        self.parent_drag_begin(context)
121    }
122
123    fn drag_data_delete(&self, context: &gdk::DragContext) {
124        self.parent_drag_data_delete(context)
125    }
126
127    fn drag_data_get(
128        &self,
129
130        context: &gdk::DragContext,
131        selection_data: &SelectionData,
132        info: u32,
133        time: u32,
134    ) {
135        self.parent_drag_data_get(context, selection_data, info, time)
136    }
137
138    fn drag_data_received(
139        &self,
140
141        context: &gdk::DragContext,
142        x: i32,
143        y: i32,
144        selection_data: &SelectionData,
145        info: u32,
146        time: u32,
147    ) {
148        self.parent_drag_data_received(context, x, y, selection_data, info, time)
149    }
150
151    fn drag_drop(&self, context: &gdk::DragContext, x: i32, y: i32, time: u32) -> Propagation {
152        self.parent_drag_drop(context, x, y, time)
153    }
154
155    fn drag_end(&self, context: &gdk::DragContext) {
156        self.parent_drag_end(context)
157    }
158
159    fn drag_failed(&self, context: &gdk::DragContext, result: DragResult) -> Propagation {
160        self.parent_drag_failed(context, result)
161    }
162
163    fn drag_leave(&self, context: &gdk::DragContext, time: u32) {
164        self.parent_drag_leave(context, time)
165    }
166
167    fn drag_motion(&self, context: &gdk::DragContext, x: i32, y: i32, time: u32) -> Propagation {
168        self.parent_drag_motion(context, x, y, time)
169    }
170
171    fn draw(&self, cr: &cairo::Context) -> Propagation {
172        self.parent_draw(cr)
173    }
174
175    // fn can_activate_accel(&self, signal_id: u32) -> bool {
176    //     self.parent_can_activate_accel( signal_id)
177    // }
178
179    /// Gets whether the widget prefers a height-for-width layout
180    /// or a width-for-height layout.
181    ///
182    /// [`Bin`][crate::Bin] widgets generally propagate the preference of
183    /// their child, container widgets need to request something either in
184    /// context of their children or in context of their allocation
185    /// capabilities.
186    ///
187    /// # Returns
188    ///
189    /// The [`SizeRequestMode`][crate::SizeRequestMode] preferred by `self`.
190    fn request_mode(&self) -> SizeRequestMode {
191        self.parent_request_mode()
192    }
193
194    /// Retrieves a widget’s initial minimum and natural width.
195    ///
196    /// This call is specific to height-for-width requests.
197    ///
198    /// The returned request will be modified by the
199    /// GtkWidgetClass::adjust_size_request virtual method and by any
200    /// `GtkSizeGroups` that have been applied. That is, the returned request
201    /// is the one that should be used for layout, not necessarily the one
202    /// returned by the widget itself.
203    ///
204    /// # Returns
205    ///
206    ///
207    /// ## `minimum_width`
208    /// location to store the minimum width, or [`None`]
209    ///
210    /// ## `natural_width`
211    /// location to store the natural width, or [`None`]
212    fn preferred_width(&self) -> (i32, i32) {
213        self.parent_preferred_width()
214    }
215
216    /// Retrieves a widget’s minimum and natural width if it would be given
217    /// the specified `height`.
218    ///
219    /// The returned request will be modified by the
220    /// GtkWidgetClass::adjust_size_request virtual method and by any
221    /// `GtkSizeGroups` that have been applied. That is, the returned request
222    /// is the one that should be used for layout, not necessarily the one
223    /// returned by the widget itself.
224    /// ## `height`
225    /// the height which is available for allocation
226    ///
227    /// # Returns
228    ///
229    ///
230    /// ## `minimum_width`
231    /// location for storing the minimum width, or [`None`]
232    ///
233    /// ## `natural_width`
234    /// location for storing the natural width, or [`None`]
235    #[doc(alias = "get_preferred_width_for_height")]
236    fn preferred_width_for_height(&self, height: i32) -> (i32, i32) {
237        self.parent_preferred_width_for_height(height)
238    }
239
240    /// Retrieves a widget’s initial minimum and natural height.
241    ///
242    /// This call is specific to width-for-height requests.
243    ///
244    /// The returned request will be modified by the
245    /// GtkWidgetClass::adjust_size_request virtual method and by any
246    /// `GtkSizeGroups` that have been applied. That is, the returned request
247    /// is the one that should be used for layout, not necessarily the one
248    /// returned by the widget itself.
249    ///
250    /// # Returns
251    ///
252    ///
253    /// ## `minimum_height`
254    /// location to store the minimum height, or [`None`]
255    ///
256    /// ## `natural_height`
257    /// location to store the natural height, or [`None`]
258    fn preferred_height(&self) -> (i32, i32) {
259        self.parent_preferred_height()
260    }
261
262    /// Retrieves a widget’s minimum and natural height if it would be given
263    /// the specified `width`.
264    ///
265    /// The returned request will be modified by the
266    /// GtkWidgetClass::adjust_size_request virtual method and by any
267    /// `GtkSizeGroups` that have been applied. That is, the returned request
268    /// is the one that should be used for layout, not necessarily the one
269    /// returned by the widget itself.
270    /// ## `width`
271    /// the width which is available for allocation
272    ///
273    /// # Returns
274    ///
275    ///
276    /// ## `minimum_height`
277    /// location for storing the minimum height, or [`None`]
278    ///
279    /// ## `natural_height`
280    /// location for storing the natural height, or [`None`]
281    #[doc(alias = "get_preferred_height_for_width")]
282    fn preferred_height_for_width(&self, width: i32) -> (i32, i32) {
283        self.parent_preferred_height_for_width(width)
284    }
285
286    /// This function is only used by [`Container`][crate::Container] subclasses, to assign a size
287    /// and position to their child widgets.
288    ///
289    /// In this function, the allocation may be adjusted. It will be forced
290    /// to a 1x1 minimum size, and the adjust_size_allocation virtual
291    /// method on the child will be used to adjust the allocation. Standard
292    /// adjustments include removing the widget’s margins, and applying the
293    /// widget’s [`halign`][struct@crate::Widget#halign] and [`valign`][struct@crate::Widget#valign] properties.
294    ///
295    /// For baseline support in containers you need to use [`WidgetExt::size_allocate_with_baseline()`][crate::prelude::WidgetExt::size_allocate_with_baseline()]
296    /// instead.
297    /// ## `allocation`
298    /// position and size to be allocated to `self`
299    fn size_allocate(&self, allocation: &Allocation) {
300        self.parent_size_allocate(allocation)
301    }
302
303    /// Creates the GDK (windowing system) resources associated with a
304    /// widget. For example, `self`->window will be created when a widget
305    /// is realized. Normally realization happens implicitly; if you show
306    /// a widget and all its parent containers, then the widget will be
307    /// realized and mapped automatically.
308    ///
309    /// Realizing a widget requires all
310    /// the widget’s parent widgets to be realized; calling
311    /// [`WidgetExt::realize()`][crate::prelude::WidgetExt::realize()] realizes the widget’s parents in addition to
312    /// `self` itself. If a widget is not yet inside a toplevel window
313    /// when you realize it, bad things will happen.
314    ///
315    /// This function is primarily used in widget implementations, and
316    /// isn’t very useful otherwise. Many times when you think you might
317    /// need it, a better approach is to connect to a signal that will be
318    /// called after the widget is realized automatically, such as
319    /// [`draw`][struct@crate::Widget#draw]. Or simply g_signal_connect () to the
320    /// [`realize`][struct@crate::Widget#realize] signal.
321    fn realize(&self) {
322        self.parent_realize();
323    }
324
325    /// This function is only useful in widget implementations.
326    /// Causes a widget to be unrealized (frees all GDK resources
327    /// associated with the widget, such as `self`->window).
328    fn unrealize(&self) {
329        self.parent_unrealize();
330    }
331    /// This function is only for use in widget implementations. Causes
332    /// a widget to be mapped if it isn’t already.
333    fn map(&self) {
334        self.parent_map();
335    }
336
337    /// This function is only for use in widget implementations. Causes
338    /// a widget to be unmapped if it’s currently mapped.
339    fn unmap(&self) {
340        self.parent_unmap();
341    }
342
343    fn motion_notify_event(&self, event: &gdk::EventMotion) -> Propagation {
344        self.parent_motion_notify_event(event)
345    }
346
347    fn scroll_event(&self, event: &gdk::EventScroll) -> Propagation {
348        self.parent_scroll_event(event)
349    }
350
351    fn enter_notify_event(&self, event: &gdk::EventCrossing) -> Propagation {
352        self.parent_enter_notify_event(event)
353    }
354
355    fn leave_notify_event(&self, event: &gdk::EventCrossing) -> Propagation {
356        self.parent_leave_notify_event(event)
357    }
358}
359
360mod sealed {
361    pub trait Sealed {}
362    impl<T: super::WidgetImpl> Sealed for T {}
363}
364
365pub trait WidgetImplExt: ObjectSubclass + sealed::Sealed {
366    fn parent_adjust_baseline_allocation(&self, baseline: &mut i32) {
367        unsafe {
368            let data = Self::type_data();
369            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
370            let f = (*parent_class)
371                .adjust_baseline_allocation
372                .expect("No parent class impl for \"adjust_baseline_allocation\"");
373            f(
374                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
375                baseline,
376            )
377        }
378    }
379    fn parent_adjust_baseline_request(
380        &self,
381
382        minimum_baseline: &mut i32,
383        natural_baseline: &mut i32,
384    ) {
385        unsafe {
386            let data = Self::type_data();
387            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
388            let f = (*parent_class)
389                .adjust_baseline_request
390                .expect("No parent class impl for \"adjust_baseline_request\"");
391            f(
392                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
393                minimum_baseline,
394                natural_baseline,
395            )
396        }
397    }
398    fn parent_adjust_size_allocation(
399        &self,
400
401        orientation: Orientation,
402        minimum_size: &mut i32,
403        natural_size: &mut i32,
404        allocated_pos: &mut i32,
405        allocated_size: &mut i32,
406    ) {
407        unsafe {
408            let data = Self::type_data();
409            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
410            let f = (*parent_class)
411                .adjust_size_allocation
412                .expect("No parent class impl for \"adjust_size_allocation\"");
413            f(
414                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
415                orientation.into_glib(),
416                minimum_size,
417                natural_size,
418                allocated_pos,
419                allocated_size,
420            )
421        }
422    }
423    fn parent_adjust_size_request(
424        &self,
425
426        orientation: Orientation,
427        minimum_size: &mut i32,
428        natural_size: &mut i32,
429    ) {
430        unsafe {
431            let data = Self::type_data();
432            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
433            let f = (*parent_class)
434                .adjust_size_request
435                .expect("No parent class impl for \"adjust_size_request\"");
436            f(
437                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
438                orientation.into_glib(),
439                minimum_size as *mut i32,
440                natural_size as *mut i32,
441            )
442        }
443    }
444    fn parent_button_press_event(&self, event: &gdk::EventButton) -> Propagation {
445        unsafe {
446            let data = Self::type_data();
447            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
448            if let Some(f) = (*parent_class).button_press_event {
449                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
450                Propagation::from_glib(f(
451                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
452                    ev_glib,
453                ))
454            } else {
455                Propagation::Proceed
456            }
457        }
458    }
459    fn parent_button_release_event(&self, event: &gdk::EventButton) -> Propagation {
460        unsafe {
461            let data = Self::type_data();
462            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
463            if let Some(f) = (*parent_class).button_release_event {
464                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
465                Propagation::from_glib(f(
466                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
467                    ev_glib,
468                ))
469            } else {
470                Propagation::Proceed
471            }
472        }
473    }
474    // fn parent_can_activate_accel(&self, signal_id: u32) -> bool;
475    fn parent_child_notify(&self, child_property: &glib::ParamSpec) {
476        unsafe {
477            let data = Self::type_data();
478            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
479            if let Some(f) = (*parent_class).child_notify {
480                let pspec_glib = glib::translate::mut_override(child_property.to_glib_none().0);
481                f(
482                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
483                    pspec_glib,
484                )
485            }
486        }
487    }
488    fn parent_composited_changed(&self) {
489        unsafe {
490            let data = Self::type_data();
491            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
492            if let Some(f) = (*parent_class).composited_changed {
493                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
494            }
495        }
496    }
497    fn parent_compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
498        unsafe {
499            let data = Self::type_data();
500            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
501            let widget = self.obj();
502            let widget = widget.unsafe_cast_ref::<Widget>();
503            if let Some(f) = (*parent_class).compute_expand {
504                let mut hexpand_glib = hexpand.into_glib();
505                let mut vexpand_glib = vexpand.into_glib();
506                f(
507                    widget.to_glib_none().0,
508                    &mut hexpand_glib,
509                    &mut vexpand_glib,
510                );
511                *hexpand = from_glib(hexpand_glib);
512                *vexpand = from_glib(vexpand_glib);
513            }
514        }
515    }
516    fn parent_configure_event(&self, event: &gdk::EventConfigure) -> Propagation {
517        unsafe {
518            let data = Self::type_data();
519            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
520            if let Some(f) = (*parent_class).configure_event {
521                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
522                Propagation::from_glib(f(
523                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
524                    ev_glib,
525                ))
526            } else {
527                Propagation::Proceed
528            }
529        }
530    }
531    fn parent_window_state_event(&self, event: &gdk::EventWindowState) -> Propagation {
532        unsafe {
533            let data = Self::type_data();
534            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
535            if let Some(f) = (*parent_class).window_state_event {
536                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
537                Propagation::from_glib(f(
538                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
539                    ev_glib,
540                ))
541            } else {
542                Propagation::Proceed
543            }
544        }
545    }
546    fn parent_damage_event(&self, event: &gdk::EventExpose) -> Propagation {
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).damage_event {
551                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
552                Propagation::from_glib(f(
553                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
554                    ev_glib,
555                ))
556            } else {
557                Propagation::Proceed
558            }
559        }
560    }
561    fn parent_delete_event(&self, event: &gdk::Event) -> Propagation {
562        unsafe {
563            let data = Self::type_data();
564            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
565            if let Some(f) = (*parent_class).delete_event {
566                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
567                Propagation::from_glib(f(
568                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
569                    ev_glib,
570                ))
571            } else {
572                Propagation::Proceed
573            }
574        }
575    }
576    fn parent_destroy(&self) {
577        unsafe {
578            let data = Self::type_data();
579            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
580            if let Some(f) = (*parent_class).destroy {
581                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
582            }
583        }
584    }
585    fn parent_destroy_event(&self, event: &gdk::Event) -> Propagation {
586        unsafe {
587            let data = Self::type_data();
588            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
589            if let Some(f) = (*parent_class).destroy_event {
590                let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
591                Propagation::from_glib(f(
592                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
593                    ev_glib,
594                ))
595            } else {
596                Propagation::Proceed
597            }
598        }
599    }
600    fn parent_direction_changed(&self, previous_direction: TextDirection) {
601        unsafe {
602            let data = Self::type_data();
603            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
604            if let Some(f) = (*parent_class).direction_changed {
605                f(
606                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
607                    previous_direction.into_glib(),
608                )
609            }
610        }
611    }
612    fn parent_dispatch_child_properties_changed(&self, pspecs: &[glib::ParamSpec]) {
613        unsafe {
614            let data = Self::type_data();
615            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
616            if let Some(f) = (*parent_class).dispatch_child_properties_changed {
617                let mut pspecs_array = pspecs
618                    .iter()
619                    .map(|p| p.to_glib_none().0)
620                    .collect::<Vec<_>>();
621                let pspecs_ptr = pspecs_array.as_mut_ptr();
622                f(
623                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
624                    pspecs.len() as u32,
625                    pspecs_ptr,
626                )
627            }
628        }
629    }
630    fn parent_drag_begin(&self, context: &gdk::DragContext) {
631        unsafe {
632            let data = Self::type_data();
633            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
634            if let Some(f) = (*parent_class).drag_begin {
635                f(
636                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
637                    context.to_glib_none().0,
638                )
639            }
640        }
641    }
642    fn parent_drag_data_delete(&self, context: &gdk::DragContext) {
643        unsafe {
644            let data = Self::type_data();
645            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
646            if let Some(f) = (*parent_class).drag_data_delete {
647                f(
648                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
649                    context.to_glib_none().0,
650                )
651            }
652        }
653    }
654    fn parent_drag_data_get(
655        &self,
656
657        context: &gdk::DragContext,
658        selection_data: &SelectionData,
659        info: u32,
660        time: u32,
661    ) {
662        unsafe {
663            let data = Self::type_data();
664            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
665            if let Some(f) = (*parent_class).drag_data_get {
666                let selection_mut = glib::translate::mut_override(selection_data.to_glib_none().0);
667                f(
668                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
669                    context.to_glib_none().0,
670                    selection_mut,
671                    info,
672                    time,
673                )
674            }
675        }
676    }
677    fn parent_drag_data_received(
678        &self,
679
680        context: &gdk::DragContext,
681        x: i32,
682        y: i32,
683        selection_data: &SelectionData,
684        info: u32,
685        time: u32,
686    ) {
687        unsafe {
688            let data = Self::type_data();
689            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
690            if let Some(f) = (*parent_class).drag_data_received {
691                let selection_mut = glib::translate::mut_override(selection_data.to_glib_none().0);
692                f(
693                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
694                    context.to_glib_none().0,
695                    x,
696                    y,
697                    selection_mut,
698                    info,
699                    time,
700                )
701            }
702        }
703    }
704    fn parent_drag_drop(
705        &self,
706        context: &gdk::DragContext,
707        x: i32,
708        y: i32,
709        time: u32,
710    ) -> Propagation {
711        unsafe {
712            let data = Self::type_data();
713            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
714            if let Some(f) = (*parent_class).drag_drop {
715                Propagation::from_glib(f(
716                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
717                    context.to_glib_none().0,
718                    x,
719                    y,
720                    time,
721                ))
722            } else {
723                Propagation::Proceed
724            }
725        }
726    }
727    fn parent_drag_end(&self, context: &gdk::DragContext) {
728        unsafe {
729            let data = Self::type_data();
730            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
731            if let Some(f) = (*parent_class).drag_end {
732                f(
733                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
734                    context.to_glib_none().0,
735                )
736            }
737        }
738    }
739    fn parent_drag_failed(&self, context: &gdk::DragContext, result: DragResult) -> Propagation {
740        unsafe {
741            let data = Self::type_data();
742            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
743            if let Some(f) = (*parent_class).drag_failed {
744                Propagation::from_glib(f(
745                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
746                    context.to_glib_none().0,
747                    result.into_glib(),
748                ))
749            } else {
750                Propagation::Proceed
751            }
752        }
753    }
754    fn parent_drag_leave(&self, context: &gdk::DragContext, time: u32) {
755        unsafe {
756            let data = Self::type_data();
757            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
758            if let Some(f) = (*parent_class).drag_leave {
759                f(
760                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
761                    context.to_glib_none().0,
762                    time,
763                )
764            }
765        }
766    }
767    fn parent_drag_motion(
768        &self,
769        context: &gdk::DragContext,
770        x: i32,
771        y: i32,
772        time: u32,
773    ) -> Propagation {
774        unsafe {
775            let data = Self::type_data();
776            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
777            if let Some(f) = (*parent_class).drag_motion {
778                Propagation::from_glib(f(
779                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
780                    context.to_glib_none().0,
781                    x,
782                    y,
783                    time,
784                ))
785            } else {
786                Propagation::Proceed
787            }
788        }
789    }
790    fn parent_draw(&self, cr: &cairo::Context) -> Propagation {
791        unsafe {
792            let data = Self::type_data();
793            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
794            if let Some(f) = (*parent_class).draw {
795                Propagation::from_glib(f(
796                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
797                    cr.to_glib_none().0,
798                ))
799            } else {
800                Propagation::Proceed
801            }
802        }
803    }
804    fn parent_request_mode(&self) -> SizeRequestMode {
805        unsafe {
806            let data = Self::type_data();
807            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
808            let f = (*parent_class).get_request_mode.unwrap();
809            from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
810        }
811    }
812    fn parent_preferred_width(&self) -> (i32, i32) {
813        unsafe {
814            let data = Self::type_data();
815            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
816            let f = (*parent_class).get_preferred_width.unwrap();
817
818            let mut minimum_size = mem::MaybeUninit::uninit();
819            let mut natural_size = mem::MaybeUninit::uninit();
820            f(
821                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
822                minimum_size.as_mut_ptr(),
823                natural_size.as_mut_ptr(),
824            );
825            (minimum_size.assume_init(), natural_size.assume_init())
826        }
827    }
828    fn parent_preferred_width_for_height(&self, height: i32) -> (i32, i32) {
829        unsafe {
830            let data = Self::type_data();
831            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
832            let f = (*parent_class).get_preferred_width_for_height.unwrap();
833
834            let mut minimum_size = mem::MaybeUninit::uninit();
835            let mut natural_size = mem::MaybeUninit::uninit();
836            f(
837                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
838                height,
839                minimum_size.as_mut_ptr(),
840                natural_size.as_mut_ptr(),
841            );
842            (minimum_size.assume_init(), natural_size.assume_init())
843        }
844    }
845    fn parent_preferred_height(&self) -> (i32, i32) {
846        unsafe {
847            let data = Self::type_data();
848            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
849            let f = (*parent_class).get_preferred_height.unwrap();
850            let mut minimum_size = mem::MaybeUninit::uninit();
851            let mut natural_size = mem::MaybeUninit::uninit();
852            f(
853                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
854                minimum_size.as_mut_ptr(),
855                natural_size.as_mut_ptr(),
856            );
857            (minimum_size.assume_init(), natural_size.assume_init())
858        }
859    }
860    fn parent_preferred_height_for_width(&self, width: i32) -> (i32, i32) {
861        unsafe {
862            let data = Self::type_data();
863            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
864            let f = (*parent_class).get_preferred_height_for_width.unwrap();
865            let mut minimum_size = mem::MaybeUninit::uninit();
866            let mut natural_size = mem::MaybeUninit::uninit();
867            f(
868                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
869                width,
870                minimum_size.as_mut_ptr(),
871                natural_size.as_mut_ptr(),
872            );
873            (minimum_size.assume_init(), natural_size.assume_init())
874        }
875    }
876    fn parent_size_allocate(&self, allocation: &Allocation) {
877        unsafe {
878            let data = Self::type_data();
879            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
880            let f = (*parent_class)
881                .size_allocate
882                .expect("No parent class impl for \"size_allocate\"");
883            f(
884                self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
885                mut_override(allocation.to_glib_none().0),
886            );
887        }
888    }
889    fn parent_realize(&self) {
890        unsafe {
891            let data = Self::type_data();
892            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
893            if let Some(f) = (*parent_class).realize {
894                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0);
895            }
896        }
897    }
898    fn parent_unrealize(&self) {
899        unsafe {
900            let data = Self::type_data();
901            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
902            if let Some(f) = (*parent_class).unrealize {
903                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0);
904            }
905        }
906    }
907    fn parent_map(&self) {
908        unsafe {
909            let data = Self::type_data();
910            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
911            if let Some(f) = (*parent_class).map {
912                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0);
913            }
914        }
915    }
916    fn parent_unmap(&self) {
917        unsafe {
918            let data = Self::type_data();
919            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
920            if let Some(f) = (*parent_class).unmap {
921                f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0);
922            }
923        }
924    }
925    fn parent_motion_notify_event(&self, event: &gdk::EventMotion) -> Propagation {
926        unsafe {
927            let data = Self::type_data();
928            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
929            if let Some(f) = (*parent_class).motion_notify_event {
930                Propagation::from_glib(f(
931                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
932                    mut_override(event.to_glib_none().0),
933                ))
934            } else {
935                Propagation::Proceed
936            }
937        }
938    }
939    fn parent_scroll_event(&self, event: &gdk::EventScroll) -> Propagation {
940        unsafe {
941            let data = Self::type_data();
942            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
943            if let Some(f) = (*parent_class).scroll_event {
944                Propagation::from_glib(f(
945                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
946                    mut_override(event.to_glib_none().0),
947                ))
948            } else {
949                Propagation::Proceed
950            }
951        }
952    }
953    fn parent_enter_notify_event(&self, event: &gdk::EventCrossing) -> Propagation {
954        unsafe {
955            let data = Self::type_data();
956            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
957            if let Some(f) = (*parent_class).enter_notify_event {
958                Propagation::from_glib(f(
959                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
960                    mut_override(event.to_glib_none().0),
961                ))
962            } else {
963                Propagation::Proceed
964            }
965        }
966    }
967    fn parent_leave_notify_event(&self, event: &gdk::EventCrossing) -> Propagation {
968        unsafe {
969            let data = Self::type_data();
970            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
971            if let Some(f) = (*parent_class).leave_notify_event {
972                Propagation::from_glib(f(
973                    self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
974                    mut_override(event.to_glib_none().0),
975                ))
976            } else {
977                Propagation::Proceed
978            }
979        }
980    }
981}
982
983impl<T: WidgetImpl> WidgetImplExt for T {}
984
985unsafe impl<T: WidgetImpl> IsSubclassable<T> for Widget {
986    fn class_init(class: &mut ::glib::Class<Self>) {
987        Self::parent_class_init::<T>(class);
988
989        if !crate::rt::is_initialized() {
990            panic!("GTK has to be initialized first");
991        }
992
993        let klass = class.as_mut();
994        klass.adjust_baseline_allocation = Some(widget_adjust_baseline_allocation::<T>);
995        klass.adjust_baseline_request = Some(widget_adjust_baseline_request::<T>);
996        klass.adjust_size_allocation = Some(widget_adjust_size_allocation::<T>);
997        klass.adjust_size_request = Some(widget_adjust_size_request::<T>);
998        klass.button_press_event = Some(widget_button_press_event::<T>);
999        klass.button_release_event = Some(widget_button_release_event::<T>);
1000        // klass.can_activate_accel = Some(widget_can_activate_accel::<T>);
1001        klass.child_notify = Some(widget_child_notify::<T>);
1002        klass.composited_changed = Some(widget_composited_changed::<T>);
1003        klass.compute_expand = Some(widget_compute_expand::<T>);
1004        klass.configure_event = Some(widget_configure_event::<T>);
1005        klass.window_state_event = Some(widget_window_state_event::<T>);
1006        klass.damage_event = Some(widget_damage_event::<T>);
1007        klass.delete_event = Some(widget_delete_event::<T>);
1008        klass.destroy = Some(widget_destroy::<T>);
1009        klass.destroy_event = Some(widget_destroy_event::<T>);
1010        klass.direction_changed = Some(widget_direction_changed::<T>);
1011        klass.dispatch_child_properties_changed =
1012            Some(widget_dispatch_child_properties_changed::<T>);
1013        klass.drag_begin = Some(widget_drag_begin::<T>);
1014        klass.drag_data_delete = Some(widget_drag_data_delete::<T>);
1015        klass.drag_data_get = Some(widget_drag_data_get::<T>);
1016        klass.drag_data_received = Some(widget_drag_data_received::<T>);
1017        klass.drag_drop = Some(widget_drag_drop::<T>);
1018        klass.drag_end = Some(widget_drag_end::<T>);
1019        klass.drag_failed = Some(widget_drag_failed::<T>);
1020        klass.drag_leave = Some(widget_drag_leave::<T>);
1021        klass.drag_motion = Some(widget_drag_motion::<T>);
1022        klass.draw = Some(widget_draw::<T>);
1023        klass.get_request_mode = Some(widget_get_request_mode::<T>);
1024        klass.get_preferred_width = Some(widget_get_preferred_width::<T>);
1025        klass.get_preferred_height_for_width = Some(widget_get_preferred_height_for_width::<T>);
1026        klass.get_preferred_height = Some(widget_get_preferred_height::<T>);
1027        klass.get_preferred_width_for_height = Some(widget_get_preferred_width_for_height::<T>);
1028        klass.size_allocate = Some(widget_size_allocate::<T>);
1029        klass.realize = Some(widget_realize::<T>);
1030        klass.unrealize = Some(widget_unrealize::<T>);
1031        klass.map = Some(widget_map::<T>);
1032        klass.unmap = Some(widget_unmap::<T>);
1033        klass.motion_notify_event = Some(widget_motion_notify_event::<T>);
1034        klass.scroll_event = Some(widget_scroll_event::<T>);
1035        klass.enter_notify_event = Some(widget_enter_notify_event::<T>);
1036        klass.leave_notify_event = Some(widget_leave_notify_event::<T>);
1037    }
1038}
1039
1040unsafe extern "C" fn widget_adjust_baseline_allocation<T: WidgetImpl>(
1041    ptr: *mut ffi::GtkWidget,
1042    baseptr: *mut i32,
1043) {
1044    let instance = &*(ptr as *mut T::Instance);
1045    let imp = instance.imp();
1046
1047    imp.adjust_baseline_allocation(&mut *baseptr)
1048}
1049
1050unsafe extern "C" fn widget_adjust_baseline_request<T: WidgetImpl>(
1051    ptr: *mut ffi::GtkWidget,
1052    minptr: *mut i32,
1053    natptr: *mut i32,
1054) {
1055    let instance = &*(ptr as *mut T::Instance);
1056    let imp = instance.imp();
1057
1058    imp.adjust_baseline_request(&mut *minptr, &mut *natptr)
1059}
1060
1061unsafe extern "C" fn widget_adjust_size_allocation<T: WidgetImpl>(
1062    ptr: *mut ffi::GtkWidget,
1063    orientation: ffi::GtkOrientation,
1064    minptr: *mut i32,
1065    natptr: *mut i32,
1066    posptr: *mut i32,
1067    sizeptr: *mut i32,
1068) {
1069    let instance = &*(ptr as *mut T::Instance);
1070    let imp = instance.imp();
1071    let wrap_orientation: Orientation = from_glib(orientation);
1072
1073    imp.adjust_size_allocation(
1074        wrap_orientation,
1075        &mut *minptr,
1076        &mut *natptr,
1077        &mut *posptr,
1078        &mut *sizeptr,
1079    )
1080}
1081
1082unsafe extern "C" fn widget_adjust_size_request<T: WidgetImpl>(
1083    ptr: *mut ffi::GtkWidget,
1084    orientation: ffi::GtkOrientation,
1085    minptr: *mut i32,
1086    natptr: *mut i32,
1087) {
1088    let instance = &*(ptr as *mut T::Instance);
1089    let imp = instance.imp();
1090    let wrap_orientation: Orientation = from_glib(orientation);
1091
1092    imp.adjust_size_request(wrap_orientation, &mut *minptr, &mut *natptr)
1093}
1094
1095unsafe extern "C" fn widget_button_press_event<T: WidgetImpl>(
1096    ptr: *mut ffi::GtkWidget,
1097    btnptr: *mut gdk::ffi::GdkEventButton,
1098) -> glib::ffi::gboolean {
1099    let instance = &*(ptr as *mut T::Instance);
1100    let imp = instance.imp();
1101    let evwrap: Borrowed<gdk::EventButton> = from_glib_borrow(btnptr);
1102
1103    imp.button_press_event(&evwrap).into_glib()
1104}
1105
1106unsafe extern "C" fn widget_button_release_event<T: WidgetImpl>(
1107    ptr: *mut ffi::GtkWidget,
1108    btnptr: *mut gdk::ffi::GdkEventButton,
1109) -> glib::ffi::gboolean {
1110    let instance = &*(ptr as *mut T::Instance);
1111    let imp = instance.imp();
1112    let evwrap: Borrowed<gdk::EventButton> = from_glib_borrow(btnptr);
1113
1114    imp.button_release_event(&evwrap).into_glib()
1115}
1116
1117// unsafe extern "C" fn widget_can_activate_accel<T: WidgetImpl>(
1118//     ptr: *mut ffi::GtkWidget,
1119//     signal_id: u32,
1120// ) -> glib::ffi::gboolean
1121// {
1122//     let instance = &*(ptr as *mut T::Instance);
1123//     let imp = instance.get_impl();
1124
1125//     imp.can_activate_accel( signal_id) as glib::ffi::gboolean
1126// }
1127
1128unsafe extern "C" fn widget_child_notify<T: WidgetImpl>(
1129    ptr: *mut ffi::GtkWidget,
1130    paramptr: *mut glib::gobject_ffi::GParamSpec,
1131) {
1132    let instance = &*(ptr as *mut T::Instance);
1133    let imp = instance.imp();
1134    let paramwrap: Borrowed<glib::ParamSpec> = from_glib_borrow(paramptr);
1135
1136    imp.child_notify(&paramwrap)
1137}
1138
1139unsafe extern "C" fn widget_composited_changed<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1140    let instance = &*(ptr as *mut T::Instance);
1141    let imp = instance.imp();
1142
1143    imp.composited_changed()
1144}
1145
1146unsafe extern "C" fn widget_compute_expand<T: WidgetImpl>(
1147    ptr: *mut ffi::GtkWidget,
1148    hexpand_ptr: *mut glib::ffi::gboolean,
1149    vexpand_ptr: *mut glib::ffi::gboolean,
1150) {
1151    let instance = &*(ptr as *mut T::Instance);
1152    let imp = instance.imp();
1153
1154    let widget = imp.obj();
1155    let widget = widget.unsafe_cast_ref::<Widget>();
1156    let mut hexpand: bool = if widget.is_hexpand_set() {
1157        widget.hexpands()
1158    } else {
1159        from_glib(*hexpand_ptr)
1160    };
1161    let mut vexpand: bool = if widget.is_vexpand_set() {
1162        widget.vexpands()
1163    } else {
1164        from_glib(*vexpand_ptr)
1165    };
1166
1167    imp.compute_expand(&mut hexpand, &mut vexpand);
1168    *hexpand_ptr = hexpand.into_glib();
1169    *vexpand_ptr = vexpand.into_glib();
1170}
1171
1172unsafe extern "C" fn widget_configure_event<T: WidgetImpl>(
1173    ptr: *mut ffi::GtkWidget,
1174    confptr: *mut gdk::ffi::GdkEventConfigure,
1175) -> glib::ffi::gboolean {
1176    let instance = &*(ptr as *mut T::Instance);
1177    let imp = instance.imp();
1178    let evwrap: Borrowed<gdk::EventConfigure> = from_glib_borrow(confptr);
1179
1180    imp.configure_event(&evwrap).into_glib()
1181}
1182
1183unsafe extern "C" fn widget_window_state_event<T: WidgetImpl>(
1184    ptr: *mut ffi::GtkWidget,
1185    winstateptr: *mut gdk::ffi::GdkEventWindowState,
1186) -> glib::ffi::gboolean {
1187    let instance = &*(ptr as *mut T::Instance);
1188    let imp = instance.imp();
1189    let evwrap: Borrowed<gdk::EventWindowState> = from_glib_borrow(winstateptr);
1190
1191    imp.window_state_event(&evwrap).into_glib()
1192}
1193
1194unsafe extern "C" fn widget_damage_event<T: WidgetImpl>(
1195    ptr: *mut ffi::GtkWidget,
1196    exposeptr: *mut gdk::ffi::GdkEventExpose,
1197) -> glib::ffi::gboolean {
1198    let instance = &*(ptr as *mut T::Instance);
1199    let imp = instance.imp();
1200    let evwrap: Borrowed<gdk::EventExpose> = from_glib_borrow(exposeptr);
1201
1202    imp.damage_event(&evwrap).into_glib()
1203}
1204
1205unsafe extern "C" fn widget_delete_event<T: WidgetImpl>(
1206    ptr: *mut ffi::GtkWidget,
1207    anyptr: *mut gdk::ffi::GdkEventAny,
1208) -> glib::ffi::gboolean {
1209    let instance = &*(ptr as *mut T::Instance);
1210    let imp = instance.imp();
1211    let evwrap: Borrowed<gdk::Event> = from_glib_borrow(anyptr);
1212
1213    imp.delete_event(&evwrap).into_glib()
1214}
1215
1216unsafe extern "C" fn widget_destroy<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1217    let instance = &*(ptr as *mut T::Instance);
1218    let imp = instance.imp();
1219
1220    imp.destroy()
1221}
1222
1223unsafe extern "C" fn widget_destroy_event<T: WidgetImpl>(
1224    ptr: *mut ffi::GtkWidget,
1225    anyptr: *mut gdk::ffi::GdkEventAny,
1226) -> glib::ffi::gboolean {
1227    let instance = &*(ptr as *mut T::Instance);
1228    let imp = instance.imp();
1229    let evwrap: Borrowed<gdk::Event> = from_glib_borrow(anyptr);
1230
1231    imp.destroy_event(&evwrap).into_glib()
1232}
1233
1234unsafe extern "C" fn widget_direction_changed<T: WidgetImpl>(
1235    ptr: *mut ffi::GtkWidget,
1236    directnptr: ffi::GtkTextDirection,
1237) {
1238    let instance = &*(ptr as *mut T::Instance);
1239    let imp = instance.imp();
1240    let dirwrap: TextDirection = from_glib(directnptr);
1241
1242    imp.direction_changed(dirwrap)
1243}
1244
1245unsafe extern "C" fn widget_dispatch_child_properties_changed<T: WidgetImpl>(
1246    ptr: *mut ffi::GtkWidget,
1247    n_pspec_ptr: u32,
1248    pspecsptr: *mut *mut glib::gobject_ffi::GParamSpec,
1249) {
1250    let instance = &*(ptr as *mut T::Instance);
1251    let imp = instance.imp();
1252    let pspecs: Vec<glib::ParamSpec> =
1253        FromGlibContainer::from_glib_none_num(pspecsptr, n_pspec_ptr as usize);
1254
1255    imp.dispatch_child_properties_changed(&pspecs)
1256}
1257
1258unsafe extern "C" fn widget_drag_begin<T: WidgetImpl>(
1259    ptr: *mut ffi::GtkWidget,
1260    ctxptr: *mut gdk::ffi::GdkDragContext,
1261) {
1262    let instance = &*(ptr as *mut T::Instance);
1263    let imp = instance.imp();
1264    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1265
1266    imp.drag_begin(&context)
1267}
1268
1269unsafe extern "C" fn widget_drag_data_delete<T: WidgetImpl>(
1270    ptr: *mut ffi::GtkWidget,
1271    ctxptr: *mut gdk::ffi::GdkDragContext,
1272) {
1273    let instance = &*(ptr as *mut T::Instance);
1274    let imp = instance.imp();
1275    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1276
1277    imp.drag_data_delete(&context)
1278}
1279
1280unsafe extern "C" fn widget_drag_data_get<T: WidgetImpl>(
1281    ptr: *mut ffi::GtkWidget,
1282    ctxptr: *mut gdk::ffi::GdkDragContext,
1283    selectptr: *mut ffi::GtkSelectionData,
1284    info: u32,
1285    time: u32,
1286) {
1287    let instance = &*(ptr as *mut T::Instance);
1288    let imp = instance.imp();
1289    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1290    let selection_data: Borrowed<SelectionData> = from_glib_borrow(selectptr);
1291
1292    imp.drag_data_get(&context, &selection_data, info, time)
1293}
1294
1295unsafe extern "C" fn widget_drag_data_received<T: WidgetImpl>(
1296    ptr: *mut ffi::GtkWidget,
1297    ctxptr: *mut gdk::ffi::GdkDragContext,
1298    x: i32,
1299    y: i32,
1300    selectptr: *mut ffi::GtkSelectionData,
1301    info: u32,
1302    time: u32,
1303) {
1304    let instance = &*(ptr as *mut T::Instance);
1305    let imp = instance.imp();
1306    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1307    let selection_data: Borrowed<SelectionData> = from_glib_borrow(selectptr);
1308
1309    imp.drag_data_received(&context, x, y, &selection_data, info, time)
1310}
1311
1312unsafe extern "C" fn widget_drag_drop<T: WidgetImpl>(
1313    ptr: *mut ffi::GtkWidget,
1314    ctxptr: *mut gdk::ffi::GdkDragContext,
1315    x: i32,
1316    y: i32,
1317    time: u32,
1318) -> glib::ffi::gboolean {
1319    let instance = &*(ptr as *mut T::Instance);
1320    let imp = instance.imp();
1321    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1322
1323    imp.drag_drop(&context, x, y, time).into_glib()
1324}
1325
1326unsafe extern "C" fn widget_drag_end<T: WidgetImpl>(
1327    ptr: *mut ffi::GtkWidget,
1328    ctxptr: *mut gdk::ffi::GdkDragContext,
1329) {
1330    let instance = &*(ptr as *mut T::Instance);
1331    let imp = instance.imp();
1332    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1333
1334    imp.drag_end(&context)
1335}
1336
1337unsafe extern "C" fn widget_drag_failed<T: WidgetImpl>(
1338    ptr: *mut ffi::GtkWidget,
1339    ctxptr: *mut gdk::ffi::GdkDragContext,
1340    resultptr: ffi::GtkDragResult,
1341) -> glib::ffi::gboolean {
1342    let instance = &*(ptr as *mut T::Instance);
1343    let imp = instance.imp();
1344    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1345    let result: DragResult = from_glib(resultptr);
1346
1347    imp.drag_failed(&context, result).into_glib()
1348}
1349
1350unsafe extern "C" fn widget_drag_leave<T: WidgetImpl>(
1351    ptr: *mut ffi::GtkWidget,
1352    ctxptr: *mut gdk::ffi::GdkDragContext,
1353    time: u32,
1354) {
1355    let instance = &*(ptr as *mut T::Instance);
1356    let imp = instance.imp();
1357    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1358
1359    imp.drag_leave(&context, time)
1360}
1361
1362unsafe extern "C" fn widget_drag_motion<T: WidgetImpl>(
1363    ptr: *mut ffi::GtkWidget,
1364    ctxptr: *mut gdk::ffi::GdkDragContext,
1365    x: i32,
1366    y: i32,
1367    time: u32,
1368) -> glib::ffi::gboolean {
1369    let instance = &*(ptr as *mut T::Instance);
1370    let imp = instance.imp();
1371    let context: Borrowed<gdk::DragContext> = from_glib_borrow(ctxptr);
1372
1373    imp.drag_motion(&context, x, y, time).into_glib()
1374}
1375
1376unsafe extern "C" fn widget_draw<T: WidgetImpl>(
1377    ptr: *mut ffi::GtkWidget,
1378    cr_ptr: *mut cairo::ffi::cairo_t,
1379) -> glib::ffi::gboolean {
1380    let instance = &*(ptr as *mut T::Instance);
1381    let imp = instance.imp();
1382    let cr: Borrowed<cairo::Context> = from_glib_borrow(cr_ptr);
1383
1384    imp.draw(&cr).into_glib()
1385}
1386
1387unsafe extern "C" fn widget_get_request_mode<T: WidgetImpl>(
1388    ptr: *mut ffi::GtkWidget,
1389) -> ffi::GtkSizeRequestMode {
1390    let instance = &*(ptr as *mut T::Instance);
1391    let imp = instance.imp();
1392
1393    imp.request_mode().into_glib()
1394}
1395
1396unsafe extern "C" fn widget_get_preferred_height<T: WidgetImpl>(
1397    ptr: *mut ffi::GtkWidget,
1398    minptr: *mut c_int,
1399    natptr: *mut c_int,
1400) {
1401    let instance = &*(ptr as *mut T::Instance);
1402    let imp = instance.imp();
1403
1404    let (min_size, nat_size) = imp.preferred_height();
1405    if !minptr.is_null() {
1406        *minptr = min_size;
1407    }
1408    if !natptr.is_null() {
1409        *natptr = nat_size;
1410    }
1411}
1412
1413unsafe extern "C" fn widget_get_preferred_width_for_height<T: WidgetImpl>(
1414    ptr: *mut ffi::GtkWidget,
1415    height: c_int,
1416    min_width_ptr: *mut c_int,
1417    nat_width_ptr: *mut c_int,
1418) {
1419    let instance = &*(ptr as *mut T::Instance);
1420    let imp = instance.imp();
1421
1422    let (min_width, nat_width) = imp.preferred_width_for_height(height);
1423    if !min_width_ptr.is_null() {
1424        *min_width_ptr = min_width;
1425    }
1426    if !nat_width_ptr.is_null() {
1427        *nat_width_ptr = nat_width;
1428    }
1429}
1430
1431unsafe extern "C" fn widget_get_preferred_width<T: WidgetImpl>(
1432    ptr: *mut ffi::GtkWidget,
1433    minptr: *mut c_int,
1434    natptr: *mut c_int,
1435) {
1436    let instance = &*(ptr as *mut T::Instance);
1437    let imp = instance.imp();
1438    let (min_size, nat_size) = imp.preferred_width();
1439    if !minptr.is_null() {
1440        *minptr = min_size;
1441    }
1442    if !natptr.is_null() {
1443        *natptr = nat_size;
1444    }
1445}
1446
1447unsafe extern "C" fn widget_get_preferred_height_for_width<T: WidgetImpl>(
1448    ptr: *mut ffi::GtkWidget,
1449    width: c_int,
1450    min_height_ptr: *mut c_int,
1451    nat_height_ptr: *mut c_int,
1452) {
1453    let instance = &*(ptr as *mut T::Instance);
1454    let imp = instance.imp();
1455
1456    let (min_height, nat_height) = imp.preferred_height_for_width(width);
1457    if !min_height_ptr.is_null() {
1458        *min_height_ptr = min_height;
1459    }
1460    if !nat_height_ptr.is_null() {
1461        *nat_height_ptr = nat_height;
1462    }
1463}
1464
1465unsafe extern "C" fn widget_size_allocate<T: WidgetImpl>(
1466    ptr: *mut ffi::GtkWidget,
1467    allocation: *mut ffi::GtkAllocation,
1468) {
1469    let instance = &*(ptr as *mut T::Instance);
1470    let imp = instance.imp();
1471    let allocate: &Allocation = &from_glib_none(allocation);
1472
1473    imp.size_allocate(allocate);
1474}
1475
1476unsafe extern "C" fn widget_realize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1477    let instance = &*(ptr as *mut T::Instance);
1478    let imp = instance.imp();
1479
1480    imp.realize();
1481}
1482
1483unsafe extern "C" fn widget_unrealize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1484    let instance = &*(ptr as *mut T::Instance);
1485    let imp = instance.imp();
1486
1487    imp.unrealize();
1488}
1489
1490unsafe extern "C" fn widget_map<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1491    let instance = &*(ptr as *mut T::Instance);
1492    let imp = instance.imp();
1493    imp.map();
1494}
1495
1496unsafe extern "C" fn widget_unmap<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1497    let instance = &*(ptr as *mut T::Instance);
1498    let imp = instance.imp();
1499    imp.unmap();
1500}
1501
1502unsafe extern "C" fn widget_motion_notify_event<T: WidgetImpl>(
1503    ptr: *mut ffi::GtkWidget,
1504    mptr: *mut gdk::ffi::GdkEventMotion,
1505) -> glib::ffi::gboolean {
1506    let instance = &*(ptr as *mut T::Instance);
1507    let imp = instance.imp();
1508    let event: Borrowed<gdk::EventMotion> = from_glib_borrow(mptr);
1509
1510    imp.motion_notify_event(&event).into_glib()
1511}
1512
1513unsafe extern "C" fn widget_scroll_event<T: WidgetImpl>(
1514    ptr: *mut ffi::GtkWidget,
1515    mptr: *mut gdk::ffi::GdkEventScroll,
1516) -> glib::ffi::gboolean {
1517    let instance = &*(ptr as *mut T::Instance);
1518    let imp = instance.imp();
1519    let event: Borrowed<gdk::EventScroll> = from_glib_borrow(mptr);
1520
1521    imp.scroll_event(&event).into_glib()
1522}
1523
1524unsafe extern "C" fn widget_enter_notify_event<T: WidgetImpl>(
1525    ptr: *mut ffi::GtkWidget,
1526    mptr: *mut gdk::ffi::GdkEventCrossing,
1527) -> glib::ffi::gboolean {
1528    let instance = &*(ptr as *mut T::Instance);
1529    let imp = instance.imp();
1530    let event: Borrowed<gdk::EventCrossing> = from_glib_borrow(mptr);
1531
1532    imp.enter_notify_event(&event).into_glib()
1533}
1534
1535unsafe extern "C" fn widget_leave_notify_event<T: WidgetImpl>(
1536    ptr: *mut ffi::GtkWidget,
1537    mptr: *mut gdk::ffi::GdkEventCrossing,
1538) -> glib::ffi::gboolean {
1539    let instance = &*(ptr as *mut T::Instance);
1540    let imp = instance.imp();
1541    let event: Borrowed<gdk::EventCrossing> = from_glib_borrow(mptr);
1542
1543    imp.leave_notify_event(&event).into_glib()
1544}
1545
1546pub unsafe trait WidgetClassSubclassExt: ClassStruct {
1547    fn set_template_bytes(&mut self, template: &glib::Bytes) {
1548        unsafe {
1549            let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1550            ffi::gtk_widget_class_set_template(widget_class, template.to_glib_none().0);
1551        }
1552    }
1553
1554    fn set_template(&mut self, template: &[u8]) {
1555        let template_bytes = glib::Bytes::from(template);
1556        self.set_template_bytes(&template_bytes);
1557    }
1558
1559    fn set_template_static(&mut self, template: &'static [u8]) {
1560        let template_bytes = glib::Bytes::from_static(template);
1561        self.set_template_bytes(&template_bytes);
1562    }
1563
1564    fn set_template_from_resource(&mut self, resource_name: &str) {
1565        unsafe {
1566            let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1567            ffi::gtk_widget_class_set_template_from_resource(
1568                widget_class,
1569                resource_name.to_glib_none().0,
1570            );
1571        }
1572    }
1573
1574    fn bind_template_child(&mut self, name: &str) {
1575        unsafe {
1576            let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1577            ffi::gtk_widget_class_bind_template_child_full(
1578                widget_class,
1579                name.to_glib_none().0,
1580                false as glib::ffi::gboolean,
1581                0,
1582            );
1583        }
1584    }
1585
1586    #[allow(clippy::missing_safety_doc)]
1587    unsafe fn bind_template_child_with_offset<T>(
1588        &mut self,
1589        name: &str,
1590        offset: field_offset::FieldOffset<Self::Type, TemplateChild<T>>,
1591    ) where
1592        T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1593    {
1594        let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1595        let private_offset = <Self::Type as ObjectSubclassType>::type_data()
1596            .as_ref()
1597            .impl_offset();
1598        ffi::gtk_widget_class_bind_template_child_full(
1599            widget_class,
1600            name.to_glib_none().0,
1601            false as glib::ffi::gboolean,
1602            private_offset + (offset.get_byte_offset() as isize),
1603        )
1604    }
1605
1606    #[doc(alias = "gtk_widget_class_set_css_name")]
1607    fn set_css_name(&mut self, name: &str) {
1608        unsafe {
1609            let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1610            ffi::gtk_widget_class_set_css_name(widget_class, name.to_glib_none().0);
1611        }
1612    }
1613
1614    #[doc(alias = "gtk_widget_class_get_css_name")]
1615    fn css_name(&self) -> glib::GString {
1616        unsafe {
1617            let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1618            from_glib_none(ffi::gtk_widget_class_get_css_name(widget_class))
1619        }
1620    }
1621}
1622
1623unsafe impl<T: ClassStruct> WidgetClassSubclassExt for T where T::Type: WidgetImpl {}
1624
1625#[derive(Debug, PartialEq, Eq)]
1626#[repr(transparent)]
1627pub struct TemplateChild<T>
1628where
1629    T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1630{
1631    ptr: *mut <T as ObjectType>::GlibType,
1632}
1633
1634impl<T> Default for TemplateChild<T>
1635where
1636    T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1637{
1638    fn default() -> Self {
1639        Self {
1640            ptr: std::ptr::null_mut(),
1641        }
1642    }
1643}
1644
1645impl<T> std::ops::Deref for TemplateChild<T>
1646where
1647    T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1648{
1649    type Target = T;
1650
1651    // rustdoc-stripper-ignore-next
1652    /// # Safety
1653    ///
1654    /// Since the template child may not be properly bound,
1655    /// this cast is potentially dangerous if, for example,
1656    /// the template child isn't bound or is of the wrong type.
1657    /// The caller is responsible for ensuring that the template
1658    /// child is bound and of the right type.
1659    fn deref(&self) -> &Self::Target {
1660        unsafe {
1661            assert!(!self.ptr.is_null());
1662            &*(&self.ptr as *const _ as *const T)
1663        }
1664    }
1665}
1666
1667impl<T> TemplateChild<T>
1668where
1669    T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1670{
1671    #[track_caller]
1672    pub fn get(&self) -> T {
1673        unsafe {
1674            Option::<T>::from_glib_none(self.ptr)
1675                .expect("Failed to retrieve template child. Please check that it has been bound.")
1676        }
1677    }
1678}
1679
1680pub trait CompositeTemplate: WidgetImpl {
1681    fn bind_template(klass: &mut Self::Class);
1682}