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