@@ -12,7 +12,7 @@ use signals::*;
1212
1313use log:: * ;
1414use std:: {
15- collections:: BTreeSet ,
15+ collections:: { BTreeSet , HashMap , HashSet } ,
1616 ffi:: CString ,
1717 mem:: zeroed,
1818 process:: Command ,
@@ -45,6 +45,7 @@ pub struct GridWM {
4545 bar_str : String ,
4646 screen_width : i16 ,
4747 screen_height : i16 ,
48+ win_bar_windows : HashMap < Window , Window > ,
4849}
4950
5051pub type Window = u64 ;
@@ -148,6 +149,7 @@ impl GridWM {
148149 bar_str,
149150 screen_width,
150151 screen_height,
152+ win_bar_windows : HashMap :: new ( ) ,
151153 } )
152154 }
153155
@@ -320,13 +322,13 @@ impl GridWM {
320322
321323 xlib:: XDefineCursor ( self . display , root, cursor) ;
322324
323- // set background yay
325+ // set background
324326 self . set_background ( self . config . desktop . color . clone ( ) ) ;
325327
326- // flush the toilet
328+ // flush
327329 XFlush ( self . display ) ;
328330
329- // draw bar for the first time yahooooo
331+ // draw bar for the first time
330332 if self . config . bar . enable {
331333 self . draw_bar ( None ) ;
332334 }
@@ -491,6 +493,15 @@ impl GridWM {
491493 self . draw_bar ( None ) ;
492494 }
493495
496+ if self . config . window . window_bars {
497+ self . draw_window_bar ( ) ;
498+ }
499+
500+ // flush
501+ unsafe {
502+ XFlush ( self . display ) ;
503+ }
504+
494505 // subtract time process took from sleep time
495506 let sleep_time = Duration :: from_millis ( self . config . general . update_ms ) ;
496507 let process_took = process_start. elapsed ( ) ;
@@ -593,7 +604,8 @@ impl GridWM {
593604 ) ) )
594605 }
595606
596- fn get_focused ( & self ) -> Option < Window > {
607+ // may be used later on
608+ fn _get_focused ( & self ) -> Option < Window > {
597609 unsafe {
598610 let mut focused: Window = std:: mem:: zeroed ( ) ;
599611 let mut revert: i32 = std:: mem:: zeroed ( ) ;
@@ -616,6 +628,7 @@ impl GridWM {
616628 desktop. remove ( & event. window ) ;
617629 self . set_desktop ( self . current_desktop , desktop) ;
618630 self . floating_windows . remove ( & event. window ) ;
631+ self . win_bar_windows . remove ( & event. window ) ;
619632 }
620633
621634 fn move_window ( & self , window : Window , x : i32 , y : i32 ) {
@@ -771,12 +784,10 @@ impl GridWM {
771784 xlib:: CurrentTime ,
772785 ) ;
773786 xlib:: XRaiseWindow ( self . display , clicked_win) ;
774- XFlush ( self . display ) ;
775787 }
776788 }
777789 unsafe {
778790 xlib:: XAllowEvents ( self . display , xlib:: ReplayPointer , xlib:: CurrentTime ) ;
779- XFlush ( self . display ) ;
780791 }
781792 }
782793
@@ -798,6 +809,90 @@ impl GridWM {
798809 }
799810 }
800811
812+ fn draw_window_bar ( & mut self ) {
813+ unsafe {
814+ let desktop = self . get_desktop ( self . current_desktop ) ;
815+
816+ let valid_windows: HashSet < Window > = desktop. iter ( ) . copied ( ) . collect ( ) ;
817+ self . win_bar_windows . retain ( |parent_win, bar_win| {
818+ if !valid_windows. contains ( parent_win) {
819+ false
820+ } else {
821+ let mut attrs = std:: mem:: zeroed ( ) ;
822+ let result = xlib:: XGetWindowAttributes ( self . display , * bar_win, & mut attrs) ;
823+ result != 0
824+ }
825+ } ) ;
826+
827+ for window in & desktop {
828+ if !self . is_tileable ( * window) {
829+ continue ;
830+ }
831+
832+ let attrs = self . get_window_attributes ( * window) ;
833+
834+ // create or get bar window
835+ let bar_window = if let Some ( & bar_win) = self . win_bar_windows . get ( window) {
836+ bar_win
837+ } else {
838+ // create a new child window for the bar
839+ let bar_win = xlib:: XCreateSimpleWindow (
840+ self . display ,
841+ * window,
842+ 0 ,
843+ -( self . config . window . window_bar_height as i32 ) ,
844+ attrs. width as u32 ,
845+ self . config . window . window_bar_height ,
846+ 0 ,
847+ 0 ,
848+ 0 ,
849+ ) ;
850+ xlib:: XMapWindow ( self . display , bar_win) ;
851+ self . win_bar_windows . insert ( * window, bar_win) ;
852+ bar_win
853+ } ;
854+
855+ // resize bar window if parent window size changed
856+ xlib:: XMoveResizeWindow (
857+ self . display ,
858+ bar_window,
859+ 0 ,
860+ -( self . config . window . window_bar_height as i32 ) ,
861+ attrs. width as u32 ,
862+ self . config . window . window_bar_height ,
863+ ) ;
864+
865+ let win_name = self . get_name ( * window) . unwrap_or_default ( ) ;
866+ let win_name_c = match CString :: new ( win_name) {
867+ Ok ( name) => name,
868+ Err ( _) => continue ,
869+ } ;
870+
871+ xlib:: XFillRectangle (
872+ self . display ,
873+ bar_window,
874+ self . win_bar_background_gc ,
875+ 0 ,
876+ -( self . config . window . window_bar_height as i32 ) ,
877+ attrs. width as u32 ,
878+ self . config . window . window_bar_height ,
879+ ) ;
880+
881+ let text_offset = ( self . config . window . window_bar_height as i32 ) * 3 / 4 ;
882+
883+ xlib:: XDrawString (
884+ self . display ,
885+ bar_window,
886+ self . win_bar_gc ,
887+ 5 ,
888+ -( self . config . window . window_bar_height as i32 ) + text_offset,
889+ win_name_c. as_ptr ( ) ,
890+ win_name_c. to_bytes ( ) . len ( ) as i32 ,
891+ ) ;
892+ }
893+ }
894+ }
895+
801896 // TODO: maybe move it somewhere else
802897 fn draw_bar ( & self , content : Option < String > ) {
803898 unsafe {
@@ -842,8 +937,6 @@ impl GridWM {
842937 bar_str. as_ptr ( ) ,
843938 bar_str. to_bytes ( ) . len ( ) as i32 ,
844939 ) ;
845-
846- XFlush ( self . display ) ;
847940 }
848941 }
849942
@@ -852,7 +945,7 @@ impl GridWM {
852945 let tileable: Vec < Window > = desktop
853946 . iter ( )
854947 . copied ( )
855- . filter ( |& w| self . is_tileable ( w) )
948+ . filter ( |& w| self . is_tileable ( w) && ! self . floating_windows . contains ( & w ) )
856949 . collect ( ) ;
857950
858951 if tileable. is_empty ( ) {
@@ -902,15 +995,15 @@ impl GridWM {
902995 + self . config . bar . height as i32
903996 + ( ( ( i / cols) + 1 ) * self . config . window . window_bar_height as i32 ) ,
904997 w,
905- h,
998+ h : h - self . config . window . window_bar_height as i32 ,
906999 }
9071000 } else if !self . config . bar . enable && self . config . window . window_bars {
9081001 WindowInfo {
9091002 x : ( i % cols) * w,
9101003 y : ( ( i / cols) * h)
9111004 + ( ( ( i / cols) + 1 ) * self . config . window . window_bar_height as i32 ) ,
9121005 w,
913- h,
1006+ h : h - self . config . window . window_bar_height as i32 ,
9141007 }
9151008 } else {
9161009 // bar disabled and window bars disabled
@@ -926,11 +1019,12 @@ impl GridWM {
9261019 }
9271020
9281021 fn is_tileable ( & self , window : Window ) -> bool {
929- if self . floating_windows . contains ( & window) {
930- return false ;
931- }
932-
9331022 unsafe {
1023+ let root = XDefaultRootWindow ( self . display ) ;
1024+ if window == 0 || window == root {
1025+ return false ;
1026+ }
1027+
9341028 let window_type_c = CString :: new ( "_NET_WM_WINDOW_TYPE" ) . unwrap ( ) ;
9351029 let notif_c = CString :: new ( "_NET_WM_WINDOW_TYPE_NOTIFICATION" ) . unwrap ( ) ;
9361030 let dock_c = CString :: new ( "_NET_WM_WINDOW_TYPE_DOCK" ) . unwrap ( ) ;
0 commit comments