@@ -12,7 +12,6 @@ use crate::handler::WindowHandlerBuilder;
1212use crate :: platform:: x11:: window_shared:: WindowInner ;
1313use crate :: platform:: x11:: xcb_window:: XcbWindow ;
1414use crate :: platform:: Result ;
15- use crate :: wrappers:: xkbcommon:: XkbcommonState ;
1615use crate :: * ;
1716
1817pub struct WindowHandle {
@@ -28,13 +27,25 @@ impl WindowHandle {
2827 ) -> Result < WindowHandle > {
2928 let ( tx, rx) = mpsc:: sync_channel :: < WindowOpenResult > ( 1 ) ;
3029 let ( parent_handle, mut window_handle) = ParentHandle :: new ( ) ;
31- let join_handle = thread:: spawn ( move || {
32- // TODO: properly handle crashes here
33- Window :: window_thread ( options, handler, tx. clone ( ) , Some ( parent_handle) ) . unwrap ( ) ;
34- } ) ;
3530
36- let raw_window_handle = rx. recv ( ) . unwrap ( ) ?;
37- window_handle. window_id = Some ( raw_window_handle) ;
31+ let join_handle =
32+ thread:: spawn ( move || match create_window ( options, handler, Some ( parent_handle) ) {
33+ Ok ( ev_loop) => {
34+ tx. send ( Ok ( ev_loop. window_id ( ) ) ) . unwrap ( ) ;
35+ ev_loop. run ( )
36+ }
37+ Err ( e) => {
38+ tx. send ( Err ( format ! ( "{}" , e) ) ) . unwrap ( ) ;
39+ }
40+ } ) ;
41+
42+ let id = match rx. recv ( ) {
43+ Ok ( Ok ( id) ) => id,
44+ Err ( e) => return Err ( super :: Error :: ChannelError ( e) ) ,
45+ Ok ( Err ( s) ) => return Err ( super :: error:: Error :: CreationFailed ( s) ) ,
46+ } ;
47+
48+ window_handle. window_id = Some ( id) ;
3849 window_handle. event_loop_handle = Some ( join_handle) . into ( ) ;
3950 Ok ( window_handle)
4051 }
@@ -91,87 +102,74 @@ impl Drop for ParentHandle {
91102 }
92103}
93104
94- pub struct Window ;
105+ type WindowOpenResult = core :: result :: Result < NonZero < x11rb :: protocol :: xproto :: Window > , String > ;
95106
96- type WindowOpenResult = Result < NonZero < x11rb:: protocol:: xproto:: Window > > ;
107+ fn create_window (
108+ options : WindowOpenOptions , build : WindowHandlerBuilder , parent_handle : Option < ParentHandle > ,
109+ ) -> Result < EventLoop > {
110+ // Connect to the X server
111+ let xcb_connection = X11Connection :: new ( ) ?;
97112
98- impl Window {
99- fn window_thread (
100- options : WindowOpenOptions , build : WindowHandlerBuilder ,
101- tx : mpsc:: SyncSender < WindowOpenResult > , parent_handle : Option < ParentHandle > ,
102- ) -> Result < ( ) > {
103- // Connect to the X server
104- let xcb_connection = X11Connection :: new ( ) ?;
113+ let scaling = match options. scale {
114+ WindowScalePolicy :: SystemScaleFactor => xcb_connection. get_scaling ( ) ,
115+ WindowScalePolicy :: ScaleFactor ( scale) => scale,
116+ } ;
105117
106- // Setup xkbcommon
107- let xkb_state = XkbcommonState :: new ( & xcb_connection) ;
118+ let physical_size = options. size . to_physical ( scaling) ;
108119
109- let scaling = match options. scale {
110- WindowScalePolicy :: SystemScaleFactor => xcb_connection. get_scaling ( ) ,
111- WindowScalePolicy :: ScaleFactor ( scale) => scale,
112- } ;
120+ #[ cfg( feature = "opengl" ) ]
121+ let visual_info =
122+ WindowVisualConfig :: find_best_visual_config_for_gl ( & xcb_connection, options. gl_config ) ?;
113123
114- let physical_size = options. size . to_physical ( scaling) ;
124+ #[ cfg( not( feature = "opengl" ) ) ]
125+ let visual_info = WindowVisualConfig :: find_best_visual_config ( & xcb_connection) ?;
115126
116- #[ cfg( feature = "opengl" ) ]
117- let visual_info =
118- WindowVisualConfig :: find_best_visual_config_for_gl ( & xcb_connection, options. gl_config ) ?;
119-
120- #[ cfg( not( feature = "opengl" ) ) ]
121- let visual_info = WindowVisualConfig :: find_best_visual_config ( & xcb_connection) ?;
122-
123- let xcb_connection = Rc :: new ( xcb_connection) ;
124-
125- let x_window = XcbWindow :: new (
126- Rc :: clone ( & xcb_connection) ,
127- physical_size,
128- & visual_info,
129- options. parent . map ( |p| p. window_id ) ,
130- ) ?;
131-
132- let cookies = [
133- x_window. map_window ( ) ?,
134- x_window. set_title ( & options. title ) ?,
135- x_window. enable_wm_protocols ( ) ?,
136- x_window. enable_dnd_protocols ( ) ?,
137- ] ;
138-
139- for cookie in cookies {
140- cookie. check ( ) ?;
141- }
127+ let xcb_connection = Rc :: new ( xcb_connection) ;
142128
143- #[ cfg( feature = "opengl" ) ]
144- let gl_context = match visual_info. fb_config {
145- None => None ,
146- Some ( fb_config) => {
147- // Because of the visual negotation we had to take some extra steps to create this context
148- Some ( super :: gl:: GlContextInner :: create (
149- & x_window,
150- Rc :: clone ( & xcb_connection) ,
151- fb_config,
152- ) ?)
153- }
154- } ;
129+ let x_window = XcbWindow :: new (
130+ Rc :: clone ( & xcb_connection) ,
131+ physical_size,
132+ & visual_info,
133+ options. parent . map ( |p| p. window_id ) ,
134+ ) ?;
155135
156- let window_id = x_window. id ( ) ;
157- let inner = Rc :: new ( WindowInner :: new (
158- xcb_connection,
159- x_window,
160- physical_size,
161- scaling,
162- visual_info. visual_id ,
163- #[ cfg( feature = "opengl" ) ]
164- gl_context,
165- ) ) ;
136+ let cookies = [
137+ x_window. map_window ( ) ?,
138+ x_window. set_title ( & options. title ) ?,
139+ x_window. enable_wm_protocols ( ) ?,
140+ x_window. enable_dnd_protocols ( ) ?,
141+ ] ;
166142
167- let handler = build. build ( WindowContext :: new ( Rc :: clone ( & inner) ) ) ?;
143+ for cookie in cookies {
144+ cookie. check ( ) ?;
145+ }
168146
169- let _ = tx. send ( Ok ( window_id) ) ;
147+ #[ cfg( feature = "opengl" ) ]
148+ let gl_context = match visual_info. fb_config {
149+ None => None ,
150+ Some ( fb_config) => {
151+ // Because of the visual negotation we had to take some extra steps to create this context
152+ Some ( super :: gl:: GlContextInner :: create (
153+ & x_window,
154+ Rc :: clone ( & xcb_connection) ,
155+ fb_config,
156+ ) ?)
157+ }
158+ } ;
159+
160+ let inner = Rc :: new ( WindowInner :: new (
161+ xcb_connection,
162+ x_window,
163+ physical_size,
164+ scaling,
165+ visual_info. visual_id ,
166+ #[ cfg( feature = "opengl" ) ]
167+ gl_context,
168+ ) ) ;
170169
171- EventLoop :: new ( inner, handler , parent_handle , xkb_state ) . run ( ) ?;
170+ let handler = build . build ( WindowContext :: new ( Rc :: clone ( & inner) ) ) ?;
172171
173- Ok ( ( ) )
174- }
172+ Ok ( EventLoop :: new ( inner, handler, parent_handle) )
175173}
176174
177175pub fn copy_to_clipboard ( _data : & str ) {
0 commit comments