gtk/subclass/
application.rs1use glib::object::Cast;
4
5use glib::translate::*;
6
7use glib::subclass::prelude::*;
8
9use crate::Window;
10use crate::{Application, ffi};
11
12pub trait GtkApplicationImpl:
13 GtkApplicationImplExt + gio::subclass::prelude::ApplicationImpl
14{
15 fn window_added(&self, window: &Window) {
16 self.parent_window_added(window)
17 }
18
19 fn window_removed(&self, window: &Window) {
20 self.parent_window_removed(window)
21 }
22}
23
24mod sealed {
25 pub trait Sealed {}
26 impl<T: super::GtkApplicationImpl> Sealed for T {}
27}
28
29pub trait GtkApplicationImplExt: ObjectSubclass + sealed::Sealed {
30 fn parent_window_added(&self, window: &Window) {
31 unsafe {
32 let data = Self::type_data();
33 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
34 if let Some(f) = (*parent_class).window_added {
35 f(
36 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
37 window.to_glib_none().0,
38 )
39 }
40 }
41 }
42 fn parent_window_removed(&self, window: &Window) {
43 unsafe {
44 let data = Self::type_data();
45 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkApplicationClass;
46 if let Some(f) = (*parent_class).window_removed {
47 f(
48 self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
49 window.to_glib_none().0,
50 )
51 }
52 }
53 }
54}
55
56impl<T: GtkApplicationImpl> GtkApplicationImplExt for T {}
57
58unsafe impl<T: GtkApplicationImpl> IsSubclassable<T> for Application {
59 fn class_init(class: &mut ::glib::Class<Self>) {
60 {
63 use std::sync;
64
65 struct WrapFn(unsafe extern "C" fn(*mut gio::ffi::GApplication));
68 unsafe impl Send for WrapFn {}
69 unsafe impl Sync for WrapFn {}
70
71 static ONCE: sync::Once = sync::Once::new();
72 static mut OLD_STARTUP: Option<WrapFn> = None;
73
74 ONCE.call_once(|| unsafe {
77 let base_klass =
78 glib::gobject_ffi::g_type_class_ref(ffi::gtk_application_get_type());
79 assert!(!base_klass.is_null());
80
81 let app_klass = &mut *(base_klass as *mut gio::ffi::GApplicationClass);
82 OLD_STARTUP = app_klass.startup.map(WrapFn);
83
84 unsafe extern "C" fn replace_startup(app: *mut gio::ffi::GApplication) {
85 unsafe {
86 if let Some(WrapFn(old_startup)) = OLD_STARTUP {
87 old_startup(app);
88 }
89 crate::rt::set_initialized();
90 }
91 }
92
93 app_klass.startup = Some(replace_startup);
94
95 glib::gobject_ffi::g_type_class_unref(base_klass);
96 });
97 }
98
99 Self::parent_class_init::<T>(class);
100
101 let klass = class.as_mut();
102 klass.window_added = Some(application_window_added::<T>);
103 klass.window_removed = Some(application_window_removed::<T>);
104 }
105}
106
107unsafe extern "C" fn application_window_added<T: GtkApplicationImpl>(
108 ptr: *mut ffi::GtkApplication,
109 wptr: *mut ffi::GtkWindow,
110) {
111 unsafe {
112 let instance = &*(ptr as *mut T::Instance);
113 let imp = instance.imp();
114
115 imp.window_added(&from_glib_borrow(wptr))
116 }
117}
118unsafe extern "C" fn application_window_removed<T: GtkApplicationImpl>(
119 ptr: *mut ffi::GtkApplication,
120 wptr: *mut ffi::GtkWindow,
121) {
122 unsafe {
123 let instance = &*(ptr as *mut T::Instance);
124 let imp = instance.imp();
125
126 imp.window_removed(&from_glib_borrow(wptr))
127 }
128}