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