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