@ -9,6 +9,7 @@
 
			
		
	
		
			
				
					# include  "sway/input/input-manager.h"  
			
		
	
		
			
				
					# include  "sway/input/seat.h"  
			
		
	
		
			
				
					# include  "sway/ipc-server.h"  
			
		
	
		
			
				
					# include  "sway/output.h"  
			
		
	
		
			
				
					# include  "sway/tree/arrange.h"  
			
		
	
		
			
				
					# include  "sway/tree/container.h"  
			
		
	
		
			
				
					# include  "sway/tree/workspace.h"  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -516,3 +517,114 @@ struct sway_container *workspace_output_get_highest_available(
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  NULL ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  pid_workspace  {  
			
		
	
		
			
				
						pid_t  pid ; 
 
			
		
	
		
			
				
						char  * workspace ; 
 
			
		
	
		
			
				
						struct  timespec  time_added ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  sway_container  * output ; 
 
			
		
	
		
			
				
						struct  wl_listener  output_destroy ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  wl_list  link ; 
 
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  struct  wl_list  pid_workspaces ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  sway_container  * workspace_for_pid ( pid_t  pid )  {  
			
		
	
		
			
				
						if  ( ! pid_workspaces . prev  & &  ! pid_workspaces . next )  { 
 
			
		
	
		
			
				
							wl_list_init ( & pid_workspaces ) ; 
 
			
		
	
		
			
				
							return  NULL ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  sway_container  * ws  =  NULL ; 
 
			
		
	
		
			
				
						struct  pid_workspace  * pw  =  NULL ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wlr_log ( L_DEBUG ,  " Looking up workspace for pid %d " ,  pid ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						do  { 
 
			
		
	
		
			
				
							struct  pid_workspace  * _pw  =  NULL ; 
 
			
		
	
		
			
				
							wl_list_for_each ( _pw ,  & pid_workspaces ,  link )  { 
 
			
		
	
		
			
				
								if  ( pid  = =  _pw - > pid )  { 
 
			
		
	
		
			
				
									pw  =  _pw ; 
 
			
		
	
		
			
				
									wlr_log ( L_DEBUG , 
 
			
		
	
		
			
				
											" found pid_workspace for pid %d, workspace %s " , 
 
			
		
	
		
			
				
											pid ,  pw - > workspace ) ; 
 
			
		
	
		
			
				
									goto  found ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
							pid  =  get_parent_pid ( pid ) ; 
 
			
		
	
		
			
				
						}  while  ( pid  >  1 ) ; 
 
			
		
	
		
			
				
					found :  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( pw  & &  pw - > workspace )  { 
 
			
		
	
		
			
				
							ws  =  workspace_by_name ( pw - > workspace ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ! ws )  { 
 
			
		
	
		
			
				
								wlr_log ( L_DEBUG , 
 
			
		
	
		
			
				
										" Creating workspace %s for pid %d because it disappeared " , 
 
			
		
	
		
			
				
										pw - > workspace ,  pid ) ; 
 
			
		
	
		
			
				
								ws  =  workspace_create ( pw - > output ,  pw - > workspace ) ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							wl_list_remove ( & pw - > output_destroy . link ) ; 
 
			
		
	
		
			
				
							wl_list_remove ( & pw - > link ) ; 
 
			
		
	
		
			
				
							free ( pw - > workspace ) ; 
 
			
		
	
		
			
				
							free ( pw ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  ws ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  pw_handle_output_destroy ( struct  wl_listener  * listener ,  void  * data )  {  
			
		
	
		
			
				
						struct  pid_workspace  * pw  =  wl_container_of ( listener ,  pw ,  output_destroy ) ; 
 
			
		
	
		
			
				
						pw - > output  =  NULL ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  workspace_record_pid ( pid_t  pid )  {  
			
		
	
		
			
				
						wlr_log ( L_DEBUG ,  " Recording workspace for process %d " ,  pid ) ; 
 
			
		
	
		
			
				
						if  ( ! pid_workspaces . prev  & &  ! pid_workspaces . next )  { 
 
			
		
	
		
			
				
							wl_list_init ( & pid_workspaces ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  sway_seat  * seat  =  input_manager_current_seat ( input_manager ) ; 
 
			
		
	
		
			
				
						struct  sway_container  * ws  = 
 
			
		
	
		
			
				
							seat_get_focus_inactive ( seat ,  & root_container ) ; 
 
			
		
	
		
			
				
						if  ( ws  & &  ws - > type  ! =  C_WORKSPACE )  { 
 
			
		
	
		
			
				
							ws  =  container_parent ( ws ,  C_WORKSPACE ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						if  ( ! ws )  { 
 
			
		
	
		
			
				
							wlr_log ( L_DEBUG ,  " Bailing out, no workspace " ) ; 
 
			
		
	
		
			
				
							return ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						struct  sway_container  * output  =  ws - > parent ; 
 
			
		
	
		
			
				
						if  ( ! output )  { 
 
			
		
	
		
			
				
							wlr_log ( L_DEBUG ,  " Bailing out, no output " ) ; 
 
			
		
	
		
			
				
							return ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  timespec  now ; 
 
			
		
	
		
			
				
						clock_gettime ( CLOCK_MONOTONIC ,  & now ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Remove expired entries
 
 
			
		
	
		
			
				
						static  const  int  timeout  =  60 ; 
 
			
		
	
		
			
				
						struct  pid_workspace  * old ,  * _old ; 
 
			
		
	
		
			
				
						wl_list_for_each_safe ( old ,  _old ,  & pid_workspaces ,  link )  { 
 
			
		
	
		
			
				
							if  ( now . tv_sec  -  old - > time_added . tv_sec  > =  timeout )  { 
 
			
		
	
		
			
				
								wl_list_remove ( & old - > output_destroy . link ) ; 
 
			
		
	
		
			
				
								wl_list_remove ( & old - > link ) ; 
 
			
		
	
		
			
				
								free ( old - > workspace ) ; 
 
			
		
	
		
			
				
								free ( old ) ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  pid_workspace  * pw  =  calloc ( 1 ,  sizeof ( struct  pid_workspace ) ) ; 
 
			
		
	
		
			
				
						pw - > workspace  =  strdup ( ws - > name ) ; 
 
			
		
	
		
			
				
						pw - > output  =  output ; 
 
			
		
	
		
			
				
						pw - > pid  =  pid ; 
 
			
		
	
		
			
				
						memcpy ( & pw - > time_added ,  & now ,  sizeof ( struct  timespec ) ) ; 
 
			
		
	
		
			
				
						pw - > output_destroy . notify  =  pw_handle_output_destroy ; 
 
			
		
	
		
			
				
						wl_signal_add ( & output - > sway_output - > wlr_output - > events . destroy , 
 
			
		
	
		
			
				
								& pw - > output_destroy ) ; 
 
			
		
	
		
			
				
						wl_list_insert ( & pid_workspaces ,  & pw - > link ) ; 
 
			
		
	
		
			
				
					}