1414
1515//! GTK implementation of features at the application scope.
1616
17- use std:: cell:: RefCell ;
18-
1917use gio:: prelude:: ApplicationExtManual ;
2018use gio:: { ApplicationExt , ApplicationFlags , Cancellable } ;
2119use gtk:: { Application as GtkApplication , GtkApplicationExt } ;
@@ -24,69 +22,59 @@ use crate::application::AppHandler;
2422
2523use super :: clipboard:: Clipboard ;
2624use super :: error:: Error ;
27- use super :: util;
28-
29- // XXX: The application needs to be global because WindowBuilder::build wants
30- // to construct an ApplicationWindow, which needs the application, but
31- // WindowBuilder::build does not get the RunLoop
32- thread_local ! (
33- static GTK_APPLICATION : RefCell <Option <GtkApplication >> = RefCell :: new( None ) ;
34- ) ;
3525
3626#[ derive( Clone ) ]
37- pub ( crate ) struct Application ;
27+ pub ( crate ) struct Application {
28+ gtk_app : GtkApplication ,
29+ }
3830
3931impl Application {
4032 pub fn new ( ) -> Result < Application , Error > {
4133 // TODO: we should give control over the application ID to the user
42- let application = GtkApplication :: new (
34+ let gtk_app = match GtkApplication :: new (
4335 Some ( "com.github.xi-editor.druid" ) ,
4436 // TODO we set this to avoid connecting to an existing running instance
4537 // of "com.github.xi-editor.druid" after which we would never receive
4638 // the "Activate application" below. See pull request druid#384
4739 // Which shows another way once we have in place a mechanism for
4840 // communication with remote instances.
4941 ApplicationFlags :: NON_UNIQUE ,
50- )
51- . expect ( "Unable to create GTK application" ) ;
42+ ) {
43+ Ok ( app) => app,
44+ Err ( err) => return Err ( Error :: BoolError ( err) ) ,
45+ } ;
5246
53- application . connect_activate ( |_app| {
47+ gtk_app . connect_activate ( |_app| {
5448 log:: info!( "gtk: Activated application" ) ;
5549 } ) ;
5650
57- application
58- . register ( None as Option < & Cancellable > )
59- . expect ( "Could not register GTK application" ) ;
51+ if let Err ( err ) = gtk_app . register ( None as Option < & Cancellable > ) {
52+ return Err ( Error :: Error ( err ) ) ;
53+ }
6054
61- GTK_APPLICATION . with ( move |x| * x. borrow_mut ( ) = Some ( application) ) ;
62- Ok ( Application )
55+ Ok ( Application { gtk_app } )
6356 }
6457
65- pub fn run ( self , _handler : Option < Box < dyn AppHandler > > ) {
66- util:: assert_main_thread ( ) ;
58+ #[ inline]
59+ pub fn gtk_app ( & self ) -> & GtkApplication {
60+ & self . gtk_app
61+ }
6762
63+ pub fn run ( self , _handler : Option < Box < dyn AppHandler > > ) {
6864 // TODO: should we pass the command line arguments?
69- GTK_APPLICATION . with ( |x| {
70- x. borrow ( )
71- . as_ref ( )
72- . unwrap ( ) // Safe because we initialized this in RunLoop::new
73- . run ( & [ ] )
74- } ) ;
65+ self . gtk_app . run ( & [ ] ) ;
7566 }
7667
7768 pub fn quit ( & self ) {
78- util:: assert_main_thread ( ) ;
79- with_application ( |app| {
80- match app. get_active_window ( ) {
81- None => {
82- // no application is running, main is not running
83- }
84- Some ( _) => {
85- // we still have an active window, close the run loop
86- app. quit ( ) ;
87- }
69+ match self . gtk_app . get_active_window ( ) {
70+ None => {
71+ // no application is running, main is not running
8872 }
89- } ) ;
73+ Some ( _) => {
74+ // we still have an active window, close the run loop
75+ self . gtk_app . quit ( ) ;
76+ }
77+ }
9078 }
9179
9280 pub fn clipboard ( & self ) -> Clipboard {
@@ -97,18 +85,3 @@ impl Application {
9785 glib:: get_language_names ( ) [ 0 ] . as_str ( ) . into ( )
9886 }
9987}
100-
101- #[ inline]
102- pub ( crate ) fn with_application < F , R > ( f : F ) -> R
103- where
104- F : std:: ops:: FnOnce ( GtkApplication ) -> R ,
105- {
106- util:: assert_main_thread ( ) ;
107- GTK_APPLICATION . with ( move |app| {
108- let app = app
109- . borrow ( )
110- . clone ( )
111- . expect ( "Tried to manipulate the application before RunLoop::new was called" ) ;
112- f ( app)
113- } )
114- }
0 commit comments