gtk4/subclass/
application.rs1use glib::translate::*;
7
8use crate::{ffi, prelude::*, subclass::prelude::*, Application, Window};
9
10pub trait GtkApplicationImpl: ApplicationImpl + ObjectSubclass<Type: IsA<Application>> {
11 fn window_added(&self, window: &Window) {
12 self.parent_window_added(window)
13 }
14
15 fn window_removed(&self, window: &Window) {
16 self.parent_window_removed(window)
17 }
18
19 #[cfg(feature = "v4_22")]
20 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
21 fn save_state(&self, state: &glib::VariantDict) -> bool {
22 self.parent_save_state(state)
23 }
24
25 #[cfg(feature = "v4_22")]
26 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
27 fn restore_state(&self, reason: crate::RestoreReason, state: &glib::Variant) -> bool {
28 self.parent_restore_state(reason, state)
29 }
30
31 #[cfg(feature = "v4_22")]
32 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
33 fn restore_window(&self, reason: crate::RestoreReason, state: &glib::Variant) {
34 self.parent_restore_window(reason, state)
35 }
36}
37
38pub trait GtkApplicationImplExt: GtkApplicationImpl {
39 fn parent_window_added(&self, window: &Window) {
40 unsafe {
41 let data = Self::type_data();
42 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
43 if let Some(f) = (*parent_class).window_added {
44 f(
45 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
46 window.to_glib_none().0,
47 )
48 }
49 }
50 }
51
52 fn parent_window_removed(&self, window: &Window) {
53 unsafe {
54 let data = Self::type_data();
55 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
56 if let Some(f) = (*parent_class).window_removed {
57 f(
58 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
59 window.to_glib_none().0,
60 )
61 }
62 }
63 }
64
65 #[cfg(feature = "v4_22")]
66 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
67 fn parent_save_state(&self, state: &glib::VariantDict) -> bool {
68 unsafe {
69 let data = Self::type_data();
70 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
71 if let Some(f) = (*parent_class).save_state {
72 from_glib(f(
73 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
74 state.to_glib_none().0,
75 ))
76 } else {
77 false
78 }
79 }
80 }
81
82 #[cfg(feature = "v4_22")]
83 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
84 fn parent_restore_state(&self, reason: crate::RestoreReason, state: &glib::Variant) -> bool {
85 unsafe {
86 let data = Self::type_data();
87 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
88 if let Some(f) = (*parent_class).restore_state {
89 from_glib(f(
90 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
91 reason.into_glib(),
92 state.to_glib_none().0,
93 ))
94 } else {
95 false
96 }
97 }
98 }
99
100 #[cfg(feature = "v4_22")]
101 #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
102 fn parent_restore_window(&self, reason: crate::RestoreReason, state: &glib::Variant) {
103 unsafe {
104 let data = Self::type_data();
105 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
106 if let Some(f) = (*parent_class).restore_window {
107 f(
108 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
109 reason.into_glib(),
110 state.to_glib_none().0,
111 )
112 }
113 }
114 }
115}
116
117impl<T: GtkApplicationImpl> GtkApplicationImplExt for T {}
118
119unsafe impl<T: GtkApplicationImpl> IsSubclassable<T> for Application {
120 fn class_init(class: &mut ::glib::Class<Self>) {
121 {
124 use std::sync;
125
126 struct WrapFn(unsafe extern "C" fn(*mut gio::ffi::GApplication));
129 unsafe impl Send for WrapFn {}
130 unsafe impl Sync for WrapFn {}
131
132 static ONCE: sync::Once = sync::Once::new();
133 static mut OLD_STARTUP: Option<WrapFn> = None;
134
135 ONCE.call_once(|| unsafe {
139 let base_klass =
140 glib::gobject_ffi::g_type_class_ref(ffi::gtk_application_get_type());
141 debug_assert!(!base_klass.is_null());
142
143 let app_klass = &mut *(base_klass as *mut gio::ffi::GApplicationClass);
144 OLD_STARTUP = app_klass.startup.map(WrapFn);
145
146 unsafe extern "C" fn replace_startup(app: *mut gio::ffi::GApplication) {
147 if let Some(WrapFn(old_startup)) = OLD_STARTUP {
148 old_startup(app);
149 }
150 crate::rt::set_initialized();
151 }
152
153 app_klass.startup = Some(replace_startup);
154
155 glib::gobject_ffi::g_type_class_unref(base_klass);
156 });
157 }
158
159 Self::parent_class_init::<T>(class);
160
161 let klass = class.as_mut();
162 klass.window_added = Some(application_window_added::<T>);
163 klass.window_removed = Some(application_window_removed::<T>);
164
165 #[cfg(feature = "v4_22")]
166 {
167 klass.save_state = Some(application_save_state::<T>);
168 klass.restore_state = Some(application_restore_state::<T>);
169 klass.restore_window = Some(application_restore_window::<T>);
170 }
171 }
172}
173
174unsafe extern "C" fn application_window_added<T: GtkApplicationImpl>(
175 ptr: *mut ffi::GtkApplication,
176 wptr: *mut ffi::GtkWindow,
177) {
178 let instance = &*(ptr as *mut T::Instance);
179 let imp = instance.imp();
180
181 imp.window_added(&from_glib_borrow(wptr))
182}
183
184unsafe extern "C" fn application_window_removed<T: GtkApplicationImpl>(
185 ptr: *mut ffi::GtkApplication,
186 wptr: *mut ffi::GtkWindow,
187) {
188 let instance = &*(ptr as *mut T::Instance);
189 let imp = instance.imp();
190
191 imp.window_removed(&from_glib_borrow(wptr))
192}
193
194#[cfg(feature = "v4_22")]
195unsafe extern "C" fn application_save_state<T: GtkApplicationImpl>(
196 ptr: *mut ffi::GtkApplication,
197 state: *mut glib::ffi::GVariantDict,
198) -> glib::ffi::gboolean {
199 let instance = &*(ptr as *mut T::Instance);
200 let imp = instance.imp();
201
202 imp.save_state(&from_glib_borrow(state)).into_glib()
203}
204
205#[cfg(feature = "v4_22")]
206unsafe extern "C" fn application_restore_state<T: GtkApplicationImpl>(
207 ptr: *mut ffi::GtkApplication,
208 reason: ffi::GtkRestoreReason,
209 state: *mut glib::ffi::GVariant,
210) -> glib::ffi::gboolean {
211 let instance = &*(ptr as *mut T::Instance);
212 let imp = instance.imp();
213
214 imp.restore_state(from_glib(reason), &from_glib_borrow(state))
215 .into_glib()
216}
217
218#[cfg(feature = "v4_22")]
219unsafe extern "C" fn application_restore_window<T: GtkApplicationImpl>(
220 ptr: *mut ffi::GtkApplication,
221 reason: ffi::GtkRestoreReason,
222 state: *mut glib::ffi::GVariant,
223) {
224 let instance = &*(ptr as *mut T::Instance);
225 let imp = instance.imp();
226
227 imp.restore_window(from_glib(reason), &from_glib_borrow(state))
228}