gtk4/subclass/
window.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for subclassing [`Window`](crate::Window).
5
6use glib::translate::*;
7
8use crate::{ffi, prelude::*, subclass::prelude::*, Window};
9
10pub trait WindowImpl: WindowImplExt + WidgetImpl {
11    /// Activates the current focused widget within the window.
12    fn activate_focus(&self) {
13        self.parent_activate_focus()
14    }
15
16    /// Activates the default widget for the window.
17    fn activate_default(&self) {
18        self.parent_activate_default()
19    }
20
21    /// Signal gets emitted when the set of accelerators or
22    ///   mnemonics that are associated with window changes.
23    fn keys_changed(&self) {
24        self.parent_keys_changed()
25    }
26
27    /// Class handler for the `GtkWindow::enable-debugging`
28    ///   keybinding signal.
29    fn enable_debugging(&self, toggle: bool) -> bool {
30        self.parent_enable_debugging(toggle)
31    }
32
33    /// Class handler for the [`close-request`][struct@crate::Window#close-request] signal.
34    ///
35    /// # Returns
36    ///
37    /// Whether the window should be destroyed
38    fn close_request(&self) -> glib::Propagation {
39        self.parent_close_request()
40    }
41}
42
43mod sealed {
44    pub trait Sealed {}
45    impl<T: super::WindowImplExt> Sealed for T {}
46}
47
48pub trait WindowImplExt: sealed::Sealed + ObjectSubclass {
49    fn parent_activate_focus(&self) {
50        unsafe {
51            let data = Self::type_data();
52            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWindowClass;
53            let f = (*parent_class)
54                .activate_focus
55                .expect("No parent class impl for \"activate_focus\"");
56            f(self.obj().unsafe_cast_ref::<Window>().to_glib_none().0)
57        }
58    }
59
60    fn parent_activate_default(&self) {
61        unsafe {
62            let data = Self::type_data();
63            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWindowClass;
64            let f = (*parent_class)
65                .activate_default
66                .expect("No parent class impl for \"activate_default\"");
67            f(self.obj().unsafe_cast_ref::<Window>().to_glib_none().0)
68        }
69    }
70
71    fn parent_keys_changed(&self) {
72        unsafe {
73            let data = Self::type_data();
74            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWindowClass;
75            let f = (*parent_class)
76                .keys_changed
77                .expect("No parent class impl for \"keys_changed\"");
78            f(self.obj().unsafe_cast_ref::<Window>().to_glib_none().0)
79        }
80    }
81
82    // Returns true if debugging (inspector) should be enabled, false otherwise
83    fn parent_enable_debugging(&self, toggle: bool) -> bool {
84        unsafe {
85            let data = Self::type_data();
86            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWindowClass;
87            let f = (*parent_class)
88                .enable_debugging
89                .expect("No parent class impl for \"enable_debugging\"");
90            from_glib(f(
91                self.obj().unsafe_cast_ref::<Window>().to_glib_none().0,
92                toggle.into_glib(),
93            ))
94        }
95    }
96
97    fn parent_close_request(&self) -> glib::Propagation {
98        unsafe {
99            let data = Self::type_data();
100            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWindowClass;
101            let f = (*parent_class)
102                .close_request
103                .expect("No parent class impl for \"close_request\"");
104            glib::Propagation::from_glib(f(self.obj().unsafe_cast_ref::<Window>().to_glib_none().0))
105        }
106    }
107}
108
109impl<T: WindowImpl> WindowImplExt for T {}
110
111unsafe impl<T: WindowImpl> IsSubclassable<T> for Window {
112    fn class_init(class: &mut ::glib::Class<Self>) {
113        Self::parent_class_init::<T>(class);
114
115        let klass = class.as_mut();
116        klass.activate_focus = Some(window_activate_focus::<T>);
117        klass.activate_default = Some(window_activate_default::<T>);
118        klass.keys_changed = Some(window_keys_changed::<T>);
119        klass.enable_debugging = Some(window_enable_debugging::<T>);
120        klass.close_request = Some(window_close_request::<T>);
121    }
122}
123
124unsafe extern "C" fn window_activate_focus<T: WindowImpl>(ptr: *mut ffi::GtkWindow) {
125    let instance = &*(ptr as *mut T::Instance);
126    let imp = instance.imp();
127
128    imp.activate_focus()
129}
130
131unsafe extern "C" fn window_activate_default<T: WindowImpl>(ptr: *mut ffi::GtkWindow) {
132    let instance = &*(ptr as *mut T::Instance);
133    let imp = instance.imp();
134
135    imp.activate_default()
136}
137
138unsafe extern "C" fn window_keys_changed<T: WindowImpl>(ptr: *mut ffi::GtkWindow) {
139    let instance = &*(ptr as *mut T::Instance);
140    let imp = instance.imp();
141
142    imp.keys_changed()
143}
144
145unsafe extern "C" fn window_enable_debugging<T: WindowImpl>(
146    ptr: *mut ffi::GtkWindow,
147    toggleptr: glib::ffi::gboolean,
148) -> glib::ffi::gboolean {
149    let instance = &*(ptr as *mut T::Instance);
150    let imp = instance.imp();
151    let toggle: bool = from_glib(toggleptr);
152
153    imp.enable_debugging(toggle).into_glib()
154}
155
156unsafe extern "C" fn window_close_request<T: WindowImpl>(
157    ptr: *mut ffi::GtkWindow,
158) -> glib::ffi::gboolean {
159    let instance = &*(ptr as *mut T::Instance);
160    let imp = instance.imp();
161
162    imp.close_request().into_glib()
163}