@@ -116,6 +116,7 @@ pub(crate) struct WindowBuilder {
116116 min_size : Option < Size > ,
117117 resizable : bool ,
118118 show_titlebar : bool ,
119+ transparent : bool ,
119120}
120121
121122#[ derive( Clone ) ]
@@ -137,6 +138,7 @@ pub(crate) struct WindowState {
137138 window : ApplicationWindow ,
138139 scale : Cell < Scale > ,
139140 area : Cell < ScaledArea > ,
141+ is_transparent : Cell < bool > ,
140142 /// Used to determine whether to honor close requests from the system: we inhibit them unless
141143 /// this is true, and this gets set to true when our client requests a close.
142144 closing : Cell < bool > ,
@@ -180,6 +182,7 @@ impl WindowBuilder {
180182 min_size : None ,
181183 resizable : true ,
182184 show_titlebar : true ,
185+ transparent : false ,
183186 }
184187 }
185188
@@ -203,6 +206,10 @@ impl WindowBuilder {
203206 self . show_titlebar = show_titlebar;
204207 }
205208
209+ pub fn set_transparent ( & mut self , transparent : bool ) {
210+ self . transparent = transparent;
211+ }
212+
206213 pub fn set_position ( & mut self , position : Point ) {
207214 self . position = Some ( position) ;
208215 }
@@ -232,7 +239,16 @@ impl WindowBuilder {
232239
233240 window. set_title ( & self . title ) ;
234241 window. set_resizable ( self . resizable ) ;
242+ window. set_app_paintable ( true ) ;
235243 window. set_decorated ( self . show_titlebar ) ;
244+ let mut can_transparent = false ;
245+ if self . transparent {
246+ if let Some ( screen) = window. get_screen ( ) {
247+ let visual = screen. get_rgba_visual ( ) ;
248+ can_transparent = visual. is_some ( ) ;
249+ window. set_visual ( visual. as_ref ( ) ) ;
250+ }
251+ }
236252
237253 // Get the scale factor based on the GTK reported DPI
238254 let scale_factor =
@@ -254,6 +270,7 @@ impl WindowBuilder {
254270 window,
255271 scale : Cell :: new ( scale) ,
256272 area : Cell :: new ( area) ,
273+ is_transparent : Cell :: new ( self . transparent & can_transparent) ,
257274 closing : Cell :: new ( false ) ,
258275 drawing_area,
259276 surface : RefCell :: new ( None ) ,
@@ -409,6 +426,19 @@ impl WindowBuilder {
409426 Inhibit ( false )
410427 } ) ) ;
411428
429+ win_state. drawing_area . connect_screen_changed (
430+ clone ! ( handle => move |widget, _prev_screen| {
431+ if let Some ( state) = handle. state. upgrade( ) {
432+
433+ if let Some ( screen) = widget. get_screen( ) {
434+ let visual = screen. get_rgba_visual( ) ;
435+ state. is_transparent. set( visual. is_some( ) ) ;
436+ widget. set_visual( visual. as_ref( ) ) ;
437+ }
438+ }
439+ } ) ,
440+ ) ;
441+
412442 win_state. drawing_area . connect_button_press_event ( clone ! ( handle => move |_widget, event| {
413443 if let Some ( state) = handle. state. upgrade( ) {
414444 state. with_handler( |handler| {
@@ -712,7 +742,11 @@ impl WindowState {
712742 * surface = None ;
713743
714744 if let Some ( w) = self . drawing_area . get_window ( ) {
715- * surface = w. create_similar_surface ( cairo:: Content :: Color , width, height) ;
745+ if self . is_transparent . get ( ) {
746+ * surface = w. create_similar_surface ( cairo:: Content :: ColorAlpha , width, height) ;
747+ } else {
748+ * surface = w. create_similar_surface ( cairo:: Content :: Color , width, height) ;
749+ }
716750 if surface. is_none ( ) {
717751 return Err ( anyhow ! ( "create_similar_surface failed" ) ) ;
718752 }
0 commit comments