@@ -26,7 +26,9 @@ use x11rb::connection::{Connection, RequestConnection};
2626use x11rb:: protocol:: present:: ConnectionExt as _;
2727use x11rb:: protocol:: render:: { self , ConnectionExt as _, Pictformat } ;
2828use x11rb:: protocol:: xfixes:: ConnectionExt as _;
29- use x11rb:: protocol:: xproto:: { self , ConnectionExt , CreateWindowAux , EventMask , WindowClass } ;
29+ use x11rb:: protocol:: xproto:: {
30+ self , ConnectionExt , CreateWindowAux , EventMask , Visualtype , WindowClass ,
31+ } ;
3032use x11rb:: protocol:: Event ;
3133use x11rb:: resource_manager:: Database as ResourceDb ;
3234use x11rb:: xcb_ffi:: XCBConnection ;
@@ -52,6 +54,11 @@ pub(crate) struct Application {
5254 /// `druid_shell::WindowHandle` to be `!Send` and `!Sync`.
5355 marker : std:: marker:: PhantomData < * mut XCBConnection > ,
5456
57+ /// The type of visual used by the root window
58+ root_visual_type : Visualtype ,
59+ /// The visual for windows with transparent backgrounds, if supported
60+ argb_visual_type : Option < Visualtype > ,
61+
5562 /// The X11 resource database used to query dpi.
5663 pub ( crate ) rdb : Rc < ResourceDb > ,
5764 pub ( crate ) cursors : Cursors ,
@@ -189,6 +196,15 @@ impl Application {
189196 col_resize : load_cursor ( "col-resize" ) ,
190197 } ;
191198
199+ let screen = connection
200+ . setup ( )
201+ . roots
202+ . get ( screen_num as usize )
203+ . ok_or_else ( || anyhow ! ( "Invalid screen num: {}" , screen_num) ) ?;
204+ let root_visual_type = util:: get_visual_from_screen ( & screen)
205+ . ok_or_else ( || anyhow ! ( "Couldn't get visual from screen" ) ) ?;
206+ let argb_visual_type = util:: get_argb_visual_type ( & * connection, & screen) ?;
207+
192208 Ok ( Application {
193209 connection,
194210 rdb,
@@ -199,6 +215,8 @@ impl Application {
199215 cursors,
200216 idle_write,
201217 present_opcode,
218+ root_visual_type,
219+ argb_visual_type,
202220 marker : std:: marker:: PhantomData ,
203221 render_argb32_pictformat_cursor,
204222 } )
@@ -326,6 +344,33 @@ impl Application {
326344 self . screen_num
327345 }
328346
347+ #[ inline]
348+ pub ( crate ) fn argb_visual_type ( & self ) -> Option < Visualtype > {
349+ // Check if a composite manager is running
350+ let atom_name = format ! ( "_NET_WM_CM_S{}" , self . screen_num) ;
351+ let owner = self
352+ . connection
353+ . intern_atom ( false , atom_name. as_bytes ( ) )
354+ . ok ( )
355+ . and_then ( |cookie| cookie. reply ( ) . ok ( ) )
356+ . map ( |reply| reply. atom )
357+ . and_then ( |atom| self . connection . get_selection_owner ( atom) . ok ( ) )
358+ . and_then ( |cookie| cookie. reply ( ) . ok ( ) )
359+ . map ( |reply| reply. owner ) ;
360+
361+ if Some ( x11rb:: NONE ) == owner {
362+ tracing:: debug!( "_NET_WM_CM_Sn selection is unowned, not providing ARGB visual" ) ;
363+ None
364+ } else {
365+ self . argb_visual_type
366+ }
367+ }
368+
369+ #[ inline]
370+ pub ( crate ) fn root_visual_type ( & self ) -> Visualtype {
371+ self . root_visual_type
372+ }
373+
329374 /// Returns `Ok(true)` if we want to exit the main loop.
330375 fn handle_event ( & self , ev : & Event ) -> Result < bool , Error > {
331376 match ev {
0 commit comments