@@ -8,17 +8,14 @@ use std::sync::Arc;
88use std:: thread:: { self , JoinHandle } ;
99
1010use x11rb:: connection:: Connection ;
11- use x11rb:: protocol:: xproto:: {
12- AtomEnum , ConnectionExt , CreateGCAux , CreateWindowAux , EventMask , PropMode , WindowClass ,
13- } ;
14- use x11rb:: wrapper:: ConnectionExt as _;
1511
1612use super :: X11Connection ;
1713use super :: { event_loop:: EventLoop , visual_info:: WindowVisualConfig } ;
18- use crate :: context:: WindowContext ;
1914use crate :: handler:: WindowHandlerBuilder ;
2015use crate :: platform:: x11:: window_shared:: WindowInner ;
21- use crate :: { WindowOpenOptions , WindowScalePolicy , WindowSize } ;
16+ use crate :: platform:: x11:: xcb_window:: XcbWindow ;
17+ use crate :: wrappers:: xkbcommon:: XkbcommonState ;
18+ use crate :: * ;
2219
2320pub struct WindowHandle {
2421 window_id : Option < NonZero < x11rb:: protocol:: xproto:: Window > > ,
@@ -105,22 +102,10 @@ impl Window {
105102 tx : mpsc:: SyncSender < WindowOpenResult > , parent_handle : Option < ParentHandle > ,
106103 ) -> Result < ( ) , Box < dyn Error > > {
107104 // Connect to the X server
108- // FIXME: baseview error type instead of unwrap()
109105 let xcb_connection = X11Connection :: new ( ) ?;
110106
111107 // Setup xkbcommon
112- let xkb_state = crate :: wrappers:: xkbcommon:: XkbcommonState :: new ( & xcb_connection) ;
113-
114- // Get screen information
115- let screen = xcb_connection. screen ( ) ;
116- let parent_id = options. parent . map ( |p| p. window_id ) . unwrap_or ( screen. root ) ;
117-
118- let gc_id = xcb_connection. conn . generate_id ( ) ?;
119- xcb_connection. conn . create_gc (
120- gc_id,
121- parent_id,
122- & CreateGCAux :: new ( ) . foreground ( screen. black_pixel ) . graphics_exposures ( 0 ) ,
123- ) ?;
108+ let xkb_state = XkbcommonState :: new ( & xcb_connection) ;
124109
125110 let scaling = match options. scale {
126111 WindowScalePolicy :: SystemScaleFactor => xcb_connection. get_scaling ( ) ,
@@ -136,88 +121,33 @@ impl Window {
136121 #[ cfg( not( feature = "opengl" ) ) ]
137122 let visual_info = WindowVisualConfig :: find_best_visual_config ( & xcb_connection) ?;
138123
139- let Some ( window_id) = NonZero :: new ( xcb_connection. conn . generate_id ( ) ?) else {
140- unreachable ! ( ) ;
141- } ;
142-
143- xcb_connection. conn . create_window (
144- visual_info. visual_depth ,
145- window_id. get ( ) ,
146- parent_id,
147- 0 , // x coordinate of the new window
148- 0 , // y coordinate of the new window
149- physical_size. width , // window width
150- physical_size. height , // window height
151- 0 , // window border
152- WindowClass :: INPUT_OUTPUT ,
153- visual_info. visual_id ,
154- & CreateWindowAux :: new ( )
155- . event_mask (
156- EventMask :: EXPOSURE
157- | EventMask :: POINTER_MOTION
158- | EventMask :: BUTTON_PRESS
159- | EventMask :: BUTTON_RELEASE
160- | EventMask :: KEY_PRESS
161- | EventMask :: KEY_RELEASE
162- | EventMask :: STRUCTURE_NOTIFY
163- | EventMask :: ENTER_WINDOW
164- | EventMask :: LEAVE_WINDOW
165- | EventMask :: FOCUS_CHANGE ,
166- )
167- // As mentioned above, these two values are needed to be able to create a window
168- // with a depth of 32-bits when the parent window has a different depth
169- . colormap ( visual_info. color_map )
170- . border_pixel ( 0 ) ,
171- ) ?;
172- xcb_connection. conn . map_window ( window_id. get ( ) ) ?;
173-
174- // Change window title
175- let title = options. title ;
176- xcb_connection. conn . change_property8 (
177- PropMode :: REPLACE ,
178- window_id. get ( ) ,
179- AtomEnum :: WM_NAME ,
180- AtomEnum :: STRING ,
181- title. as_bytes ( ) ,
182- ) ?;
124+ let xcb_connection = Rc :: new ( xcb_connection) ;
183125
184- xcb_connection. conn . change_property32 (
185- PropMode :: REPLACE ,
186- window_id. get ( ) ,
187- xcb_connection. atoms . WM_PROTOCOLS ,
188- AtomEnum :: ATOM ,
189- & [ xcb_connection. atoms . WM_DELETE_WINDOW ] ,
126+ let x_window = XcbWindow :: new (
127+ Rc :: clone ( & xcb_connection) ,
128+ physical_size,
129+ & visual_info,
130+ options. parent . map ( |p| p. window_id ) ,
190131 ) ?;
191132
192- // Enable drag and drop (TODO: Make this toggleable?)
193- xcb_connection. conn . change_property32 (
194- PropMode :: REPLACE ,
195- window_id. get ( ) ,
196- xcb_connection. atoms . XdndAware ,
197- AtomEnum :: ATOM ,
198- & [ 5u32 ] , // Latest version; hasn't changed since 2002
199- ) ?;
133+ x_window. map_window ( ) ?;
134+ x_window. set_title ( & options. title ) ?;
135+ x_window. enable_wm_protocols ( ) ?;
136+ x_window. enable_dnd_protocols ( ) ?;
200137
201138 xcb_connection. conn . flush ( ) ?;
202- let xcb_connection = Rc :: new ( xcb_connection) ;
203139
204140 #[ cfg( feature = "opengl" ) ]
205141 let gl_context = visual_info. fb_config . map ( |fb_config| {
206- use std:: ffi:: c_ulong;
207-
208- let window = window_id. get ( ) as c_ulong ;
209-
210142 // Because of the visual negotation we had to take some extra steps to create this context
211- let context =
212- super :: gl:: GlContextInner :: create ( window, Rc :: clone ( & xcb_connection) , fb_config)
213- . expect ( "Could not create OpenGL context" ) ;
214-
215- Rc :: new ( context)
143+ super :: gl:: GlContextInner :: create ( & x_window, Rc :: clone ( & xcb_connection) , fb_config)
144+ . expect ( "Could not create OpenGL context" )
216145 } ) ;
217146
147+ let window_id = x_window. id ( ) ;
218148 let inner = Rc :: new ( WindowInner :: new (
219149 xcb_connection,
220- window_id ,
150+ x_window ,
221151 physical_size,
222152 scaling,
223153 visual_info. visual_id . try_into ( ) ?,
@@ -227,10 +157,6 @@ impl Window {
227157
228158 let handler = build. build ( WindowContext :: new ( Rc :: clone ( & inner) ) ) ;
229159
230- // Send an initial window resized event so the user is alerted of
231- // the correct dpi scaling.
232- handler. resized ( WindowSize :: from_physical ( physical_size. cast ( ) , scaling) ) ;
233-
234160 let _ = tx. send ( Ok ( window_id) ) ;
235161
236162 EventLoop :: new ( inner, handler, parent_handle, xkb_state) . run ( ) ?;
0 commit comments