@@ -60,29 +60,51 @@ impl<T: GtkApplicationImpl> GtkApplicationImplExt for T {
60
60
61
61
unsafe impl < T : GtkApplicationImpl > IsSubclassable < T > for Application {
62
62
fn class_init ( class : & mut :: glib:: Class < Self > ) {
63
+ // Override the original `GtkApplication` startup implementation so that
64
+ // we can set GTK as initialized right afterwards.
65
+ {
66
+ use std:: sync;
67
+
68
+ // Needed because the function pointer is not `Send+Sync` otherwise but has to be to be
69
+ // stored in a `static mut`.
70
+ struct WrapFn ( unsafe extern "C" fn ( * mut gio:: ffi:: GApplication ) ) ;
71
+ unsafe impl Send for WrapFn { }
72
+ unsafe impl Sync for WrapFn { }
73
+
74
+ static ONCE : sync:: Once = sync:: Once :: new ( ) ;
75
+ static mut OLD_STARTUP : Option < WrapFn > = None ;
76
+
77
+ // One the very first call replace the original `GtkApplication` startup with a
78
+ // function that first calls the original one and then marks gtk-rs as initialized.
79
+ ONCE . call_once ( || unsafe {
80
+ let base_klass =
81
+ glib:: gobject_ffi:: g_type_class_ref ( ffi:: gtk_application_get_type ( ) ) ;
82
+ assert ! ( !base_klass. is_null( ) ) ;
83
+
84
+ let app_klass = & mut * ( base_klass as * mut gio:: ffi:: GApplicationClass ) ;
85
+ OLD_STARTUP = app_klass. startup . map ( WrapFn ) ;
86
+
87
+ unsafe extern "C" fn replace_startup ( app : * mut gio:: ffi:: GApplication ) {
88
+ if let Some ( WrapFn ( old_startup) ) = OLD_STARTUP {
89
+ old_startup ( app) ;
90
+ }
91
+ crate :: rt:: set_initialized ( ) ;
92
+ }
93
+
94
+ app_klass. startup = Some ( replace_startup) ;
95
+
96
+ glib:: gobject_ffi:: g_type_class_unref ( base_klass) ;
97
+ } ) ;
98
+ }
99
+
63
100
Self :: parent_class_init :: < T > ( class) ;
64
101
65
102
let klass = class. as_mut ( ) ;
66
103
klass. window_added = Some ( application_window_added :: < T > ) ;
67
104
klass. window_removed = Some ( application_window_removed :: < T > ) ;
68
-
69
- // Chain our startup handler in here
70
- let parent_klass = & mut class. as_mut ( ) . parent_class ;
71
- parent_klass. startup = Some ( application_startup :: < T > ) ;
72
105
}
73
106
}
74
107
75
- unsafe extern "C" fn application_startup < T : ObjectSubclass > ( ptr : * mut gio:: ffi:: GApplication )
76
- where
77
- T : GtkApplicationImpl ,
78
- {
79
- let instance = & * ( ptr as * mut T :: Instance ) ;
80
- let imp = instance. imp ( ) ;
81
- let wrap: Borrowed < gio:: Application > = from_glib_borrow ( ptr) ;
82
- imp. startup ( wrap. unsafe_cast_ref ( ) ) ;
83
- crate :: rt:: set_initialized ( ) ;
84
- }
85
-
86
108
unsafe extern "C" fn application_window_added < T : GtkApplicationImpl > (
87
109
ptr : * mut ffi:: GtkApplication ,
88
110
wptr : * mut ffi:: GtkWindow ,
0 commit comments