@ -86,6 +86,7 @@ struct tinywl_toplevel {
 
			
		
	
		
			
				
						struct  wlr_scene_tree  * scene_tree ; 
 
			
		
	
		
			
				
						struct  wl_listener  map ; 
 
			
		
	
		
			
				
						struct  wl_listener  unmap ; 
 
			
		
	
		
			
				
						struct  wl_listener  commit ; 
 
			
		
	
		
			
				
						struct  wl_listener  destroy ; 
 
			
		
	
		
			
				
						struct  wl_listener  request_move ; 
 
			
		
	
		
			
				
						struct  wl_listener  request_resize ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -93,6 +94,12 @@ struct tinywl_toplevel {
 
			
		
	
		
			
				
						struct  wl_listener  request_fullscreen ; 
 
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  tinywl_popup  {  
			
		
	
		
			
				
						struct  wlr_xdg_popup  * xdg_popup ; 
 
			
		
	
		
			
				
						struct  wl_listener  commit ; 
 
			
		
	
		
			
				
						struct  wl_listener  destroy ; 
 
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  tinywl_keyboard  {  
			
		
	
		
			
				
						struct  wl_list  link ; 
 
			
		
	
		
			
				
						struct  tinywl_server  * server ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -672,12 +679,26 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > link ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  xdg_toplevel_commit ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						/* Called when a new surface state is committed. */ 
 
			
		
	
		
			
				
						struct  tinywl_toplevel  * toplevel  =  wl_container_of ( listener ,  toplevel ,  commit ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( toplevel - > xdg_toplevel - > base - > initial_commit )  { 
 
			
		
	
		
			
				
							/* When an xdg_surface performs an initial commit, the compositor must
 
 
			
		
	
		
			
				
							 *  reply  with  a  configure  so  the  client  can  map  the  surface .  tinywl 
 
			
		
	
		
			
				
							 *  configures  the  xdg_toplevel  with  0 , 0  size  to  let  the  client  pick  the 
 
			
		
	
		
			
				
							 *  dimensions  itself .  */ 
 
			
		
	
		
			
				
							wlr_xdg_toplevel_set_size ( toplevel - > xdg_toplevel ,  0 ,  0 ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  xdg_toplevel_destroy ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						/* Called when the xdg_toplevel is destroyed. */ 
 
			
		
	
		
			
				
						struct  tinywl_toplevel  * toplevel  =  wl_container_of ( listener ,  toplevel ,  destroy ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > map . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > unmap . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > commit . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > destroy . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > request_move . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & toplevel - > request_resize . link ) ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -793,6 +814,8 @@ static void server_new_xdg_toplevel(struct wl_listener *listener, void *data) {
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_toplevel - > base - > surface - > events . map ,  & toplevel - > map ) ; 
 
			
		
	
		
			
				
						toplevel - > unmap . notify  =  xdg_toplevel_unmap ; 
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_toplevel - > base - > surface - > events . unmap ,  & toplevel - > unmap ) ; 
 
			
		
	
		
			
				
						toplevel - > commit . notify  =  xdg_toplevel_commit ; 
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_toplevel - > base - > surface - > events . commit ,  & toplevel - > commit ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						toplevel - > destroy . notify  =  xdg_toplevel_destroy ; 
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_toplevel - > events . destroy ,  & toplevel - > destroy ) ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -808,10 +831,37 @@ static void server_new_xdg_toplevel(struct wl_listener *listener, void *data) {
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_toplevel - > events . request_fullscreen ,  & toplevel - > request_fullscreen ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  xdg_popup_commit ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						/* Called when a new surface state is committed. */ 
 
			
		
	
		
			
				
						struct  tinywl_popup  * popup  =  wl_container_of ( listener ,  popup ,  commit ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( popup - > xdg_popup - > base - > initial_commit )  { 
 
			
		
	
		
			
				
							/* When an xdg_surface performs an initial commit, the compositor must
 
 
			
		
	
		
			
				
							 *  reply  with  a  configure  so  the  client  can  map  the  surface . 
 
			
		
	
		
			
				
							 *  tinywl  sends  an  empty  configure .  A  more  sophisticated  compositor 
 
			
		
	
		
			
				
							 *  might  change  an  xdg_popup ' s  geometry  to  ensure  it ' s  not  positioned 
 
			
		
	
		
			
				
							 *  off - screen ,  for  example .  */ 
 
			
		
	
		
			
				
							wlr_xdg_surface_schedule_configure ( popup - > xdg_popup - > base ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  xdg_popup_destroy ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						/* Called when the xdg_popup is destroyed. */ 
 
			
		
	
		
			
				
						struct  tinywl_popup  * popup  =  wl_container_of ( listener ,  popup ,  destroy ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_remove ( & popup - > commit . link ) ; 
 
			
		
	
		
			
				
						wl_list_remove ( & popup - > destroy . link ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						free ( popup ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  server_new_xdg_popup ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						/* This event is raised when a client creates a new popup. */ 
 
			
		
	
		
			
				
						struct  wlr_xdg_popup  * xdg_popup  =  data ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  tinywl_popup  * popup  =  calloc ( 1 ,  sizeof ( * popup ) ) ; 
 
			
		
	
		
			
				
						popup - > xdg_popup  =  xdg_popup ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* We must add xdg popups to the scene graph so they get rendered. The
 
 
			
		
	
		
			
				
						 *  wlroots  scene  graph  provides  a  helper  for  this ,  but  to  use  it  we  must 
 
			
		
	
		
			
				
						 *  provide  the  proper  parent  scene  node  of  the  xdg  popup .  To  enable  this , 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -821,6 +871,12 @@ static void server_new_xdg_popup(struct wl_listener *listener, void *data) {
 
			
		
	
		
			
				
						assert ( parent  ! =  NULL ) ; 
 
			
		
	
		
			
				
						struct  wlr_scene_tree  * parent_tree  =  parent - > data ; 
 
			
		
	
		
			
				
						xdg_popup - > base - > data  =  wlr_scene_xdg_surface_create ( parent_tree ,  xdg_popup - > base ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						popup - > commit . notify  =  xdg_popup_commit ; 
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_popup - > base - > surface - > events . commit ,  & popup - > commit ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						popup - > destroy . notify  =  xdg_popup_destroy ; 
 
			
		
	
		
			
				
						wl_signal_add ( & xdg_popup - > events . destroy ,  & popup - > destroy ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					int  main ( int  argc ,  char  * argv [ ] )  {