@@ -115,6 +115,7 @@ pub(crate) struct WindowBuilder {
115115 min_size : Option < Size > ,
116116 resizable : bool ,
117117 show_titlebar : bool ,
118+ transparent : bool ,
118119}
119120
120121#[ derive( Clone ) ]
@@ -136,6 +137,7 @@ pub(crate) struct WindowState {
136137 window : ApplicationWindow ,
137138 scale : Cell < Scale > ,
138139 area : Cell < ScaledArea > ,
140+ is_transparent : Cell < bool > ,
139141 /// Used to determine whether to honor close requests from the system: we inhibit them unless
140142 /// this is true, and this gets set to true when our client requests a close.
141143 closing : Cell < bool > ,
@@ -179,6 +181,7 @@ impl WindowBuilder {
179181 min_size : None ,
180182 resizable : true ,
181183 show_titlebar : true ,
184+ transparent : false ,
182185 }
183186 }
184187
@@ -202,6 +205,10 @@ impl WindowBuilder {
202205 self . show_titlebar = show_titlebar;
203206 }
204207
208+ pub fn set_transparent ( & mut self , transparent : bool ) {
209+ self . transparent = transparent;
210+ }
211+
205212 pub fn set_position ( & mut self , position : Point ) {
206213 self . position = Some ( position) ;
207214 }
@@ -231,7 +238,16 @@ impl WindowBuilder {
231238
232239 window. set_title ( & self . title ) ;
233240 window. set_resizable ( self . resizable ) ;
241+ window. set_app_paintable ( true ) ;
234242 window. set_decorated ( self . show_titlebar ) ;
243+ let mut can_transparent = false ;
244+ if self . transparent {
245+ if let Some ( screen) = window. get_screen ( ) {
246+ let visual = screen. get_rgba_visual ( ) ;
247+ can_transparent = visual. is_some ( ) ;
248+ window. set_visual ( visual. as_ref ( ) ) ;
249+ }
250+ }
235251
236252 // Get the scale factor based on the GTK reported DPI
237253 let scale_factor =
@@ -253,6 +269,7 @@ impl WindowBuilder {
253269 window,
254270 scale : Cell :: new ( scale) ,
255271 area : Cell :: new ( area) ,
272+ is_transparent : Cell :: new ( self . transparent & can_transparent) ,
256273 closing : Cell :: new ( false ) ,
257274 drawing_area,
258275 surface : RefCell :: new ( None ) ,
@@ -408,6 +425,19 @@ impl WindowBuilder {
408425 Inhibit ( false )
409426 } ) ) ;
410427
428+ win_state. drawing_area . connect_screen_changed (
429+ clone ! ( handle => move |widget, _prev_screen| {
430+ if let Some ( state) = handle. state. upgrade( ) {
431+
432+ if let Some ( screen) = widget. get_screen( ) {
433+ let visual = screen. get_rgba_visual( ) ;
434+ state. is_transparent. set( visual. is_some( ) ) ;
435+ widget. set_visual( visual. as_ref( ) ) ;
436+ }
437+ }
438+ } ) ,
439+ ) ;
440+
411441 win_state. drawing_area . connect_button_press_event ( clone ! ( handle => move |_widget, event| {
412442 if let Some ( state) = handle. state. upgrade( ) {
413443 state. with_handler( |handler| {
@@ -711,7 +741,11 @@ impl WindowState {
711741 * surface = None ;
712742
713743 if let Some ( w) = self . drawing_area . get_window ( ) {
714- * surface = w. create_similar_surface ( cairo:: Content :: Color , width, height) ;
744+ if self . is_transparent . get ( ) {
745+ * surface = w. create_similar_surface ( cairo:: Content :: ColorAlpha , width, height) ;
746+ } else {
747+ * surface = w. create_similar_surface ( cairo:: Content :: Color , width, height) ;
748+ }
715749 if surface. is_none ( ) {
716750 return Err ( anyhow ! ( "create_similar_surface failed" ) ) ;
717751 }
0 commit comments